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