Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 2021-02-22 in Posts

  1. When I reported on IRC that my skirmish maps weren't working, @Stan`gave me a link to this script https://code.wildfiregames.com/P232 I've attached the python script it to this post. python3 <scriptname> <version> <path> The correct version to use is "7". For the path, I used "." (single dot) while in the directory containing my custom skirmish maps. After that, you may have to edit your xml. I still get errors such as the following when opening most maps into Atlas 0ad-map-upgrade-20210222-01.py
    3 points
  2. Okay, so here's the whole texture pack, again, with the latest changes. And I'm going to throw in some examples of what it can do for materials and objects. First the Material Textures set: Red_channel 5 bits "albedo.dds" (DXT5) Green_channel 6 bits " Blue_channel 5 bits " Aged_Color 8 bits " MSpecularity 5 bits "optics.dds" (DXT5) SurfacePurity 6 bits " FresnelGloss 5 bits " Smoothness 8 bits " Aged_Color is for rust color, typically; 0.0 = black, 0.2 = burgundy, 0.4 = red, 0.6 = orange, 0.8 is no effect, and 1.0 is transparent rust. This channel does not tell you where the rust is to be located in a material; only what it WOULD look like if called for. What calls for rust to manifest is the Ageing channel in the Zones texture; see below. The Object Textures set: Normal_U 8 bits "Forms.png" (PNG sRGBA; no mipmaps) Normal_V 8 bits " Normal_W 8 bits " Height 8 bits " Emit_red 5 bits "Light.dds" (DXT5) Emit_grn 6 bits " Emit_blu 5 bits " AO_bake 8 bits " Faction 5 bits "Zones.dds" (DXT3) Ageing 6 bits " DetailMod 5 bits " Alpha 4 bits " The Ageing channel ushers-in rust --for metals ... NOTE: What Ageing and Aged_Color would or could do for non-metals is not clear to me. I'd hate to waste an opportunity for yet another fancy feature; but the problem is that we know many metals rust, and we know the color the rust will be in advance. If we tried to use these two channels to usher some effect on non-metals, the question is what do we know in advance about those materials. We could use this to progressively fade in blood stains on warriors as their health goes down, for example. If anyone has any ideas, by all means, speak up. The rules, as I'm thinking them so far, are: Where Ageing is 0.0 (black), nothing is modified. Where Ageing is 1.0 (white), modifications are maximal, as follows: If Aged_Color is below 0.8 (light gray or darker) the corresponding color will be shown, matte, on top of the metal surface (overwriting albedo color, zeroing specularity, and zeroing Purity for good measure). And if Ageing is, say, 0.5 (50% gray), the matte color will be alpha-blended at 50% on the metal. If Aged_Color is 1.0 (white) and Ageing is any non-zero value, a dielectric, transparent film on top of the metal will be simulated, of a thickness of up to 10 microns, modulated by Ageing's value. Thus, white in ageing produces the thickest dielectric film. The dielectric constant of the film is whatever the Gloss channel specifies. And rather than decrease specularity and purity, Ageing with Aged_Color at white will actually boost specularity and purity. This clear rust film will be almost invisible; hard to notice, unless you see something bright reflecting off the object, in which case you'll see moving bands of rainbow-tinted color, kind of iridescent. What this whole thing allows is to encode an alternative look for each material via the material textures, and to then interpolate between the two apparences via a color channel in the object textures domain. Let's create a few metals, just for fun: ALBEDO.DDS: SILVER IRON STEEL CHROME ALUMINIUM GOLD Red_channel 0.8 0.4 0.6 0.70 0.93 0.9 Green_channel 0.8 0.4 0.6 0.70 0.93 0.8 Blue_channel 0.8 0.4 0.6 0.70 0.93 0.5 Aged_Color 0.0 0.2 0.6 1.0 1.00 0.8 OPTICS.DDS: MSpecularity 0.8 0.6 0.7 1.0 0.9 0.9 SurfacePurity 1.0 1.0 1.0 1.0 1.0 1.0 FresnelGloss 0.0 0.0 0.0 0.55 0.19 0.0 Smoothness 0.7 0.4 0.6 0.9 0.7 0.9 NOTES: Chromium's 70% reflectivity is by reference. Its oxides' refractive indices are hard to find, but I found a refernce to chromium thin films having RI of 3.2. To encode 3.2, subtract 1 and divide by 4, ergo Gloss = 0.55 Aluminium's 93% reflectivity is by reference. Alumina's refractive index is 1.77. Gloss =1.77-1... 0.77/4 = 0.19 For other metals, the figures are fudged; pulled out of nowhere. Smoothness is not a material attribute, traditionally speaking, but here it is; thus polished silver and rough silver would be different materials. The materials here are assumed polished, but the smoothness varies by the polish-ability of the material (equalized efforts; not results XD), and also by what we want the passivated rust finish to look like. Compromise... The same can be said of MSpec where 0.9 means that 10% of the light reflects diffusely, 90% specularly. Is that the case? Well, If I look at aluminium foil I think far less than 10% of it reflects diffusely, but then I look at my aluminium pot and cry. Aged_Color is dialing in black for silver, dark red for iron, orange-red for steel, and clear film of passivated rust for both chromium and aluminium. For gold, at 0.8, it dials in no change at all. Gloss is not applicable to non-self-passivating oxide metals (unless you varnish them... or anodize aluminium). Purity refers to absence of diffuse particles on a dielectric surface; default is 1; less than 1.0 values are used to describe plastics or biological materials. Nothing prevents you from creating a custom, multi-material material, and use it for a single object; therefore if you need a copper sarcophagus with green rust, you can create that in this system. The Ageing mechanism is a trick to get a lot of art done for less effort, but it is not the only way to get rust. But like I said, those rusts are dormant until you put some light into the Ageing channel in the Zones texture; then rust comes alive. This will save a lot of work. Think about it. Without this feature, to put one dot of rust on a metal surface you'd have to, a) put the dot of red on the gray of iron, and b) put the same dot but in black in the specular channel. That's simple, okay; but what about then a sprinkling zones of rust kind of alpha-blending on the metal? Then you have to start creating masks and using them for specular and diffuse. But then what about a film of refractive self-passivating oxide of varying thickness? Now you have several channels to modify using masks. Here you just air-brush the Ageing channel, and all the layer work is taken care of. Furthermore, it has the benefit of keeping the definition of rust together with the metal, but the control of it with the objects' textures. So, if you change your mind and switch a sword from steel to chrome, or vice-versa, you just change the material it calls for; the rust will be in the same places, just look different. Conversely, if you find your sword has too much or two little rust, you don't have to change the material, affecting possibly dozens of other objects that use it; you just dial down the Ageing channel of your sword's Zones texture.
    3 points
  3. Brighter but more toned down colors? Large shield and cape marks player color but the colorful tone could still cause a little distraction for some, feel free to discuss the idea below. Older files that I have: Also this, could we potentially use it for something? Like a hero?
    3 points
  4. @DanW58 Honestly, at this moment a lot of what you post is overwhelming for a lot of us. You go into a lot of (exquisite) detail that will (eventually) be very useful if you continue on your course and improve the renderer as you plan. I like your "fall back" ideas so that we need fewer materials and map types "default" lower to a 1 texel image. That will be very helpful to us modders and artists, your documentation. Please continue and I encourage you to try the IRC channel and join other discussions regarding other aspects of the game. First and foremost, recognize that in this development environment it is a marathon, not a sprint. Personally, I have been involved with the development of this game in one way or another since 2005. I know this isn't the technical feedback you want, but i hope it helps regardless.
    3 points
  5. 3 points
  6. Woodcutting behavior is sometimes "weird". IT seems that when a tree is depleted, the units are searching for the next nearest tree to the spot where the last tree was rather than the most efficient one (the nearest tree to the dropsite). As a result, units are sometimes drawn far away from the forest by a couple of isolated trees.
    2 points
  7. Major channel rearrangement: Red_channel 5 bits "albedo.dds" (DXT5) Green_channel 6 bits " Blue_channel 5 bits " Aged_Color 8 bits " <<<<<<<<<<<----------***** new ****** MSpecularity 5 bits "optics.dds" (DXT5) SurfacePurity 6 bits " FresnelGloss 5 bits " Smoothness 8 bits " <<<<<<<<<<<----------***** moved ****** "Aged_Color" added; Thickness (of dielectric rust layer) moved to the Object Texture set, Zones texture, second channel, and changed name to "Ageing". The reasons for these changes are as follows: Zones of rusting are actually "Zones" in object space; NOT parts of a (shared) material. The "Ageing" channel, in object UV space, will allow demarcation of zones where rusting or staining occurs for an object. Passivated dielectric oxides that glow with iridescence are just one type of oxide; there are matte red, black and orange oxides. So it is clearly adventageous to expand the usefulness of this zoning to include any type of rust or weathering we may want to show; not just iridescence. The AgedColor channel in the albedo texture now encodes a color for "rust", from black (0.0), to red (0.25), to orange (0.5), and then clear (1.0). The 0.75 range is not to be used. When rust is colored (0.0~0.5), the Ageing channel value alpha-blends this color. When it is clear (1.0), the value in the Ageing channel encodes thickness of transparent layer. The alpha-blending of color also reduces MSpec and Purity. When AgedColor is clear (1.0), Ageing's value increases MSpec and Purity. This arrangement improves clarity even further: Now the albedo.dds texture has an rgb albedo, plus it encodes an optional "aged" albedo in alpha. Smoothness, which was rightfully a part of optics, is now in optics.dds. And Thickness, which was a means of zoning rust effects, is now in Zones.dds. Zones texture rearranged: Faction 5 bits "Zones.dds" (DXT3) Ageing 6 bits " <<<<<<<<<<<----------****** new ****** DetailMod 5 bits " <<<<<<<<<<<----------***** moved ****** Alpha 4 bits " The reason for this change is that Microns, (oxide layer thickness for iridescent reflections), is actually a "zone" on an "object", rather than a material characteristic. On the other hand, it is but one type of rust metal can exhibit. Rusts can be black, red, orange, greenish for copper, or clear. If we use the albedo alpha channel to encode for a rust color, then this "Ageing" rust mask channel can tell where to apply it and how thick. For colored rusts, Ageing acts like an alpha-blend. For clear rust, it acts as thickness of dielectric film. Perhaps it could be used to also add staining to non-metals. The idea is that if Ageing is fully on (1.0), if AgedColor is a color (below 0.75), it will overwrite albedo and set MSpec and Purity to zero. But if AgedColor is clear (1.0), MSpec and Purity will be maxed out. How this would look on non-metals I don't know and at least for now I don't care.
    2 points
  8. Sunday fun, and possibly the most exciting game I've covered so far?
    2 points
  9. hi guys (sa) first of all sory for my english . ı make mistakes guys ı think team maches should be ranking . like cs go or leage of legends because some people dont care tg ,when they are lose the game they are closing game and we stay 4 v3 or some people have high rate and never play 1 v1 so ı wish ranking team game what do you think about this topic guys
    1 point
  10. Hey everyone, I have been asking around in some matches about things that should be changed or that are unbalanced. Here is a short list about what I have so far: Hotkeys dont work (Hotkeys to build easier) Outpost useless because units placed inside are killed to easy (It seems more realistic but some players dont like it) Most of the time towers shoot further then their range bubble Resource gathering slower because of units movement (not sure if this is a problem or that we just have to deal with it) Auto formation is a bad thing until pathfinding is better (multiple complaints about this one Slinger being same speed as javileneers is a bad thing (most of the players say so) Archers are op (most players say so) Archers shot sound is very low compared to the rest. (I have the same problem) Indian war elephant is way to powerfull, one can take down a CC (Not sure if it is a problem, they are considered siege) Elephants are op (player told me) Please feel free to comment more feedback, we want to fix as many problems as we can.
    1 point
  11. I think it would be fair to first of all point out that there is a good deal more variety in Age of Empires 2 compared to 0 AD at the moment when it comes to civilisations; they might have extremely similar fundamental mechanics, but the variation in tech trees and depth of strategy is significantly better developed there. Then again that is a full-fledged game while 0 AD is in alpha. As to your second point, it holds little water. Spear served as the weapon of choice on the battlefield for a good reason. Its reach is massive compared to most arming swords; the advantage of a sword is that it is a reliable side-arm, something that can be drawn after the primary weapon has been discarded or rendered inoperable. Even legionnaires, who are perhaps some of the most famous dedicated swordsmen in history, used them as the followup to their javelin volleys. The primary point that you have failed to dismantle is the fact that spearmen being worse at dismantling rams makes little to no sense. Also, I would respectfully ask you to consider being more polite with your tone. Needlessly belittling people does nothing to advance arguments and makes one sound immature. My apologies if that came off as insulting.
    1 point
  12. Hmmm.... I've got myself into a conflict. Gloss (refractive index) has two meanings now. My original intent was for gloss to stay at zero for metals. Zero gloss maps to 1.0, which is the refractive index of vacuum by definition, and of air, by luck. So Fresnel specularity is computed for metals, but produces no effect. But now, for metals like chromium, where a self-passivating oxide can happen by rusting, and needs a refractive index, if I use the Gloss channel to specify it, the whole thing will have a film of it, not just the rusted parts. Unless I use MSpec to deny Gloss unless Ageing is non-zero. This is doable, but would deny us the freedom to have anodized aluminum, or varnished metal; this may not be an issue for 0ad but might be an issue for my Masters of Orion remake mod. On the other hand, the latter problem could be solved by making the Ageing channel all white and forego ageing effects. Think, think, think ... EDIT: I actually like the last solution; the problem is that it makes the shader a bit more complex to understand. Artists will have to have a good grasp of the shader pipeline, but having Gloss denied by metallicity unless pushed by Ageing is a bit of a gordian knot. Furthermore, there's no reason to deny Gloss by metallicity if the rust type indicated by Aged_Color is not 1.0 (transparent). In other words, Iron rusts red, so Gloss would be at zero. If Gloss is not zero, it could not possibly be for rusting, so it means we are varnished head to toe. More complexity... On the other hand, how often will this situation arise? Need coffee ... EDIT2: With the last solution, the ONLY two situations that will be odd are a varnished chromium sword, and a heatsink of anodized aluminium. In order for these to be covered in varnish or rust, respectively, they have to have their Aged channel whitened. The problem with that is that they won't be able to rust; but then again, neither WOULD rust, anyways!
    1 point
  13. Hi, I am maintainer of mozjs78 in Fedora. Can you add a patch to that ticket? Or provide a link to that patch if it's somewhere in 0ad's repo? I'll happily include a patch for this in Fedora package. Thanks!
    1 point
  14. With these errors you can just use Notepad++ or your favorite text editor and do a ctrl-H replace all gaia/tree/cretan_date_palm_tall
    1 point
  15. I would really like to change this for A25. EA should really adopt DE's forest groves. You don't even have to adopt DE's grove auras and traversability in case you're too scared of changing gameplay.
    1 point
  16. Yeah that's exactly what happens actually. I think there was already behaviour to do that in A23, but maybe it didn't work quite the same. My recommended "fix" is to simply make more dropsites, because efficiency goes down very rapidly with walking distance anyways. This is something I'd like to fix for A25, but it's not that trivial
    1 point
  17. Thanks for commenting this game! Was actually tough to be 2v1 on my side, and supporting a bit the other team. I could have done better. Instead of going to Crypto, should have get down WeirdJokes on my first attack, maybe, not sure.. Anyway, I felt bad loosing with @Boudicaepic performance! GG to team 1. The title could be 3v4
    1 point
  18. Thank you for the feedback. Getting the balance right is tricky and we certainly do not claim everything is perfect; 0 A.D. is very much a work in progress. Nevertheless, players such as @badosu, @borg-, @Feldfeld, and @ValihrAnt participated during the development and gave feedback, therefore we hope A24 is overall better than any previous release. As for war elephants, their crush damage has actually been reduced, from 150 to 120. As for slingers, they had a reload time of 1 s in A23, in A24 it's increased to 1.25 s. As for archers, their range has been reduced from 72+4+4 to 60. Moreover, ranged troops promote more slowly and advanced, elite, and champion ranged troops are easier to kill. That said, there will be further changes in the next release (A25) and more feedback is certainly welcome!
    1 point
  19. I think the building hotkeys were property of @naniautociv mod.
    1 point
  20. I agree with this one. A bad change. Maybe give back outpost vision and just make outpost cost 1 pop.
    1 point
  21. hey! just discovering 0AD! i wanna play LAN, 1v1 on windows and ubuntu, its posible? we just downloaded the game, but it seems that versions dosent match 24 on windows and 23 on linux. wait for the update on linux or downgrade on windows? amazing work! we will enjoy join the ride.
    1 point
  22. I do think the mod selection screen is a little... open source. Meaning, unintuitive.
    1 point
  23. Hi! First of all, congratulations to everyone who contributed to this new 0 A.D. Alpha release. I confess that I imagined months ago that this release would be something smaller (few changes) and I was totally wrong. And that's good! Thanks again to the community of contributors this awesome release became a reality. That said, I would like to ask about the bug related to the previous installations mods. Is it possible to implement something that prevents this from happening in the next 0 A.D. versions? In addition, it would be great if there was a beautiful and explanatory interface for selecting mods, advising which are compatible, which are not, descriptions etc. Something suitable for novice users, not assuming an experienced player. By the way, congratulations on the map selection menu. Great feature! Regards!
    1 point
  24. #version 777 #include "common/fog.h" #include "common/los_fragment.h" #include "common/shadows_fragment.h" #if USE_OBJECTCOLOR uniform vec3 objectColor; #else #if USE_PLAYERCOLOR uniform vec3 playerColor; #endif #endif // Textures: uniform sampler2D TS_albedo; uniform sampler2D TS_optics; varying vec2 UV_material; // First UV set. //~~~~~~~~~~~ uniform sampler2D TS_forms; uniform sampler2D TS_light; uniform sampler2D TS_zones; uniform sampler2D TS_detail; varying vec2 UV_object; // Second UV set. //~~~~~~~~~~~ uniform samplerCube skyCube; // Vectors: uniform vec3 v3_sunDir; varying vec4 v4_normal; varying vec3 v3_eyeVec; varying vec3 v3_half; varying vec4 v4_tangent; varying vec3 v3_bitangent; varying vec4 v4_lighting; // Colors: uniform vec3 sunColor; uniform vec3 gndColor; // SUBROUTINES: vec3 renormalize( vec3 input ) // For small errors only, faster than normalize(). { return input * vec3( 1.5 - (0.5 * dot(input, input)) ); } float LOD_bias_from_spec_power( float spec_power ) { return clamp( 8.0 - ( 0.5 * log2(spec_power) ), 0.0, 7.78 ); } float LOD_bias_from_AO( float AO ) { return clamp( 8.0 + (0.4373 * log2(AO)), 0.0, 7.78 ); } vec3 SchlickApproximateReflectionCoefficient( float rayDotNormal, float From_IOR, float To_IOR ) { float R0 = (To_IOR - From_IOR) / (From_IOR + To_IOR); float angle_part = pow( 0.9*(1.0-rayDotNormal), 5.0 ); R0 = R0 * R0; float RC = R0 + (1.0 - R0) * angle_part; return vec3(RC, RC, RC); // Returns Fresnel refl coeff as gray-scale color. } void main() { vec4 temp4; vec3 temp3; vec2 temp2; float temp; // MATERIAL TEXTURES: // Load albedo.dds data: temp4 = texture2D( TS_albedo, UV_material ); vec3 Mat_RGB_albedo = temp4.rgb; // To be split into diffuse and specular... float Mat_alpha = temp4.a; // Load optics.dds data: temp4 = texture2D( TS_optics, UV_material ); float Mat_MSpec = temp4.r; // Metallic specularity % (vs diffuse). float Mat_Purity = temp4.g; float Mat_IOR = ( temp4.b * 4.0 ) + 1.0; // Gloss to IOR. float Mat_SpecularPower = 1.0 / min( 1.0 - temp4.a, 1.0/256.0 ); Mat_SpecularPower = SpecularPower * SpecularPower; // Smoothness. // OBJECT TEXTURES: // Load forms.png data: temp4 = texture2D( TS_forms, UV_object ); vec3 Obj_NM_normal = normalize( vec3(2.0, 2.0, 1.0) * ( temp4.rgb - vec3(0.5, 0.5, 0.0) ) ); float Obj_ParallaxHeight = temp4.a; // Any scaling needed? // Load light.dds data: temp4 = texture2D( TS_light, UV_object ); vec3 Obj_RGB_emmit = temp4.rgb; // Emissive + self-lighting. float Obj_AO = temp4.a; // Occlusion. vec3 Obj_RGB_ao = vec3( temp4.a ); // AO as color, for convenience. // Load zones.dds data: temp4 = texture2D( TS_zones, UV_object ); float Obj_is_Faction = temp4.r; // Where to put faction color. float Obj_Microns = 10.0 * temp4.g; // Thickness of oxide film. float Obj_AO_detailMod = 1.0 - min( temp4.b * 2.0, 1.0 ); float Obj_SP_detailMod = max( 0.0, temp4.b * 2.0 - 1.0 ); float Obj_Alpha = temp4.a; // Load detail.dds data, and apply it: temp3 = texture2D( TS_detail, UV_object * vec2(11.090169945) ); temp = dot( temp3, vec3(1.0) ); Obj_RGB_ao = Obj_RGB_ao + vec3(0.0625 * Obj_AO_detailMod) * (temp3 - vec3(0.5)); Mat_SpecularPower = Mat_SpecularPower * ( 1.0 + ( 0.0625 * Obj_SP_detailMod * (temp-0.5) ) ); // VECTORS AND STUFF: // Sanitize and normalize: // v3_sunDir should not need renormalization vec3 v3_raw_normal = renormalize( vec3( v4_normal ) ); vec3 v3_eye_vector = renormalize( v3_eyeVec ); vec3 v3_half_vec = renormalize( v3_half ); // Tangent stuff ... I know nothing about it. // Normal-map-modulated normal: vec3 v3_mod_normal = renormalize( v3_raw_normal * Obj_NM_normal ); vec3 v3_refl_view = -reflect( v3_half_vec, v3_mod_normal ); // These numbers are precomputed, as they will be needed more than once: float upwardsness = v3_raw_normal.y; float rayDotNormal = max( 0.0, dot( -v3_sunDir, v3_mod_normal ) ); float eyeDotNormal = max( 0.0, dot( v3_eye_vector, v3_mod_normal ) ); vec3 fresnel_refl_color = SchlickApproximateReflectionCoefficient( eyeDotNormal, 1.0, Mat_IOR ); // STUFF I KNOW NOTHING ABOUT: #if (USE_INSTANCING || USE_GPU_SKINNING) && (USE_PARALLAX || USE_NORMAL_MAP) vec3 bitangent = vec3(v4_normal.w, v4_tangent.w, v4_lighting.w); mat3 tbn = mat3(v4_tangent.xyz, bitangent, v4_normal.xyz); #endif #if (USE_INSTANCING || USE_GPU_SKINNING) && USE_PARALLAX { float h = Obj_ParallaxHeight; vec2 coord = UV_object; vec3 eyeDir = normalize(v_eyeVec * tbn); float dist = length(v_eyeVec); vec2 move; float height = 1.0; float scale = effectSettings.z; int iter = int(min(20.0, 25.0 - dist/10.0)); if (iter > 0) { float s = 1.0/float(iter); float t = s; move = vec2(-eyeDir.x, eyeDir.y) * scale / (eyeDir.z * float(iter)); vec2 nil = vec2(0.0); for (int i = 0; i < iter; ++i) { height -= t; t = (h < height) ? s : 0.0; temp2 = (h < height) ? move : nil; coord += temp2; h = texture2D(TS_forms, coord).a; } // Move back to where we collided with the surface. // This assumes the surface is linear between the sample point before we // intersect the surface and after we intersect the surface. float hp = texture2D(TS_forms, coord - move).a; coord -= move * ((h - height) / (s + h - hp)); } } // ALBEDO AND THINGS: // Separate albedo into diffuse and specular components: float Mat_MDiff = 1.0 - Mat_MSpec; vec3 Mat_RGB_diff = Mat_RGB_albedo * Mat_RGB_albedo; // Boost saturation. vec3 Mat_RGB_spec = sqrt( Mat_RGB_albedo ); // Wash saturation. Mat_RGB_diff = ( (Mat_MDiff * Mat_RGB_diff) + (Mat_MSpec * Mat_RGB_albedo) ) * Mat_MDiff; Mat_RGB_spec = ( (Mat_MSpec * Mat_RGB_spec) + (Mat_MDiff * Mat_RGB_albedo) ) * Mat_MSpec; temp3 = Mat_RGB_albedo / (Mat_RGB_diff + Mat_RGB_spec); // Renormalize results. Mat_RGB_diff = Mat_RGB_diff * temp3; Mat_RGB_spec = Mat_RGB_spec * temp3; // Done! Mat_RGB_diff = mix( Mat_RGB_diff, playerColor, Obj_is_Faction ); // CUBE MAP FETCHINGS: vec3 RGBlight_reflSky = vec3( textureCube(skyCube, v3_reflView, LODbias_from_spec_power( Mat_specular_power ) ) ); vec3 RGBlight_normSky = vec3( textureCube(skyCube, v3_raw_normal, LODbias_from_AO( Obj_AO ) ) ); // THE REAL STUFF BEGINS ... I forgot the detail textures. Adding them above. I just had a change of heart about where to place the dielectric film thickness channel. I had it as part of the material textures; but there's a problem with that: It is not really a material, or is it? If you want to make some parts of a sword reflect more iridescently than others, it is not the material you are adding this feature to; it is to the sword; you are modifying the sword itself, NOT the material that it is made of, which could be shared by many other objects. You are also marking a zone, where passivated rusting occurs. It seems to belong in the Zones texture, in the Objec Textures pack. I'm still editing this post... (I'll delete this sentence when I'm done.) Stay tuned ...
    1 point
  25. We're making progress!!! So, add these functions before main: float LODbias_from_spec_power( float spec_power ) { return clamp( 8.0 - ( 0.5 * log2(spec_power) ), 0.0, 7.78 ); } float LOD_bias_from_AO( float AO ) { return clamp( 8.0 + ( 0.4373 * log2(AO) ), 0.0, 7.78 ); } And now we can finish what we started. These environment map fetches have to be done as early as possible, as many things depend on them. void main() { // MATERIAL TEXTURES ................................... // OBJECT TEXTURES ................................... // VECTORS ETC. ................................... vec3 RGBlight_reflSky = vec3( textureCube(skyCube, v3_reflView, LODbias_from_spec_power( Mat_specular_power ) ) ); vec3 RGBlight_normSky = vec3( textureCube(skyCube, v3_raw_normal, LODbias_from_AO( Obj_AO ) ) ); This is FANTASTIC! We have initialized everything that needs initializing; now we are ready for the actual guts of the shader. Before I go on, however, I will put all we've done so far into a code snippet, as the next post.
    1 point
  26. Another question I might get, "why not just use HDRI and forget about matching Phong to LOD bias and all that?" Good question, again. Because HDRI cube maps don't really solve any problem except laziness, and they do so at a very high price, having to have great bit depth to expres a dynamic range of light spanning millions. Besides, having the sun in the sky, or in the sky texture, is basically the same thing. If you want it in the texture, you have to put it there, though. If you want to show the same scene at different times of the day, are you going to manipulate the environment texture to move the sun? I'm not the biggest fan of OpenGL, but lights were created for a reason. Anyways, calculating LOD bias from AO: From the first post in this thread we have formulas relating AO and blur radius, namely, hemispheres = 1 - cos( radius ) radius = arccos( 1 - hemispheres ) Hemispheres IS the AO. So we can write AO = 1 - cos( radius ). In the table above I have a column for radius; maybe I can calculate AO for each radius, and add it as a new column ... SpecPWR radius (rads) /2.35 blur 2/x=rez log2(x) 10-log2x=bias AO fudged AO ========================================================================================== 65,536 0.00459924964 0.00195713 1021 ~9.99 0.0 0.00... 0.00... 4,096 0.01839651273 0.00782830 255.5 ~8.00 2.0 0.00017 0.00024 256 0.07355492296 0.03129997 63.9 6.00 4.0 0.0027 0.00390 16 0.29223187184 0.12435399 16.0 4.00 6.0 0.042 0.06250 1 1.04719755125 0.44561598 4.5 ~2.22 ~7.8 0.5 1.00000 Well, this is interesting... For values of AO greater than 0.5, the LOD bias saturates! What could this mean? Oh, I think I know what it means: The innermost LOD of a cubemap has 6 texels. Each represents a third of a hemisphere. Larger solid angles than a third of a hemisphere are not represented. So, what do we do? I'd like the bias to be continuous; not to be just limited after AO gets larger than 0.5. I'd like the bias to go to 8 when AO is 1.0. Okay, let me derive a continuous AO that biases at 8 when it is 1 and goes by the same powers as specular power, which is what it seems to do (0.042/.0027~=16; 0.0027/.00017~=16). So, let me write a first fudge like, float LOD_bias_from_AO( float AO ) { return clamp( 8.0 + (0.5 * log2(AO)), 0.0, 7.8 ); } I added the results as an extra column titled "fudged AO". I think the result is pretty good. Of course the question will come up, why am I fudging a value after ranting about fudging so much. Well, in this case I find it close enough to true value, and it is a very economical solution. To do better, I'd have to have a conditional testing for AO being greater than 0.5, and if so doing my own filtering by interpolating between the LOD bias 8 fetch and "AmbientLight", that being the cubemap's average; and that would be an incorrect calculation anyways. More correct would be to take say 7 samples in a hexagonal pattern with a center, and average them; but that's expensive. In any case, the numbers are pretty close, except for LOD 8, which is exactly what I hoped for. In this case, continuity will look better than absolute precision. Or else, one other thing I can do is scale the bias effect so that LOD6 matches the true number. To get 0.042 to give me bias of 6, or in other words, to get 2 subtracted from 8 at .042, with log2(0.042) being −4.573466862, 2/4.573466862=0.437305016, so, float LOD_bias_from_AO( float AO ) { return clamp( 8.0 + (0.4373 * log2(AO)), 0.0, 7.8 ); } Now I still get 8.0 for ao of 1.0, and for AO of 0.042 I get 6.00000845. BINGO!!!!
    1 point
  27. Someone might ask, "is it necessary to derive exact formulas for things like LOD bias?" The answer is a qualified yes. What most engines that even use LOD bias do is just fudge it. Just like they fudge a rough formula for Fresnel. The problem with fudging things is that eventually you arrive at a visible inconsistency. One possible inconsistency here is between environment mapping's reaction to specular power, and sunlight's reaction to specular power. One blurs by LOD biasing the cubemap with trilinear filtering. The other one blurs by computing the Phong formula. And the two have to agree. If they don't, your visual cortex will know it, even if your prefrontal cortex denies it. The same goes for the light intensity relationship between diffuse and specular. Everybody fudges that. But the day you see a shader that doesn't fudge it, that matches them mathematically, something about it seems cinematic in quality, and you don't even know what it is. And the light intensity between diffuse and specular match perfectly when specular power is 1.0, and reflection falls by 1/2 at 60 degrees from the half angle, just like in diffuse it falls to 1/2 at 60 degrees between light and normal vectors. Yes, these things are important, both in relative and absolute terms. I know because 20 years ago I worked on all this and came up with a shader that was utterly unbelievable. I had been working on all the math on faith that it would make a difference; and in the end it far exceeded my wildest expectations. THIS IS PHYSICS-BASED RENDERING, by the way; not all those other pretentious parties out there with far more money than brains. Anyways, let us continue: How about we calculate blur radius for four other specular powers, namely 4096, 256, 16 and 1.0, and see if we see a pattern? Using the formula Radius = arccos( 0.5^(1/n) ) where n is the spec power, SpecPWR radius (rads) /2.35 blur 2/x=rez log2(x) 10-log2x=bias ================================================================ 65,536 0.00459924964 0.00195713 1021 ~9.99 0.0 4,096 0.01839651273 0.00782830 255.5 ~8.00 2.0 256 0.07355492296 0.03129997 63.9 6.00 4.0 16 0.29223187184 0.12435399 16.0 4.00 6.0 1 1.04719755125 0.44561598 4.5 ~2.22 ~7.8 These calculations were painful, but certainly not wasted. How in the world an arccos of a funny power comes so close to a much simpler formula, I don't know, but seeing is believing. Bias appears to be equal to 8 minus the log2( sqrt( spec_power ) ). But the log of a square root is 1/2 the log of the thing, so this boils down to ... float LODbias_from_spec_power( float spec_power ) { return clamp( 8.0 - ( 0.5 * log2(spec_power) ), 0.0, 7.78 ); } Now we need to get a formula from AO. Remember that the AO is basically a measure of solid angle expressed in hemispheres. White, in AO, means a full hemisphere of visibility, which happens to be 2 pi (6.28) steradians. Next post ...
    1 point
  28. Better yet, an in-game Option.
    1 point
  29. There's another math issue to resolve before proceeding to the next stuff, namely the environment cube fetches. There are two main reasons to read the env_cube: specular reflections, and ambient light. Ambient light?! Well, yes; the env_cube IS our ambient. Reflected ambient light at any point in a surface is nothing but the light it reflects diffusely from the part of the sky its normal points to, multiplied by the ao. Naturally! So the AmbientLight uniform is not needed when we have an env_cube; the slot can be used for Ground Color... ;-) So, we have two fetches: one for reflection, and one for ambient lighting. But now, obviously we don't want the color of an exact point in the sky for ambient; do we? We want a very, VERY blurred sum of a portion of sky, --up to half of it, if the ao is 1.0. But how do we read half the sky? Well, that's easy, actually. We simply read the env_cube with a lot of LOD bias. The deepest LOD represents the entire sphere of sky with 6 texels. If we don't have LOD's in the cube_maps, no problem, there are free tools that can generate them. It will only take an afternoon to add LOD's to the cube-maps. So then you read the cubemap with an LOD parameter, which is a floating point number; the fetch is tri-linearly filtered. In the case of specular reflections, we also want to calculate a bias, as such reflections are blurred by the roughness of the surface, the inverse of smoothness, of specular power. To each specular power there is a corresponding blur radius. And to each LOD in the env_cube there is a corresponding blur radius. We need to compute a bias that will match them. Now, the problem is how do we compute the bias? In the first post in this forum thread I derived a formula to relate specular power to solid angle. So, we need a formula that relates solid angle to cube-map LOD. If we were to assume no filtering, solid angle for an LOD would be texel size solid angle. However, being a cube, the solid angle for a texel in the middle of a face is larger than for a texel near a corner, which is why cube-maps MUST --ABSOLUTELY MUST-- have spherical blurring applied. And I believe the absolute minimum effective blur diameter is 2.5 texels --of the ones in the middle of a face. A radius of 1.25. So, assuming our cube-maps are 1024 x 1024 x 6 at LOD zero, the angle of 1.25 texels is what? Hmmm... It would be the arctan of 1.25/512 = 0.0024414014 radians. From the first post, my formula relating shininess to radius was n = ln( 0.5 ) / ln( cos(SpotRadius) )... cos(0.0024414014) = 0.99999701978 ln(0.99999701978) = -0.0000029802244 ln(0.5) = -0.6931471806 0.6931471806 / 0.0000029802244 = 232582.2 Yes; that's a specular power equivalent of 232,000 and change. Which is not impossible, in principle; a good mirror probably has specular power in the millions, if we were to calculate it; funny they don't use that for marketing; it's just that we cannot represent it in the game. I think I designed the Smoothness mapping to get 64k at 255 channel value, so no reflective surface in-game will come even close to the most detailed LOD (level 0). How about we go the other way? Let's find out what blur radius we need for a given spec power. Maybe we can get away with much smaller environment cubes... At spec power of 65536, SpotRadius = arccos( 0.5^(1/n) ) = arccos( 0.99998942347 ) = .00459924962 radians. tan( 0.00459924964 ) = 0.00459928207 The inverse is 217.426771381 blur radiuses per half a side, or 434.85 radiuses for full side. Okay, so we can use 1024 cube maps, just keeping the blur radius to 2.35 texels, which is good; I was worried about not being able to blur the cube-map enough to prevent DXT compression artifacts; it seems we HAVE to do a nice blur. EXCELLENT! So, I was going to say that the shader needed to be passed the cubemap size and blur radius as uniforms, but I think there is not much room to play with those parameters; I think what these calculations are saying is that cubemaps HAVE to be 1024, AND HAVE to have a blur radius of 2.35 texels, or 0.0046 radians, at LOD 0. So, let the shader assume these numbers, and I'll make sure our cube maps meet these specifications. Okay, so now we know that for a specular power of 65,536 we need an LOD bias of zero. But what is the general formula? Stay tuned.
    1 point
  30. what we need is a TG cooldown like in csgo if you quit too many games/ if your connection is crap etc to protect the time of other players.
    1 point
  31. One question you might be pondering is why I haven't put the texture data loading stuff into subroutines. Good question! It would be nice to do so, but the problem is that the glsl language doesn't support pointers or references, which is okay if your subroutine only needs to return a value; but if a routine needs to modify several variables there is no way it can do so. So, subroutines in glsl are great for functions that funnel a bunch of data into a single result; not for functions that generate multiple outputs. All those texture data loads are like inverted funnels, they take data from the texture and spread it to different variables. But don't worry, we will have plenty of subroutines soon enough. Here's our incoming vector declarations: uniform vec3 v3_sunDir; varying vec4 v4_normal; varying vec3 v3_eyeVec; varying vec3 v3_half; varying vec4 v4_tangent; varying vec3 v3_bitangent; Note that some are vec4's; that's because there are additional parameters tagged onto the fourth float, which are used for some tangent space calculations in the current shader that are way beyond my head; probably parallax related. I don't want to mess with it, so I will transfer the xyz parts to vec3's in due course. So now, back in main... vec3 renormalize( vec3 input ) // For small errors only, faster than normalize(). { return input * vec3( 1.5 - (0.5 * dot(input, input)) ); } void main() { // ...TEXTURE STUFF... ......................... // VECTORS AND STUFF: // Sanitize and normalize: // v3_sunDir should not need renormalization vec3 v3_raw_normal = renormalize( vec3( v4_normal ) ); vec3 v3_eye_vector = renormalize( v3_eyeVec ); vec3 v3_half_vec = renormalize( v3_half ); // Tangent stuff ... I know nothing about it. // Normal-map-modulated normal: vec3 v3_mod_normal = renormalize( v3_raw_normal * Obj_NM_normal ); vec3 v3_refl_view = -reflect( v3_half_vec, v3_mod_normal ); // These numbers are precomputed, as they will be needed more than once: float upwardsness = v3_raw_normal.y; float rayDotNormal = max( 0.0, dot( -v3_sunDir, v3_mod_normal ) ); float eyeDotNormal = max( 0.0, dot( v3_eye_vector, v3_mod_normal ) ); vec3 fresnel_refl_color = SchlickApproximateReflectionCoefficient( eyeDotNormal, 1.0, Mat_IOR );
    1 point
  32. Some news coverage https://news.ycombinator.com/item?id=26207191 https://www.gamingonlinux.com/2021/02/open-source-rts-0-ad-alpha-24-is-out-now-with-plenty-of-new-features https://www.phoronix.com/scan.php?page=news_item&px=0-AD-Alpha-24 Well, if anyone finds a convenient way to get all the coverage, let me know. I only used Searx and searched for external links. href:https://play0ad.com/new-release-0-a-d-alpha-24-xsayarsa/ Noteworthy: Wolframalpha play0ad.com vs ageofempires.com
    1 point
  33. Changing the name of color.dds to albedo.dds, because it will actually represent the sum of diffuse and specular. Here's the shader's texture input declarations: uniform sampler2D TS_albedo; uniform sampler2D TS_optics; varying vec2 UV_material; // First UV set. //~~~~~~~~~~~ uniform sampler2D TS_forms; uniform sampler2D TS_light; uniform sampler2D TS_zones; varying vec2 UV_object; // Second UV set. //~~~~~~~~~~~ uniform samplerCube skyCube; Those "varying"s are interpolated texture coordinates coming from the vertex shader. The uniform sampler2D things are texture reader units. The last uniform is a cubemap reader, for the environment; and coordinates for it don't come in a varying because they have to be calculated right here in the fragment shader. Once in main(), the first thing we want to do is read those textures, as the operations will take a few cycles and we want to minimize dependencies. The shader compiler would optimize dependencies anyways, but I like to keep my brains close to the silicon. void main() { vec4 temp4; vec3 temp3; vec2 temp2; float temp; // MATERIAL TEXTURES: // Load albedo.dds data: temp4 = texture2D( TS_albedo, UV_material ); vec3 Mat_RGB_albedo = temp4.xyz; // To be split into diffuse and specular... float Mat_SpecularPower = 1.0 / ( 1.0 - temp4.w ), 2.0; Mat_SpecularPower = SpecularPower * SpecularPower; // Smoothness. // Load optics.dds data: temp4 = texture2D( TS_optics, UV_material ); float Mat_MSpec = temp4.x; // Metallic specularity % (vs diffuse). float Mat_Purity = temp4.y; float Mat_IOR = ( temp4.z * 4.0 ) + 1.0; // Gloss to IOR. float Mat_Microns = 10.0 * temp4.w; // Thickness of oxide film. // OBJECT TEXTURES: // Load forms.png data: temp4 = texture2D( TS_forms, UV_object ); vec3 Obj_NM_normal = normalize( vec3(2.0, 2.0, 1.0) * ( temp4.xyz - vec3(0.5, 0.5, 0.0) ) ); float Obj_ParallaxHeight = temp4.w; // Any scaling needed? // Load light.dds data: temp4 = texture2D( TS_light, UV_object ); vec3 Obj_RGB_emmit = temp4.xyz; // Emissive + self-lighting. float Obj_AO = temp4.w; // Occlusion. vec3 Obj_RGB_ao = vec3( temp4.w ); // AO as color, for convenience. // Load zones.dds data: temp4 = texture2D( TS_zones, UV_object ); float Obj_is_Faction = temp.x; // Where to put faction color. float Obj_AO_detailMod = 1.0 - min( temp.x * 2.0, 1.0 ); float Obj_SP_detailMod = max( 0.0, temp.x * 2.0 - 1.0 ); //temp4.z is vacant for now. float Obj_Alpha = temp4.w; // VECTORS: ....................... // ENVIRONMENT CUBE FETCHES: ....................... Deriving diffuse and specular from albedo is not as simple as a multiplying by MSpec and its complement. In any given material, the diffuse has higher saturation than the specular color due to light making multiple bounces before reflecting back; so, technically, diffuse color is a power of specular color. So we need an algorithm that can yield this type of relationship, while keeping the sum of the two colors equal to albedo. Furthermore, if the material is 90% metallic reflectivity (by which we mean single-bounce reflectivity), we'd want the smaller diffuse component to be more saturated than the albedo, and specular be same as albedo, more or less. But if the material is 0.1 MSpec, that is, 10% single bounce, 90% multi-bounce, we'd want the now smaller specular component to have less saturation than albedo, while the diffuse component remaining about equal to albedo. How do we achieve all of this? Well, it took me a few trials and errors on paper, but finally I think I got it, --subject to debugging later, of course. // Separate albedo into diffuse and specular components: float Mat_MDiff = 1.0 - Mat_MSpec; vec3 Mat_RGB_diff = Mat_RGB_albedo * Mat_RGB_albedo; // Boost saturation. vec3 Mat_RGB_spec = sqrt( Mat_RGB_albedo ); // Wash saturation. Mat_RGB_diff = ( (Mat_MDiff * Mat_RGB_diff) + (Mat_MSpec * Mat_RGB_albedo) ) * Mat_MDiff; Mat_RGB_spec = ( (Mat_MSpec * Mat_RGB_spec) + (Mat_MDiff * Mat_RGB_albedo) ) * Mat_MSpec; temp3 = Mat_RGB_albedo / (Mat_RGB_diff + Mat_RGB_spec); // Renormalize results. Mat_RGB_diff = Mat_RGB_diff * temp3; Mat_RGB_spec = Mat_RGB_spec * temp3; // Done! In the next post, we'll process all the needed vectors; stay tuned. EDIT: Another way of looking at the glTF stuff is this: What exactly is the difference between it and the traditional way? The ONLY difference I see is the fact that they got rid of the diffuse and specular colors, replaced it by a "color", plus a boolean "metal" or "spec" parameter. This is GOOD STUFF; there's no denying that; but is it enough to call their entire system "Physics-Based"? How do hype and pretense compare to substance? I have made that change (1), PLUS: The diff and spec components are separated from albedo having a natural counter-saturation relationship, physics-based (2). The "MetallicSpecularity" that I have is a continuous parameter, CAN be filtered, interpolated, adjusted; makes sense at 0.9, physics-based (3). The naming of parameters I have is far more intuitive, with "Smoothness" for spec power, "Gloss" for index of refraction. In the shader, I modulate intensity of reflections inversely to spot size by a physics-base formula (4) --see first post. I DO have index of refraction (Gloss), which they don't, and is good for skin and a million things, not just water; all physics-based (5). I have a way to specify surface purity (from diffuse particles) to physics-based (6) distinguish paint from plastic, for example. I have a way to specify dielectric rust film thickness for physics-based chromatic reflectivity (7). I separate material from object concerns, and rightfully serve dual UV paradigms. Textures occupy about half as much space in video memory as in glTF Channels are combined into textures in ways that make sense; textures are named intuitively. Final score: 7 to 1 (vis-a-vis physics-based feature count alone). Not really the final score; there's a lot more to it ... In other words, THIS SYSTEM is Physics-Based; NOT glTF. THIS is the ONLY Physics-Based system there is, in all likelihood.
    1 point
  34. I like the idea, but consider issues like crash/internet problems of a player could affect all other teammembers, you can play op but still lose rating. If you evaluate personal play on the other hand you encourage ego strats. So tg could be ranked, but all would have to agree. Also team making when rated could take forever to get all to agree. However also an issue is, that if you only evaluate win/loss and games are well balanced, you can be the player carrying the team all the time but your win rate is 50% so u have still nub rating. Combining rating personal performance and team win would also be somewhat complex to implement, especially in a way so it will really reflect impact, for example op rush but dealy of eco and so on.
    1 point
  35. OBJECT TEXTURES REVISITED (take 2) Object textures are what defines an object's appearance other than material, as mentioned before. Normal_U 8 bits "Forms.png" (PNG sRGBA; no mipmaps) Normal_V 8 bits " Normal_W 8 bits " Height 8 bits " Emit_red 5 bits "Light.dds" (DXT5) Emit_grn 6 bits " Emit_blu 5 bits " Occlusion 8 bits " Faction 5 bits "Zones.dds" (DXT3) DetailMod 6 bits " ???????? 5 bits " Alpha 4 bits " EUREKA! 3 Object Pack textures, with one channel to spare. What I particularly like about it is how the channels hang together: Normals and height are interrelated; they are both form modifiers. Same thing goes for Emission and Occlusion, both of which have to do with light and are "baked" in similar ways. (I don't mean that lightbulbs and torches are baked; I mean how they illuminate the object is something that can be and should be baked. And this baking can be modulated by the CPU; thus, a flame sequence for a torch can have an intensity track which in turn can be used to modulate the baked emissive. And if you worry about actual lights in the emissive texture that should not be modulated, worry not; I dealt with that problem a long time ago; found a trick to decouple light sources from baked illumination. ) Finally, the Zones texture has three zonings. Faction tells where to place faction color. DetailMod tells where and how to add detail noise (0.5 will be NO detail; 0.0 will be max smoothness detail, 1.0 will be max AO detail. For a ground or a very rough surface, AO detail can be best. For a smoother surface, smoothness detail shines). And alpha, which is also a zoning. The reason I chose DXT3 instead of DXT5 for Zones.dds is that the alpha channel does not need ANY precision, in fact, I would have been happy with a single bit alpha for alpha testing, and instead it really needs to NOT be messed up by correlation expectations of the DXT algorithm. And all the stuff that doesn't mipmap well at all, but require high precision and low artifacts, namely the normalmap and the height for parallax, those two are together uncompressed and bi-linearly filtered. I'm particularly happy about keeping the normalmap uncompressed, rather than try the roundabout way of Age of Dragons, of using DXT5 RGB for U, then alpha for V, and computing W on the fly. Like I said, I came up with that VERY idea 20 years ago, EXACTLY same idea, and implemented it, but the results were far less than satisfactory, and eventually we decided to go uncompressed and un-mip-mapped. No need to repeat that long learning experience. The way it is here, the normalmap format is entirely standard, unproblematic, and the alpha channel has the height channel, which is the way it's been done for ages by engines using parallax. Why reinvent a wheel that works well? Those two things, normalmap and height, go well together. To summarize, I have two DXT5 textures for materials, and then one uncompressed, one DXT5 and one DXT3 textures for objects 5 textures altogether, only one of them is not compressed, and the channels they pack MAKE SENSE together. Yes! Compare this with the glTF abomination, which uses 3 UNCOMPRESSED textures, plus one compressed texture that mixes (object) AO with (material) attribute channels, making it useless to any engine that has the good sense to appropriately separate the concerns of objects and materials with separate UV mappings. But so, DXT3 and DXT5 being 4:1 compressed formats, this boils down to glTF being about TWICE THE SIZE of this packing (in video memory terms), and it doesn't even have such material channels as index of refraction, surface purity or passivized layer thickness; and it doesn't have object texture channels such as height, faction, detail texture modulator or even a friggin alpha channel !!! You get not even half the goodness, but have to pay TWICE the price, in video memory consumption, with that glTF stupid garbage ... ( And it pretentiously calls itself "physics based" but doesn't even have a channel for index of refraction. What a joke! ) Here, even the names of textures, and the names of channels, make sense: albedo.dds, optics.dds, forms.png, light.dds and zones.dds. Where else in the world do you get so much clarity? "Smoothness" for specular power, "Gloss" for index of refraction, "Purity" for surface lack of diffuse impurities, "Thickness" for rust thickness ... Any system you look into, nowadays, they intentionally misname things to mystify and pretend. Nobody gives you clarity like this. NOBODY. Couple of closing notes: I worked for years with an engine that supported only 1 UV mapping, Vegastrike, and back then I thought it was good. But it didn't take me 5 minutes around here to realize what a great idea having 2 UV's is. Separating the Material and Object concerns is a Win-Win-WIN, with the added advantage that pixelation concerns are minimized when two uncorrelated mappings are blended. The ability to overlap islands in material space is invaluable, as it creates an appearance of great detail at minimal cost, and reduces artistic work enormously. Imagine if for every building that uses brick or wood you would have to re-create, or at best copy and paste, bricks, or wood. It is insane. Don't throw away the best thing your engine has to offer. Question, instead, the self-proclaimed authorities that came up with that glTF TRASH, --as it will be remembered (if at all) once all the the marketing dust settles. Note that materials don't have Emit, in this system; here temperature is an object-related thing; not a material attribute; such that a lava flow would have to be an object, and have emissive color from the object texture pack, and with (non-emissive) volcanic rock as the material. Which may simply boil down to the terrain, as an object, having an emissive burgundy color painted on the lava flow, to make it glow. Regarding translucent plant leaves, fires, plasma drives and glass, all that will be served by another shader; the "fireglass" shader, as I called it 20 years ago (yes, I coded it back then; but I don't have the files; will have to code it again). (Coming after this one ...) Comments? Opinions? ((But please, keep it to technical merits; don't start telling me I should be a sheeple and follow what "the big guys" do; I would rather kill myself.)) If nobody has anything to add, subtract or point out, I will start working on the shader tomorrow. Regarding exporting materials from Blender, I can't see what problems there'd be. Blender has Index of Refraction, specular power, etc., built in; Cycles has them too. I could come up with a set of nodes for rendering to ensure they follow the exact same math as the shader, and therefore be sure renders look exactly like what objects will look like in-game. Easier to debug in the shader first, THEN transfer to Blender, though. As for texturing in Blender, we could simplify the workflow by using color codes for materials. So you select, say, 16 materials you will need, assign them color codes, then in Blender you paint using color codes, but when you hit F-12 the colors are replaced by actual materials for rendering. Just an idea, and it would probably need a lot of manual touch-up after export due to filtering aritfacts. I'd like to write a tool (in C++) to convert png to DXT1/3/5 better than other tools out there do. I don't know that they DON't do what I would do, yet; but I'm guessing they don't. You know what dithering is? It's basically a recursive algorithm that, given a quantization limitation in a texture, and given a higher precision values texture than is representable in the lesser texture, rather than throwing away data by rounding, tries to spred the errors a little bit among neighboring pixels, so that the overall effect is more precise. Well, I think the same algorithm could be, and should be applied to a texture before DXT compression, except for the peculiar 5,6,5 bits of DXT color representation. So you dither down to where you have the three lowest bits of red an blue channels at zero, and green channel's two least significant bits as zero, while maintaining texel neighborhood color accuracy as much as possible, then DXT-compress. Furthermore, I think in some situations it may be better to NOT use nearest points in the line to pick end colors, but allow the end points to move if it helps the overall matching accuracy with two bit indexes. I'm sure NOBODY is doing these things... Furthermore, where the 16 points form a cloud that's very difficult to linearize, a good algorithm should skip the texel, continue with the others, and once the neighboring texels are worked out, perhaps choose the same line orientation as one of the neigbors, or average the orientations of the neighboring texels. EDIT (day or two later): Zones texture rearranged: Faction 5 bits "Zones.dds" (DXT3) Ageing 6 bits " DetailMod 5 bits " Alpha 4 bits " The reason for this change is that Microns, (oxide layer thickness for iridescent reflections), is actually a "zone" on an "object", rather than a material characteristic. On the other hand, it is but one type of rust metal can exhibit. Rusts can be black, red, orange, greenish for copper, or clear. If we use the albedo alpha channel to encode for a rust color, then this "Ageing" rust mask channel can tell where to apply it and how thick. For colored rusts, Ageing acts like an alpha-blend. For clear rust, it acts as thickness of dielectric film. Perhaps it could be used to also add staining to non-metals. The idea is that if Ageing is fully on (1.0), if AgedColor is a color (below 0.75), it will overwrite albedo and set MSpec and Purity to zero. But if AgedColor is clear (1.0), MSpec and Purity will be maxed out. How this would look on non-metals I don't know and at least for now I don't care.
    1 point
  36. MATERIAL TEXTURES REVISITED (take 2) Red_channel 5 bits "albedo.dds" (DXT5) Green_channel 6 bits " Blue_channel 5 bits " Smoothness 8 bits " MSpecularity 5 bits "optics.dds" (DXT5) SurfacePurity 6 bits " FresnelGloss 5 bits " FilmThickness 8 bits " I was stuck at 2.5 textures for a while, finally decided to get rid of alpha, whether alpha blending or alpha testing, from the materials pack. Leave it to the object pack to do its own alpha. There's really no need to define chicken wire fence as a material, and trees can instance smaller objects representing small branches full of leaves, with object texture pack level alpha. Getting rid of alpha allowed me to use the alpha channel for Smoothness. I was also worried about film thickness precision, as pixelation artifacts in this data can be quite noticeable in the play of rainbow tint reflections; but then I found I had a second 8-bit alpha channel I could use for it. I think this packing ROCKS! (No, not for the rocks; they will get their own shader, which will also rock...) Really super-efficient and optimized. Disney and all those people haven't a clue how to even think ... Next post, this time, will really deal with our Object Textures package. EDIT (couple of days later): Major channel rearrangement: Red_channel 5 bits "albedo.dds" (DXT5) Green_channel 6 bits " Blue_channel 5 bits " AgedColor 8 bits " MSpecularity 5 bits "optics.dds" (DXT5) SurfacePurity 6 bits " FresnelGloss 5 bits " Smoothness 8 bits " "Aged_Color" added; Thickness (of dielectric rust layer) moved to the Object Texture set, Zones texture, second channel, and changed name to "Ageing". The reasons for these changes are as follows: Zones of rusting are actually "Zones" in object space; NOT part of a (shared) material. The "Ageing" channel, in object UV space, will allow demarcation of zones where rusting or staining occurs for an object. Passivated dielectric oxides that glow with iridescence are just one type of oxide; there are matte red, black and orange oxides. So it is clearly adventageous to expand the usefulness of this zoning to include any type of rust or weathering we may want to show; not just iridescence. The AgedColor channel in the albedo texture now encodes a color for "rust", from black (0.0), to red (0.25), to orange (0.5), and then clear (1.0). The 0.75 range is not to be used. When rust is colored (0.0~0.5), the Ageing channel value alpha-blends this color. When it is clear (1.0), the value in the Ageing channel encodes thickness of transparent layer. The alpha-blending of color also reduces MSpec and Purity. When AgedColor is clear (1.0), Ageing's value increases MSpec and Purity. This arrangement improves clarity even further: Now the albedo.dds texture has an rgb albedo, plus it encodes an optional "aged" albedo in alpha. Smoothness, which was rightfully a part of optics, is now in optics.dds. And Thickness, which was a means of zoning rust effects, is now in Zones.dds.
    1 point
  37. Okay, it's not that easy. I just went to refresh my memory on DXT texture formats, and the 5,5,5,1 format doesn't exist. The way it is, which is now coming back, after so many years, is that DDS takes 16 texels at a time (and they call each 16-texel bunch ... a "texel" again... boggles the mind... the world is just drowning in stupidity), places the four incoming colors in a 3D color space, and tries to find the nearest line to all four points; then finds the closest point on the line from each of the points. For the two outer points, it encodes the color as 5,6,5 bits for rgb, and for the two inner points it interpolates using a two bit number. So, 16 bits for each end-color is 32 bits, plus a 2-bit index for each of the 16 texels = 32 bits. 32+32 = 64 bits per 16-texel "texel", which works out to 4 bits per texel (versus 24 bits for uncompressed sRGB). Of course, only 4 colors are actually present in each group of 16 texels, which is rather apathetic. Works well if the image is filtered and dull; but produces a lot of artifacts with sharp images. Well, not necessarily; the issue is with color channel correlations or the lack thereof. The great advantage of this format is that it decompresses locally. If you are decompressing jpg, for example, you have to decompress the entire image at once, so when using jpg or png formats the videocard driver has to do the decompression, and the image is put in video memory uncompressed. DDS format decompresses locally, so the whole texture can be loaded into graphics memory compressed, and decompressed on the fly by the gpu as it reads it, taking a lot less space in video memory (1/4 as much space, to be exact). The take-away is that in an image, depending on the detail and sharpness, you can have uncorrelated R, G and B data scatter, but DXT compression assumes it can bundle this scatter into a single straight line between two colors to interpolate across. In other words, it depends on R/G/B correlation. If you have a linear gradient, whether vertical, horizontal, or at any angle, DXT will capture that very well. But for UNcorrelated change it can be terrible. So, for blurry images it may work well ... What I just described above is actually the most basic rgb format of dxt, namely DXT1, though. There's also two formats containing alpha channels: DXT3 and DXT5. DXT3 and DXT5 both result in the same size texture from a given RGBA input. They just express alpha two different ways, better suited to different circumstances: In DXT5, the minimum and maximum alpha values in the 16-texel "texel" are expressed as 8-bit numbers; so that's 16 bits. Then the 16 texels are interpolated between those two extremes via 3-bit indexes, resulting in up to 8 shades of alpha per 16-texel group. 3 bits x 16 texels = 48 bits. 16+48 = 64, so the size of a DXT5 is double the size of a DXT1, but the quality of the alpha channel is much higher than for rgb, though it may suffer a bit in the interpolation. In DXT3, each of the 16 texels gets an individual alpha value; no fancy interpolations; but each value is 4-bits only. 16 x 4 = 64. DXT5 works better for smoothly changing alpha channels, or for packing smoothly changing data, such as AO. For images with real detail in alpha, such as holes in a fence, you're much better off with DXT3. For data-packing, any smoothly changing data benefitting from higher precision, like AO, would be best encoded as DXT5 alpha, but rapidly changing, detailed data not needing much precision, DXT3's alpha channel is much better. But there's no such thing as a DXT format with 1-bit alpha for alpha-testing. Actually, there probably is, as DXT has a phone-book of texture formats, but the ones commonly used are DXT1,3,5, and I wonder if there's even hardware support for the others.
    1 point
  38. MATERIAL TEXTURES REVISITED Red_channel 5 bits "color.dds" Green_channel 5 bits " Blue_channel 5 bits " Alpha_test_ch 1 bit " FresnelGloss 5 bits "optic.dds" FilmThickness 5 bits " SurfacePurity 5 bits " MSpecularity 1 bit " Smoothness 8 bits "smooth.dds" I decided to forgo the idea of using fractional metallicity for rocks, and leave MSpec as a single bit channel, --"is_metal", in other words. Single-bit channels are not too friendly to mipmapping and filtering, but on the other hand I can't think of an example where metal and non-metal would be finely mixed in a material, EXCEPT ROCKS ... But even in rocks, most metals appear as (optically) non-metallic oxides. I think we can postpone rocks. If worse comes to worst, we could conceivably have a separate shader for rocks and soils. Such a shader could produce the scintillation effect of grain of sand -sized chrystals with flat faces in random directions. I once saw a shader that simulated 8 randomly oriented tiny mirror surfaces per pixel, to give a metallized paint look. Even as I write this, it is becoming more and more clear to me that indeed, rocks and soils deserve a specialized shader. So, as you see above, our material textures are settling nicely. Basically, we have two DDS textures 5+5+5+1 bits, and a monochrome 8-bit, all with mipmaps. I think this it for now for our Material Textures package. Next post I will deal with our Object Textures package.
    1 point
  39. darn! I forgot to include a single-bit alpha-test channel. This is surprising: We need alpha testing for both materials AND objects. Why? For example, you could consider chicken wire fencing a "material" and use alpha-testing for the spaces between wires. Or you could make a whole set of tree-leaves into a material and apply this material to trees having big leaves made of it; but so the material needs alpha-testing. Whereas the object may need alpha testing for all sorts of reasons, windows, bullet-holes, you name it... NOTE: Some readers might be alarmed by the number of textures being discussed. Keep in mind this is the full set, which in many cases may not be used. The only thing I ask, though, is that we use the same shader regardless of whether the object uses or not this texture or that. There should be in the game a folder for commonly used textures, and in this folder there should be a BLACK.PNG, WHITE.PNG, NONM.PNG (NO normal map, e.g 0.5, 0.5, 1.0 blue), etceteras, all 1x1 texel in size. When an object doesn't need a normal map, it just calls for NONM.PNG. Period! No need to change shaders for every combination of textures. If the oject doesn't need an emmissive texture, it calls BLACK.PNG. If it doesn't need an AO it calls GRAY50AO.PNG. Etceteras. ANOTHER NOTE: I like clear terms. I like "smoothness" for specular power much more than I like roughness or glossiness. Roughness is the inverse of specular power, so it is counter-intuitive. Glossiness is a gross misnomer, as it has more to do with reflectivity than with surface geometry. Glossiness could be a good name for the Index of Refraction channel. "Smoothness" is PERFECT. Number two: "Metal" or "Specular"? Both can lead to confusion. How about "MSpec"? It has the advantage that you cannot assume you know what it is; you have to RTFM. Number three: Indeed I really want to use "glossiness" for Index of Refraction, but the imbeciles took it over... If I use it for IOR, now, it will confuse people familiar with the bad systems. darn! ... Well, FARK THEM! "Gloss" it is. NOT "Glossiness"; just "Gloss" That will be the name for IOR. (And for anyone about to argue the term, consider this: You go to the paint store and see a can of "high gloss" varnish. Does that mean that the surface will be very flat? No, the surface will be as flat as you paint it. It means it has a top of the range index of refraction, so it reflects a lot. So I'm not being harsh calling them imbeciles; they ARE TOTAL imbeciles, twisting the meaning of words --deliberately, probably, just to look authoritative and powerful by twisting words AND getting away with it; as well as to mesmerize and confuse and be pretentious.) One thing that looking at that tlGF stuff reminded me of is that multi-channel textures exist. We only have one UV coordinate for material, and one UV coordinate for AO, per fragment shader execution, so it is a bit wasteful to have so many separate texture fetches. If we packed all 8 material channels in one texture, and all 8 object channels in another (AO, normalmap, etc), we could have just two texture fetches (in addition to environment map fetches, of course). That might have better performance. I've never used multi-layer textures, however; I have no idea with regards to their support by older hardware... It shouldn't be too bad, though, as I remember these types of double decker whooper textures existed when I was in this business 20 years ago. But for now I will try to proceed as if I'm targeting a bunch of standard texture formats. In any case, some angles we must look at before moving forward too fast are the precision, dynamic range and mipmap concerns for each of the channels. MIPMAPS: (For those who may not know what mip-maps are: These are like a set of smaller textures packed together with a texture, where each is half the size of the previous. Imagine you take your image in GIMP and scale it 50% and save under a new name; then scale again 50% and save under another name, until you get to a 1x1 texture, then package all those scalings in one file. At game-time, if you zoom out or move away from an object, pixels on the screen would fall on multi-texel strides on the texture, which would introduce aliasing problems, so you pick the the level of scaling that gives you a stride of 1 texel. Or rather, you pick the two scalings with the closest to 1 texel strides, and interpolate between them, as well as in the U and V directions in the texture, which is why this technique is called tri-linear filtering.) Having said that, mipmaps sometimes cause artifacts, rather than prevent them. Just to give you a simple example, normalmaps are kind of infamous vis-a-vis mip-mapping and filtering artifacts. Ambient occlusion isn't negatively impacted by mipmapping at all, but it doesn't always benefit from it, either. Height map (for parallax) can suffer disastrously from mipmapping... Notice a pattern? It seems like all the textures in our Object Textures set are mip-map un-friendly, or at least mip-map skeptical ... Perhaps it's worth considering NOT having mipmaps for Object textures; but stick to bi-linear filtering for them. Food for thought... I can't think of any of the material channels having any serious problems with mip-mapping, on the other hand. Can you? DYNAMIC RANGE: I don't mean HDRI here. Color channels are all 0~1; no material can be albedo of 2. HDRI deals with dynamic range of LIGHT; here we are dealing with MATERIALS. Big difference. The dynamic ranges to consider are for such parameters that need to be mapped to a 0.0~1.0 range. So, it does not apply to red, green or blue. It does not apply to a "boolean" such as "is_metal". It does not apply to the "surface purity" channel, which goes from pure diffuse (0.0 purity), to pure dielectric specularity (1.0 purity). It does, however, apply to... Gloss, our term for Index of Refraction. This is going to be a hard choice here, though... Indexes of refraction for materials go, PRACTICALLY, from 1 to 3. Anything outside this range is for SciFi really. But there are exceptions. Some people argue that metals have negative indices of refraction. If we were to take that at heart, we'd get rid of the MSpec channel, and have Gloss extend down to -1.0. I'm not sure what results we'd get. But it is not a good choice because metals can have a passivated oxide layer that acts as a non-metal, having a positive IOR, of some given thickness; and a negative IOR to represent metal would then be unable to represent metals with transparent oxide surface layers. So the bottom of the range for IOR is 1.0, same IOR as for air and vacuum. Water is 1.5. Glass is 1.5 also, which is why it is so hard to see a piece of glass under water. I think diamond is 2. I heard some materials going a little over 3.0. Then again, there are some laboratory made materials with IOR's as high as 7, or so I've heard. I think that in the interest of simplicity and compromise (and peace) I'm going to set the range to 1.0~5.0, mapped to 0.0~1.0. Thus, IOR = ( Gloss * 4.0 ) + 1.0 Gloss = clamp( ( IOR - 1.0 ) / 4.0, 0.0, 1.0 ) I don't thing Gloss will need too many bits of precision, however, for two reasons: Variations in IOR in a material would not be too apparently noticeable, and they don't often occur, whether naturally or artificially. Thickness of passivated layer, for rainbow tinted specularities, I would tentatively say that the range of interest is up to 10 to 20 wavelengths of red light. 650nm x 10 = 6500nm = 6.5 microns. So, from 6.5 to 13 microns. More than that thickness we get into a range where the rainbow tint cycles would cycle too fast with changing angle to even notice. So, tentatively I say 0 to 10 microns maps in 0.0~1.0 range. You may be wondering why we need a channel for thickness of this passivated oxide layer. We do because whenever you see such rainbow reflections they seem to proceed at different speeds, slowly near areas without the effect, faster away from them; and to produce a realistic effect we'd have to make it do something similar. So, if you are modelling a magical sword made by Indra, you might give it a thick layer on the sides, but thinning towards the edge, and with multiple thinning blobs along the length, and blurred the heck out of, for good measure. This should result in fine bands of rainbow color on the sides (as you turn the sword in reflecting a light), slowing to wide and less changing color bands towards the sharp edge and blobs. Smoothness is a very special case, because here we need to map a range from zero to infinity with a miserable 8 bits of precision. I tackled this in some other thread and came to the conclusion that a pretty good mapping would be one minus the inverse of the fourth root of specular power. Let's try it to see if it works: To texture: Smoothness = 1.0 - 1.0 / sqrt( sqrt( SpecularPower ) ) From texture: SpecularPower = pow( 1.0 / ( 1.0 - Smoothness ), 4.0 ) So, an encoding of 255 for maximum smoothness comes to... 1-255/256 = 1/256; 1/(1/256) = 256; 256^4 = 64k^2 = Too much. In fact, the highest specular power we could ever need is 65000, as that is the specular power that represents a sun reflection of the right diameter, if the sun is modeled as a point source, as per the calculations at the bottom of the first post in this forum thread. So I'm going to change the formula to just a square, instead of a fourth power. To texture: Smoothness = 1.0 - 1.0 / sqrt( SpecularPower )) From texture: SpecularPower = pow( 1.0 / ( 1.0 - Smoothness ), 2.0 ) This channel, however, is probably THE most precision-sensitive channel in the whole package. PRECISION (OR RESOLUTION): For RGB, I defer to the designers of the DDS texture format(s). 5,6,5 bits, or whatever they did, is fine with me. Color is overrated, anyways. Alpha testing by definition needs only 1 bit. MSpec would probably do well with as little as 5 bits. Gloss would probably do well with as little as 5 bits. Purity would probably do well with as little as 5 bits. Thickness of passivated layer would probably do well with as little as 5 bits. Smoothness, OTOH, needs a full 8 bits. Ambient occlusion needs a full 8 bits. Normalmap also needs 8 bits, but we could save the W channel; it can be calculated by the shader from U and V. Emissive would probably do well with as little as 5 bits. Faction color, decal and logo would do with 1 bit each. In the next post I'm going to summarize all this in a table.
    1 point
  40. So, having said all that, let's get to work. Thanks to analyzing glTF's absurdities, I now have a more clear view of the path ahead. Texture channels need to be separated into two distinct groups: MATERIAL TEXTURES Material textures are what defines a material, irrespective of where it is used, irrespective of lighting conditions, irrespective of whether there's a bump on its surface, regardless of whether a blow torch is heating a portion of it and making it glow red. All the material textures care about is the representation of a material, and should include at least the following eight channels: Red Green Blue Specularity (metallic) Smoothness (gloss or ANTI-roughness) Index of refraction Purity of surface layer Thickness of refractive layer (for rainbow tinted metallic reflections through passivated oxide layers) OBJECT TEXTURES Object textures are what defines an object's appearance other than material. Object textures should be material-independent to the extent that you could completely change the material(s) an object is made of and NOT have to even touch the object textures at all. Here are 7 to 9 channels to consider Ambient Occlusion Normal U Normal V Normal W Height (for parallax) Emissive texture (incident light, rather; NOT material-modulated) Faction Color Map Decals and Logos (option to consider) Damage (option to consider) UNDECIDED: There's one channel I've been mentioning, Detail Texture Modulation, which I'm now on the fence whether it should be material-oriented or object oriented... Nah, 1 minute of thinking did it. Object. Why? Because material textures can have unlimited detail due to the freedom to overlap UV islands. Where detail is at a premium is in the second UV set. So adding this as number 7. EDIT: And even if we considered having detail textures for materials, which we can still do, it would probably not be necessary to modulate them. OBJECT TEXTURES (revised) Object textures are what defines an object's appearance other than material. Object textures should be material-independent to the extent that you could completely change the material(s) an object is made of and NOT have to even touch the object textures at all. Here are 8 to 10 channels to consider: Ambient Occlusion Normal U Normal V Normal W Height (for parallax) Emissive texture (incident light, rather; NOT material-modulated) Detail texture modulation Faction Color Map Decals and Logos (option to consider) Damage (option to consider) EDIT: Another thing to consider, for materials, is generative textures. Some algorithms can produce 3D textures, such that you could cut a stone and find what the texture looks like inside. Not much use for this in 0ad, but worth keeping in mind for future expansion in use of the engine.
    1 point
  41. Hyperion, I'm not insisting we do things differently, necessarily. I just want to establish requirements first; even design a packing in full detail; THEN compare to other solutions. I like to think things through from first principles, just like Elon Musk; I don't assume others know better than me. Sometimes it is the case; but I like to discover it, rather than assume it. If I'm going to sit on Disney's shoulder, I want to know EXACTLY what advantage it's going to give me. Am I going to get free scripts that generate all the textures, which otherwise I will have to write my own? Or is it compatibility with rock and stone libraries that go for $50 a virtual bag, when I can get real stone at Dollarama for $1.25? I don't have Substance Painter, or 3ds Max. So all I'm asking is let me go at this the long but sure way. Think it through in detail. Afterwards we compare to something else and figure out if we should go with that instead. I'm frankly tired of hearing about this and that being the ultimate crap sort of marketing, which often amount to 1.5 good ideas under the hood, and a dozen new problems. In electronics, there was the EDA revolution in CAD systems, with probably several million hours of sales teams going around manufacturers to explain what a marvelous new thing EDA was, and the entire world jumped on it, and all the CAD companies became repeaters of the EDA mantra, and here we are today, CAD systems are the same they always was; EDA was complete vapor-ware. There was ISO-9000 and how it was going to revolutionize industry with deep, company wide quality philosophy, and where does it all stand? Companies have to rush once a year to "put something together to show the ISO guy when he comes". Just a huge pile of hogwash. The only effect of these "revolutions" is to actually prevent evolution in the very direction they claim to promote it. In the case of ISO-9000, for example, it prevents good documentation practices. Twice in my career I tried to implement a GOOD documentation system (I do have a working definition) but was told that whatever I did could not conflict with ISO-9000's (dictatorial) ways. I was writing software, at one time, to automate going between parts-lists from my CAD tool and stock control, and was told it was not necessary since the tools coming soon would have EDA and automate all that... Never happened. In this case it may have happened already; but I want to see if the solution is exactly right, or not. And if it isn't exactly right, is there enough advantage in following them to offset the lack(s) or shortcoming(s)? But if you want me to NOT think, just blindly follow, it is not going to work. I've never been, and never will be, a blind follower; and appeal to authority does not appeal to me. EDIT: I'm reading through the page you linked, trying to understand where they are at. One thing that strikes me already is the poor writing, such as "The format does expect the textures in a specific format". It says that base color, normal and emission are saved as individual files, but does not explain why. It insinuates it is due to precision, saying they are PNG, but I can't imagine color or emission are so sensitive to compression. Normalmap yes... So, if I try to piece together this steaming pile of confusion, they basically have the same thing I was suggesting as far as a single RGB for diffuse or specular, controlled by a fourth channel, call it "metal" or "specular", matters not. Then roughness (or gloss) ((or as that game developer suggested SHOULD have been named, "smoothness")) is the specular power. PERIOD. Now, @hyperion , here is the crux of the matter and why we cannot use their solution. Why, in fact, it is poorly thought out: We have two UV layouts in the models. A great idea. 1) The first is for material textures that are shared game-wide. In this layout, islands of unwrap can be freely overlapped, increasing efficiency. 2) The second is for ambient occlusion, where not so much resolution and detail are needed, but the UV islands MUST NOT overlap each other. I presume this second UV layout is the one to use also for normalmap, as well as for the emissive texture. ALL of these must be unique, non-overlapping. If Disney, or whoever came up with this glTF would have spent some time THINKING, they would have realized that all material related files, and all non-material related files, should be kept separate. Thus, you would pack color, metal and roughness in one texture; and ambient occlusion, normal and emission in another. Instead, they mixed things from these two domains randomly: "The Ambient Occlusion, Roughness, and Metallic textures are saved in a single channel-packed texture". And where is the Index of Refraction? This is retarded. In any case, we cannot use it, as our ambient occlusion is in a separate UV. EDIT: This is the only reference I can find so far on the metal/roghness/spec/gloss being anything but semantics: Which is clear as mud to me. So "Metallness [sic] defines where the specular color inherits from the underlying albedo", eh? So where is the texture for undelying albedo? And where in physics does specularity need to "inherit" anything? If anything, albedo should inherit from specularity. When you speak of the albedo of a comet or asteroid, it combines diffuse and specular. Diffuse inherits from specular, in a physical sense, as it is a power of specular color, given multiple bounces. And albedo inherits from diffuse AND specular, by combining them. So here is someone who has no idea what he is saying, pretending to explain the unexplainable, and only going half way... What about specular?
    1 point
  42. Tower-Scene - logs, trees and fence are from BlenderKit
    1 point
  43. Slightly late this week!
    1 point
  44. Some more eyecandy ... also all handmade
    1 point
  45. 1 point
  46. The purpose of this topic is to show in a simple and basic way how to improve your skills in 0a.d with 20 simple tips. 1- SHIFT button. Extremely important, mainly for order of buildings and micro. for example when picking up some wood collectors to build a house, hold the SHIFT button and right click on the house and then again on the wood, so immediately after finishing the house, they will automatically collect wood again. Your enemy is dancing in front of you, and your units missing shots, then select your units, hold SHIFT button, and select the stopped units you want to hit, so after killing the first selected enemy unit, they will fire in the next, avoiding that you shoot the dancer. You have selected 40 units, and you need to select more, keep SHIFT Button press, and select the 15 units, so you have 55 units selected. If you have enough wood and want to build 10 houses, keep SHIFT pressed, select the house and click 10 times in map. SHIFT greatly facilitates the construction of walls (make a test). 2- CTRL button: mainly required to select units. Let's imagine that you have 10 archers, 10 lancers and 10 women, you select them all, then in their interface show 3 small squares in the center with 10 archers, 10 lancers and 10 women. If you hold CTRL Buttom and click on the square of the 10 women, then you take the 10 women out of the selection, stay only 10 archers and 10 lancers, its is very important especially when suffering from harassment. CTRL button is also a shortcut key for storing units in buildings. Select the units, keep CTRL button press, and right click on the building. 3- U buttom. Shortcut button so that the units exit from within the buildings. 4- Two left mouse click. Press two left-clicks on mouse on archers for example, then all archers in your sight will be selected. 5- H button. Your units attacked the nearest unit. 6- Dance: the units automatically attack the nearest units, then select a unit and send it to the front, then click with it from side to side, you can use the SHIFT for this. 7- Storage. Must be made as close just to wood, fruit and hunting as possible. Metal and stone must have a distance that fits the units between the metal/stone to the storage. Doing too close will make your units have to walk a unnecessary distance. If necessary, make two or three. As your wood is cut make new Storages. When there is enough space for a new storage. 8- Outpost: Vision wins game, simple as that. Have vision so you will not have any more surprises. 9- keep some women close to the men, so that the collect gain 10%. 10- Tips for using with CTRL and U. I'll use an example that I only use at the moment (I did not see anyone else use until then). you are playing with iberians, and you are collecting outside the walls, so your enemy attacks you with some horses, you have no way to defend, and the gates are too far for you to run, what do you do? Select your units, press CTRL and click for units to enter the tower of the walls, then quickly click the U button several times so that the units exit quickly (Do not forget to select for the tower to unload the units inside the city). The same can be done with several types of constructions, in several occasions, use your imagination. 11- manipulation of animals: some animals can be manipulated in your favor. If the animal is too far from its storage or CC, hit him, and continues to walk behind it (no more hits), this will take the animal to the desired location. Walruses are aggressive animals, so if you hit a shot at him, they will go after you. then it is important that you select a unit and walk on the map giving a one hit on each,(preference ranges unit) and then send your unit back to your city, all walruses will follow. 12- Buildings within the radius of attack of the CC. An important tip especially for the beginning of the game, keep your houses and other possible constructions within reach of your CC, if your enemy rush you, he probably could not convert his constructions (If this happens, you probably lost the game). 13- Avoid fighting within range of towers and castles. Just fight if it's in your favor, if that does not happen, fight in another region, or make small attacks in multiple places at once. This is a regular mistake among beginners. 14- Whenever possible, make economic upgrades. Serious error between beginners and good players too, and plsssss, baskets upgrade are very, very important, basically you reduce 50% of walking time (first upgrade). 15- In fights whenever possible have melee/tank units on the front. Has already been proven in several tests that melee + ranged can win fights vs only ranged (Of course this depends on several factors). 16- Use constructs like houses/barracks to reach some resources beyond the edge. 17- keep in mind some basic things about factions / units. You are playing on Mauryans and your enemy is Romans, you do not know what strategy he used, but you should avoid some. Example, If he is a smart player it is likely that he will use spear horses against you for the simple fact that archers can not stop them, so what should you do? Make some lancers instead of archers, this will block it. 18- Preferably to armor upgrades rather than attack. Armor upgrades are cheaper, and reach more soldiers than attack upgrades. 1350 for +1 armor for melee and ranges units or 1500 for 20% attack only ranges units? 19- Balance eco. This is the most mistake among all players. Try to keep your economy always balanced and in progress. If you are collecting fruits, and they are running out, do not expect them to end up for making some farms, make before. If you are going to attack/defense, do not use all your units of a particular resource, only in special harassment and specific strategies. This will cause your economy to stop, you will have to switch resources, and this will see a snowball. 20 -keep an eye on the time. Minutes are important so you knew how well or how bad it is going. For me, for example, I know that if I'm in the minute 14 and I'm still in phase 2 in a game without major problems, I'm late, If I am playing against a good player, I can be in serious trouble. Maybe I even have a larger population, but if it has some rams or elephants, this can complicate me. I memorized some schedules, this facilitates my games, I know when to attack, pass phase, and i also know when the enemy probably attacked me in a probable rush. Well there are several other tips, but I hope that in a simple way I can help raise the level of the gameplay. Tips from other players are very welcome.
    1 point
×
×
  • Create New...