]> icculus.org git repositories - divverent/nexuiz.git/blob - data/glsl/default.glsl
fixed nex trail effect & moved a spawnpoint on nexdm08
[divverent/nexuiz.git] / data / glsl / default.glsl
1 // ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader
2 // written by Forest 'LordHavoc' Hale
3
4 // common definitions between vertex shader and fragment shader:
5
6 #ifdef __GLSL_CG_DATA_TYPES
7 #define myhalf half
8 #define myhvec2 hvec2
9 #define myhvec3 hvec3
10 #else
11 #define myhalf float
12 #define myhvec2 vec2
13 #define myhvec3 vec3
14 #endif
15
16
17 varying vec2 TexCoord;
18 varying vec2 TexCoordLightmap;
19
20 varying myhvec3 CubeVector;
21 varying vec3 LightVector;
22 varying vec3 EyeVector;
23
24 varying myhvec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)
25 varying myhvec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)
26 varying myhvec3 VectorR; // direction of R texcoord (surface normal)
27
28
29
30
31 // vertex shader specific:
32 #ifdef VERTEX_SHADER
33
34 uniform vec3 LightPosition;
35 uniform vec3 EyePosition;
36 uniform myhvec3 LightDir;
37
38 // TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)
39
40 void main(void)
41 {
42         gl_FrontColor = gl_Color;
43         // copy the surface texcoord
44         TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
45 #if !defined(MODE_LIGHTSOURCE) && !defined(MODE_LIGHTDIRECTION)
46         TexCoordLightmap = vec2(gl_MultiTexCoord4);
47 #endif
48
49 #ifdef MODE_LIGHTSOURCE
50         // transform vertex position into light attenuation/cubemap space
51         // (-1 to +1 across the light box)
52         CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);
53
54         // transform unnormalized light direction into tangent space
55         // (we use unnormalized to ensure that it interpolates correctly and then
56         //  normalize it per pixel)
57         vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;
58         LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);
59         LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);
60         LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);
61 #endif
62
63 #ifdef MODE_LIGHTDIRECTION
64         LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);
65         LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);
66         LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);
67 #endif
68
69         // transform unnormalized eye direction into tangent space
70         vec3 eyeminusvertex = EyePosition - gl_Vertex.xyz;
71         EyeVector.x = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);
72         EyeVector.y = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);
73         EyeVector.z = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);
74
75 #ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE
76         VectorS = gl_MultiTexCoord1.xyz;
77         VectorT = gl_MultiTexCoord2.xyz;
78         VectorR = gl_MultiTexCoord3.xyz;
79 #endif
80
81         // transform vertex to camera space, using ftransform to match non-VS
82         // rendering
83         gl_Position = ftransform();
84 }
85
86 #endif // VERTEX_SHADER
87
88
89
90
91 // fragment shader specific:
92 #ifdef FRAGMENT_SHADER
93
94 uniform sampler2D Texture_Normal;
95 uniform sampler2D Texture_Color;
96 uniform sampler2D Texture_Gloss;
97 uniform samplerCube Texture_Cube;
98 uniform sampler2D Texture_FogMask;
99 uniform sampler2D Texture_Pants;
100 uniform sampler2D Texture_Shirt;
101 uniform sampler2D Texture_Lightmap;
102 uniform sampler2D Texture_Deluxemap;
103 uniform sampler2D Texture_Glow;
104
105 uniform myhvec3 LightColor;
106 uniform myhvec3 AmbientColor;
107 uniform myhvec3 DiffuseColor;
108 uniform myhvec3 SpecularColor;
109 uniform myhvec3 Color_Pants;
110 uniform myhvec3 Color_Shirt;
111 uniform myhvec3 FogColor;
112
113 uniform myhalf OffsetMapping_Scale;
114 uniform myhalf OffsetMapping_Bias;
115 uniform myhalf FogRangeRecip;
116
117 uniform myhalf AmbientScale;
118 uniform myhalf DiffuseScale;
119 uniform myhalf SpecularScale;
120 uniform myhalf SpecularPower;
121
122 void main(void)
123 {
124         // apply offsetmapping
125 #ifdef USEOFFSETMAPPING
126         myhvec2 TexCoordOffset = myhvec2(TexCoord);
127 #define TexCoord TexCoordOffset
128
129         myhvec3 eyedir = myhvec3(normalize(EyeVector));
130
131 #ifdef USEOFFSETMAPPING_RELIEFMAPPING
132         myhalf depthbias = 1.0 - eyedir.z; // should this be a -?
133         depthbias = 1.0 - depthbias * depthbias;
134
135         // 14 sample relief mapping: linear search and then binary search
136         myhvec3 OffsetVector = myhvec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * myhvec2(-0.1, 0.1), -0.1);
137         vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;
138         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
139         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
140         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
141         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
142         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
143         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
144         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
145         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;
146         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
147         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
148         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
149         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
150         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
151         if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;
152         TexCoord = RT.xy;
153 #else
154
155         // parallax mapping as described in the paper
156         // "Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces" by Terry Welsh
157         // The paper provides code in the ARB fragment program assembly language
158         // I translated it to GLSL but may have done something wrong - SavageX
159         myhalf height = texture2D(Texture_Normal, TexCoord).a;
160         height = (height * myhalf(OffsetMapping_Scale)) + myhalf(-0.02); // scale and bias
161         TexCoordOffset += myhalf(height) * myhvec2(eyedir.x, -1.0 * eyedir.y);
162         
163 #endif
164 #endif
165
166         // combine the diffuse textures (base, pants, shirt)
167         vec4 color = vec4(texture2D(Texture_Color, TexCoord));
168 #ifdef USECOLORMAPPING
169         color.rgb += myhvec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhvec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;
170 #endif
171
172
173
174
175 #ifdef MODE_LIGHTSOURCE
176         // light source
177
178         // get the surface normal and light normal
179         myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - 0.5);
180         myhvec3 diffusenormal = myhvec3(normalize(LightVector));
181
182         // calculate directional shading
183         color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));
184 #ifdef USESPECULAR
185         myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));
186         color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);
187 #endif
188
189 #ifdef USECUBEFILTER
190         // apply light cubemap filter
191         //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));
192         color.rgb *= myhvec3(textureCube(Texture_Cube, CubeVector));
193 #endif
194
195         // apply light color
196         color.rgb *= LightColor;
197
198         // apply attenuation
199         //
200         // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright
201         // center and sharp falloff at the edge, this is about the most efficient
202         // we can get away with as far as providing illumination.
203         //
204         // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to
205         // provide significant illumination, large = slow = pain.
206         color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);
207
208
209
210
211 #elif defined(MODE_LIGHTDIRECTION)
212         // directional model lighting
213
214         // get the surface normal and light normal
215         myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - 0.5);
216         myhvec3 diffusenormal = myhvec3(normalize(LightVector));
217
218         // calculate directional shading
219         color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);
220 #ifdef USESPECULAR
221         myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));
222         color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);
223 #endif
224
225
226
227
228 #elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)
229         // deluxemap lightmapping using light vectors in modelspace (evil q3map2)
230
231         // get the surface normal and light normal
232         myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - 0.5);
233         
234         #ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE
235         myhvec3 diffusenormal_modelspace = myhvec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;
236         myhvec3 diffusenormal = normalize(myhvec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));
237         #else 
238         myhvec3 diffusenormal = normalize(myhvec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);
239         #endif
240         // calculate directional shading
241         myhvec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));
242 #ifdef USESPECULAR
243         myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));
244         tempcolor += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);
245 #endif
246
247         // apply lightmap color
248         color.rgb = tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * myhvec3(AmbientScale);
249
250
251 #else // MODE none (lightmap)
252         // apply lightmap color
253         color.rgb *= myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + myhvec3(AmbientScale);
254 #endif // MODE
255
256 #ifdef USEGLOW
257         color.rgb += myhvec3(texture2D(Texture_Glow, TexCoord));
258 #endif
259
260 #ifdef USEFOG
261         // apply fog
262         myhalf fog = texture2D(Texture_FogMask, myhvec2(length(EyeVector)*FogRangeRecip, 0.0)).x;
263         color.rgb = color.rgb * fog + FogColor * (1.0 - fog);
264 #endif
265
266         gl_FragColor = color * gl_Color;
267 }
268
269 #endif // FRAGMENT_SHADER