Super shader
Motivation, goal
Super shader is shader which contains all our standard shader techniques (such as normal, specular, ambient, detail maps etc.) a furthermore it has on input fresnel map defining course of specularity similarly to shader Glass.
Goal is to start use this shader for all usual objects which we see ingame.For such objects which haven't defined some maps may be used default, procedurally generated textures.
Definition of individual stages in material
In frames are quoted default values in case we want that stage ignored.
1. Normal map
Normal map of type _NO or _NOHQ.
texture="#(argb,8,8,3)color(0.5,0.5,1,1)";
2. Detail map
Detail map of type _DT.
texture="#(argb,8,8,3)color(0.5,0.5,0.5,0)";
3. Macro map
Macro map _MC.
texture="#(argb,8,8,3)color(0,0,0,0)";
4. AmbientShadow map
Ambient shadow map _AS.
texture="#(argb,8,8,3)color(0,1,1,1)";
5. Specular map
Specular mapa of type _SMDI. On the contrary map of typ _SM isn't supported.
6. Fresnel function
Fresnel function is entered as procedural texture in following form: texture="#(ai,64,64,1)fresnel(N,K)";. N and K are inputs for fresnel equation that's on theirs basics and for given angle able determine how much reflects under given angle. N and K are constant for given material and are known for individual elements. Following table include roundup of basic materials and theirs settings. In table are shown values for individual wavelenghts which was possible found. Visible spectrum is approx 400µm-800µm. Interesting are values around middle of this inerval (if available).
Material | wavelength | N | K |
Aluminum | 600 | 1.3 | 7 |
Cobalt | 600 | 0.2 | 3 |
Copper | 850 | 2.08 | 7.15 |
Gold | 600 | 0.3 | 3 |
Iron | 886 | 3.12 | 3.87 |
Lead | 850 | 1.44 | 4.35 |
Molybdenum | 954 | 2.77 | 3.74 |
Nickel | 855 | 2.59 | 4.55 |
Palladium | 827 | 2.17 | 5.22 |
Platinum | 827 | 2.92 | 5.07 |
Silver | 600 | 0.2 | 3 |
Titanium | 821 | 3.21 | 4.01 |
Vanadium | 984 | 2.94 | 3.50 |
Tungsten | 827 | 3.48 | 2.79 |
Additional sources where You can find N and K values: http://en.wikipedia.org/wiki/List_of_refractive_indices
Other values must must be found e.g. empirically. For that may help following program which can inside TexView visualize course of fresnel function for given N and K (on left is normal line to line of sight, on right directly against line of sight, the more is value closer 1 the higher reflection is):
N = 0.969770; K = 0.0118000; X = u * 0.5 + 0.5; S = acos(X); AA = sqrt((sqrt((N^2-K^2-sin(S)^2)^2 + 4*N^2*K^2)+(N^2-K^2-sin(S)^2))/2); BB = sqrt((sqrt((N^2-K^2-sin(S)^2)^2 + 4*N^2*K^2)-(N^2-K^2-sin(S)^2))/2); FS = (AA^2+BB^2-2*AA*cos(S) + cos(S)^2)/(AA^2+BB^2+2*AA*cos(S) + cos(S)^2); FP = FS*(AA^2+BB^2-2*AA*sin(S)*tan(S)+sin(S)^2*tan(S)^2)/(AA^2+BB^2+2*AA*sin(S)*tan(S)+sin(S)^2*tan(S)^2); r=1; g=1; b=1; a=(FS+FP)/2;
7. Environmental map
Environmental map.
Example
ambient[]={1.000000,1.000000,1.000000,1.000000}; diffuse[]={1.000000,1.000000,1.000000,1.000000}; forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000}; emmisive[]={0.000000,0.000000,0.000000,1.000000}; specular[]={0.700000,0.700000,0.700000,1.000000}; specularPower=180.000000; PixelShaderID="Super"; VertexShaderID="Super"; class Stage1 { texture="ca\weapons\data\aimpoint_NOHQ.paa"; uvSource="tex"; }; class Stage2 { texture="#(argb,8,8,3)color(0.5,0.5,0.5,0)"; uvSource="tex"; }; class Stage3 { texture="#(argb,8,8,3)color(0,0,0,0)"; uvSource="tex"; }; class Stage4 { texture="#(argb,8,8,3)color(0,1,1,1)"; uvSource="tex"; }; class Stage5 { texture="ca\weapons\data\aimpoint_SMDI.paa"; uvSource="tex"; }; class Stage6 { texture="#(ai,64,64,1)fresnel(1.3,7)"; uvSource="none"; }; class Stage7 { texture="ca\air\data\env_co.paa"; uvSource="none"; };
How is gained fresnel from procedural texture
Procedural texture for fresnel function contains single-dimensional conversion table (visually it's sort of brightness gradient ) from which reads value on position (U,V). Value U is calculated as scalar product between normal line and direction to the camera (both vertors must be normalized)) in each surface point of model (this value also represents cosine of angle between vectors). Value V is always 0.5, therefore it's unneeded that texture height would be different than 1. For example: function with parameters N = 1.0 and K = 0.6 should be entered with width 64 and height 1: "#(ai,64,1,1)fresnel(1.0,0.6)". Size of texture is then only 64 bytes instead 4096 in case if the height is 64. When we realize that such texture is generated for every material with fresnel inside scene, then saving of memory and performance is indispensable!
Picture with visual representation of obtaining fresnel value from procedural texture: