2 // ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader
3 // written by Forest 'LordHavoc' Hale
5 // use half floats if available for math performance
18 uniform myhvec3 LightColor;
19 #ifdef USEOFFSETMAPPING
20 uniform myhalf OffsetMapping_Scale;
21 uniform myhalf OffsetMapping_Bias;
24 uniform myhalf SpecularPower;
27 uniform myhalf FogRangeRecip;
29 uniform myhalf AmbientScale;
30 uniform myhalf DiffuseScale;
32 uniform myhalf SpecularScale;
35 uniform sampler2D Texture_Normal;
36 uniform sampler2D Texture_Color;
38 uniform sampler2D Texture_Gloss;
41 uniform samplerCube Texture_Cube;
44 uniform sampler2D Texture_FogMask;
47 varying vec2 TexCoord;
48 varying myhvec3 CubeVector;
49 varying vec3 LightVector;
50 #if defined(USESPECULAR) || defined(USEFOG) || defined(USEOFFSETMAPPING)
51 varying vec3 EyeVector;
58 // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright
59 // center and sharp falloff at the edge, this is about the most efficient
60 // we can get away with as far as providing illumination.
62 // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to
63 // provide significant illumination, large = slow = pain.
64 myhalf colorscale = max(1.0 - dot(CubeVector, CubeVector), 0.0);
68 colorscale *= texture2D(Texture_FogMask, myhvec2(length(EyeVector)*FogRangeRecip, 0)).x;
71 #ifdef USEOFFSETMAPPING
72 // this is 3 sample because of ATI Radeon 9500-9800/X300 limits
73 myhvec2 OffsetVector = normalize(EyeVector).xy * vec2(-0.333, 0.333);
74 myhvec2 TexCoordOffset = TexCoord + OffsetVector * (OffsetMapping_Bias + OffsetMapping_Scale * texture2D(Texture_Normal, TexCoord).w);
75 TexCoordOffset += OffsetVector * (OffsetMapping_Bias + OffsetMapping_Scale * texture2D(Texture_Normal, TexCoordOffset).w);
76 TexCoordOffset += OffsetVector * (OffsetMapping_Bias + OffsetMapping_Scale * texture2D(Texture_Normal, TexCoordOffset).w);
77 #define TexCoord TexCoordOffset
80 // get the surface normal
81 #ifdef SURFACENORMALIZE
82 myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - 0.5);
84 myhvec3 surfacenormal = -1.0 + 2.0 * myhvec3(texture2D(Texture_Normal, TexCoord));
88 myhvec3 diffusenormal = myhvec3(normalize(LightVector));
89 myhvec3 color = myhvec3(texture2D(Texture_Color, TexCoord)) * (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));
91 myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));
92 color += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);
96 // apply light cubemap filter
97 color *= myhvec3(textureCube(Texture_Cube, CubeVector));
100 // calculate fragment color (apply light color and attenuation/fog scaling)
101 gl_FragColor = myhvec4(color * LightColor * colorscale, 1);