]> icculus.org git repositories - divverent/nexuiz.git/blob - data/glsl/light.frag
more attic dirs
[divverent/nexuiz.git] / data / glsl / light.frag
1
2 // ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader
3 // written by Forest 'LordHavoc' Hale
4
5 // use half floats if available for math performance
6 #ifdef GEFORCEFX
7 #define myhalf half
8 #define myhvec2 hvec2
9 #define myhvec3 hvec3
10 #define myhvec4 hvec4
11 #else
12 #define myhalf float
13 #define myhvec2 vec2
14 #define myhvec3 vec3
15 #define myhvec4 vec4
16 #endif
17
18 uniform myhvec3 LightColor;
19 #ifdef USEOFFSETMAPPING
20 uniform myhalf OffsetMapping_Scale;
21 uniform myhalf OffsetMapping_Bias;
22 #endif
23 #ifdef USESPECULAR
24 uniform myhalf SpecularPower;
25 #endif
26 #ifdef USEFOG
27 uniform myhalf FogRangeRecip;
28 #endif
29 uniform myhalf AmbientScale;
30 uniform myhalf DiffuseScale;
31 #ifdef USESPECULAR
32 uniform myhalf SpecularScale;
33 #endif
34
35 uniform sampler2D Texture_Normal;
36 uniform sampler2D Texture_Color;
37 #ifdef USESPECULAR
38 uniform sampler2D Texture_Gloss;
39 #endif
40 #ifdef USECUBEFILTER
41 uniform samplerCube Texture_Cube;
42 #endif
43 #ifdef USEFOG
44 uniform sampler2D Texture_FogMask;
45 #endif
46
47 varying vec2 TexCoord;
48 varying myhvec3 CubeVector;
49 varying vec3 LightVector;
50 #if defined(USESPECULAR) || defined(USEFOG) || defined(USEOFFSETMAPPING)
51 varying vec3 EyeVector;
52 #endif
53
54 void main(void)
55 {
56         // attenuation
57         //
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.
61         //
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);
65
66 #ifdef USEFOG
67         // apply fog
68         colorscale *= texture2D(Texture_FogMask, myhvec2(length(EyeVector)*FogRangeRecip, 0)).x;
69 #endif
70
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
78 #endif
79
80         // get the surface normal
81 #ifdef SURFACENORMALIZE
82         myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - 0.5);
83 #else
84         myhvec3 surfacenormal = -1.0 + 2.0 * myhvec3(texture2D(Texture_Normal, TexCoord));
85 #endif
86
87         // calculate shading
88         myhvec3 diffusenormal = myhvec3(normalize(LightVector));
89         myhvec3 color = myhvec3(texture2D(Texture_Color, TexCoord)) * (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));
90 #ifdef USESPECULAR
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);
93 #endif
94
95 #ifdef USECUBEFILTER
96         // apply light cubemap filter
97         color *= myhvec3(textureCube(Texture_Cube, CubeVector));
98 #endif
99
100         // calculate fragment color (apply light color and attenuation/fog scaling)
101         gl_FragColor = myhvec4(color * LightColor * colorscale, 1);
102 }
103