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