]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
reorganized GLSL shader
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 24 Dec 2009 12:21:52 +0000 (12:21 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 24 Dec 2009 12:21:52 +0000 (12:21 +0000)
added Cg shader

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9669 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c

index 5c81aa92c93b6dde10994d440990f0ebb08c3d8e..e88b31efbaced40464eb4d6d1d82b30f8ea705e4 100644 (file)
@@ -456,11 +456,59 @@ static void R_BuildFogTexture(void)
        }
 }
 
+//=======================================================================================================================================================
+
 static const char *builtinshaderstring =
 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
 "// written by Forest 'LordHavoc' Hale\n"
+"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
+"\n"
+"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
+"# define USEFOG\n"
+"#endif\n"
+"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"#define USELIGHTMAP\n"
+"#endif\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n"
+"#define USEEYEVECTOR\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
+"# extension GL_ARB_texture_rectangle : enable\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef GL_EXT_gpu_shader4\n"
+"#   extension GL_EXT_gpu_shader4 : enable\n"
+"# endif\n"
+"# ifdef GL_ARB_texture_gather\n"
+"#   extension GL_ARB_texture_gather : enable\n"
+"# else\n"
+"#   ifdef GL_AMD_texture_texture4\n"
+"#     extension GL_AMD_texture_texture4 : enable\n"
+"#   endif\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# extension GL_EXT_gpu_shader4 : enable\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWSAMPLER\n"
+"# extension GL_ARB_shadow : enable\n"
+"#endif\n"
 "\n"
-"// enable various extensions depending on permutation:\n"
+"//#ifdef __GLSL_CG_DATA_TYPES\n"
+"//# define myhalf half\n"
+"//# define myhalf2 half2\n"
+"//# define myhalf3 half3\n"
+"//# define myhalf4 half4\n"
+"//#else\n"
+"# define myhalf float\n"
+"# define myhalf2 vec2\n"
+"# define myhalf3 vec3\n"
+"# define myhalf4 vec4\n"
+"//#endif\n"
 "\n"
 "#ifdef VERTEX_SHADER\n"
 "uniform mat4 ModelViewProjectionMatrix;\n"
@@ -474,6 +522,10 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif\n"
 "#else // !MODE_DEPTH_ORSHADOW\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_SHOWDEPTH\n"
 "#ifdef VERTEX_SHADER\n"
 "void main(void)\n"
@@ -490,6 +542,10 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif\n"
 "#else // !MODE_SHOWDEPTH\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_POSTPROCESS\n"
 "varying vec2 TexCoord1;\n"
 "varying vec2 TexCoord2;\n"
@@ -562,6 +618,10 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif\n"
 "#else // !MODE_POSTPROCESS\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_GENERIC\n"
 "#ifdef USEDIFFUSE\n"
 "varying vec2 TexCoord1;\n"
@@ -613,6 +673,10 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif\n"
 "#else // !MODE_GENERIC\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_BLOOMBLUR\n"
 "varying TexCoord;\n"
 "#ifdef VERTEX_SHADER\n"
@@ -690,6 +754,10 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif\n"
 "#else // !MODE_REFRACTION\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_WATER\n"
 "varying vec2 TexCoord;\n"
 "varying vec3 EyeVector;\n"
@@ -750,55 +818,16 @@ static const char *builtinshaderstring =
 "#endif\n"
 "#else // !MODE_WATER\n"
 "\n"
-"#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
-"# extension GL_ARB_texture_rectangle : enable\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef GL_EXT_gpu_shader4\n"
-"#   extension GL_EXT_gpu_shader4 : enable\n"
-"# endif\n"
-"# ifdef GL_ARB_texture_gather\n"
-"#   extension GL_ARB_texture_gather : enable\n"
-"# else\n"
-"#   ifdef GL_AMD_texture_texture4\n"
-"#     extension GL_AMD_texture_texture4 : enable\n"
-"#   endif\n"
-"# endif\n"
-"#endif\n"
 "\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# extension GL_EXT_gpu_shader4 : enable\n"
-"#endif\n"
 "\n"
-"#ifdef USESHADOWSAMPLER\n"
-"# extension GL_ARB_shadow : enable\n"
-"#endif\n"
 "\n"
 "// common definitions between vertex shader and fragment shader:\n"
 "\n"
-"//#ifdef __GLSL_CG_DATA_TYPES\n"
-"//# define myhalf half\n"
-"//# define myhalf2 half2\n"
-"//# define myhalf3half3\n"
-"//# define myhalf4 half4\n"
-"//#else\n"
-"# define myhalf float\n"
-"# define myhalf2 vec2\n"
-"# define myhalf3 vec3\n"
-"# define myhalf4 vec4\n"
-"//#endif\n"
-"\n"
-"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
-"# define USEFOG\n"
-"#endif\n"
-"\n"
 "varying vec2 TexCoord;\n"
 "#ifdef USEVERTEXTEXTUREBLEND\n"
 "varying vec2 TexCoord2;\n"
 "#endif\n"
-"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USELIGHTMAP\n"
+"#ifdef USELIGHTMAP\n"
 "varying vec2 TexCoordLightmap;\n"
 "#endif\n"
 "\n"
@@ -813,14 +842,11 @@ static const char *builtinshaderstring =
 "varying vec3 LightVector;\n"
 "#endif\n"
 "\n"
-"#if defined(USEOFFSETMAPPING) || defined(USESPECULAR)\n"
-"//#if defined(USEOFFSETMAPPING) || defined(USESPECULAR) || defined(MODE_LIGHTDIRECTION) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USEEYEVECTOR\n"
+"#ifdef USEEYEVECTOR\n"
 "varying vec3 EyeVector;\n"
 "#endif\n"
 "#ifdef USEFOG\n"
-"varying vec3 EyeVectorModelSpace;\n"
-"varying float FogPlaneVertexDist;\n"
+"varying vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n"
 "#endif\n"
 "\n"
 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
@@ -850,129 +876,8 @@ static const char *builtinshaderstring =
 "\n"
 "\n"
 "\n"
-"// vertex shader specific:\n"
-"#ifdef VERTEX_SHADER\n"
-"\n"
 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
 "\n"
-"#ifdef MODE_DEFERREDGEOMETRY\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-"      TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"      gl_FrontColor = gl_Color;\n"
-"      TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"\n"
-"      // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEOFFSETMAPPING\n"
-"      vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"      VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
-"      VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
-"      VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
-"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#else // !MODE_DEFERREDGEOMETRY\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-"      ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
-"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#else // !MODE_DEFERREDLIGHTSOURCE\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform mat4 ModelToLight;\n"
-"#endif\n"
-"void main(void)\n"
-"{\n"
-"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
-"      gl_FrontColor = gl_Color;\n"
-"#endif\n"
-"      // copy the surface texcoord\n"
-"      TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"      TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-"      TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"      // transform vertex position into light attenuation/cubemap space\n"
-"      // (-1 to +1 across the light box)\n"
-"      CubeVector = vec3(ModelToLight * gl_Vertex);\n"
-"\n"
-"# ifdef USEDIFFUSE\n"
-"      // transform unnormalized light direction into tangent space\n"
-"      // (we use unnormalized to ensure that it interpolates correctly and then\n"
-"      //  normalize it per pixel)\n"
-"      vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
-"      LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
-"      LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
-"      LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
-"      LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
-"      LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
-"      LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"      // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEEYEVECTOR\n"
-"#ifndef USEFOG\n"
-"      vec3 EyeVectorModelSpace;\n"
-"#endif\n"
-"      EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-"#ifndef USEEYEVECTOR\n"
-"      EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-"#endif\n"
-"      FogPlaneVertexDist = dot(FogPlane, gl_Vertex);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"      VectorS = gl_MultiTexCoord1.xyz;\n"
-"      VectorT = gl_MultiTexCoord2.xyz;\n"
-"      VectorR = gl_MultiTexCoord3.xyz;\n"
-"#endif\n"
-"\n"
-"      // transform vertex to camera space, using ftransform to match non-VS rendering\n"
-"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"\n"
-"#ifdef USEREFLECTION\n"
-"      ModelViewProjectionPosition = gl_Position;\n"
-"#endif\n"
-"}\n"
-"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
-"#endif // !MODE_DEFERREDGEOMETRY\n"
-"\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
 "// fragment shader specific:\n"
 "#ifdef FRAGMENT_SHADER\n"
 "\n"
@@ -1028,15 +933,17 @@ static const char *builtinshaderstring =
 "uniform float FogRangeRecip;\n"
 "uniform float FogPlaneViewDist;\n"
 "uniform float FogHeightFade;\n"
-"myhalf FogVertex(void)\n"
+"float FogVertex(void)\n"
 "{\n"
+"      vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
+"      float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
 "      float fogfrac;\n"
 "#ifdef USEFOGOUTSIDE\n"
 "      fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
 "#else\n"
 "      fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
 "#endif\n"
-"      return myhalf(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
+"      return float(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
 "}\n"
 "#endif\n"
 "\n"
@@ -1124,10 +1031,10 @@ static const char *builtinshaderstring =
 "#endif\n"
 "\n"
 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"# ifndef USESHADOWMAPVSDCT\n"
 "vec3 GetShadowMapTC2D(vec3 dir)\n"
 "{\n"
 "      vec3 adir = abs(dir);\n"
-"# ifndef USESHADOWMAPVSDCT\n"
 "      vec2 tc;\n"
 "      vec2 offset;\n"
 "      float ma;\n"
@@ -1166,22 +1073,26 @@ static const char *builtinshaderstring =
 "      stc.xy += offset * ShadowMap_Parameters.y;\n"
 "      stc.z += ShadowMap_Parameters.z;\n"
 "      return stc;\n"
+"}\n"
 "# else\n"
+"vec3 GetShadowMapTC2D(vec3 dir)\n"
+"{\n"
+"      vec3 adir = abs(dir);\n"
 "      vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
 "      float ma = max(max(adir.x, adir.y), adir.z);\n"
 "      vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
 "      stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
 "      stc.z += ShadowMap_Parameters.z;\n"
 "      return stc;\n"
-"# endif\n"
 "}\n"
+"# endif\n"
 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
 "\n"
 "#ifdef USESHADOWMAPCUBE\n"
 "vec4 GetShadowMapTCCube(vec3 dir)\n"
 "{\n"
-"    vec3 adir = abs(dir);\n"
-"    return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
+"      vec3 adir = abs(dir);\n"
+"      return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
 "}\n"
 "#endif\n"
 "\n"
@@ -1194,9 +1105,9 @@ static const char *builtinshaderstring =
 "\n"
 "#    ifdef USESHADOWMAPPCF\n"
 "#      define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n"
-"    f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"      f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
 "#    else\n"
-"    f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
+"      f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
 "#    endif\n"
 "\n"
 "#  else\n"
@@ -1204,24 +1115,24 @@ static const char *builtinshaderstring =
 "#    ifdef USESHADOWMAPPCF\n"
 "#      if USESHADOWMAPPCF > 1\n"
 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n"
-"    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-"    vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
-"    vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
-"    vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
-"    vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
-"    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-"    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+"      vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"      vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+"      vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
+"      vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
+"      vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
+"      vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+"      f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
 "#      else\n"
 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(x, y)).r\n"
-"    vec2 offset = fract(shadowmaptc.xy);\n"
-"    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-"    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
-"    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
-"    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-"    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
+"      vec2 offset = fract(shadowmaptc.xy);\n"
+"      vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+"      vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
+"      vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
+"      vec3 cols = row2 + mix(row1, row3, offset.y);\n"
+"      f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
 "#      endif\n"
 "#    else\n"
-"    f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
+"      f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
 "#    endif\n"
 "\n"
 "#  endif\n"
@@ -1232,16 +1143,16 @@ static const char *builtinshaderstring =
 "# ifdef USESHADOWMAP2D\n"
 "float ShadowMapCompare(vec3 dir)\n"
 "{\n"
-"    vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
-"    float f;\n"
+"      vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
+"      float f;\n"
 "\n"
 "#  ifdef USESHADOWSAMPLER\n"
 "#    ifdef USESHADOWMAPPCF\n"
 "#      define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r  \n"
-"    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
-"    f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"      vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
+"      f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
 "#    else\n"
-"    f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
+"      f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
 "#    endif\n"
 "#  else\n"
 "#    ifdef USESHADOWMAPPCF\n"
@@ -1251,15 +1162,15 @@ static const char *builtinshaderstring =
 "#      else\n"
 "#        define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x,y)*ShadowMap_TextureScale)\n"
 "#      endif\n"
-"    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-"    center *= ShadowMap_TextureScale;\n"
-"    vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
-"    vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
-"    vec4 group3 = step(shadowmaptc.z, texval(-1.0,  1.0));\n"
-"    vec4 group4 = step(shadowmaptc.z, texval( 1.0,  1.0));\n"
-"    vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
-"                mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
-"    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+"      vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"      center *= ShadowMap_TextureScale;\n"
+"      vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
+"      vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
+"      vec4 group3 = step(shadowmaptc.z, texval(-1.0,  1.0));\n"
+"      vec4 group4 = step(shadowmaptc.z, texval( 1.0,  1.0));\n"
+"      vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
+"                              mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
+"      f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
 "#     else\n"
 "#      ifdef GL_EXT_gpu_shader4\n"
 "#        define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
@@ -1267,52 +1178,86 @@ static const char *builtinshaderstring =
 "#        define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r  \n"
 "#      endif\n"
 "#      if USESHADOWMAPPCF > 1\n"
-"    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-"    center *= ShadowMap_TextureScale;\n"
-"    vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
-"    vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
-"    vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
-"    vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
-"    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-"    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+"      vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"      center *= ShadowMap_TextureScale;\n"
+"      vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+"      vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
+"      vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
+"      vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
+"      vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+"      f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
 "#      else\n"
-"    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
-"    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-"    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
-"    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
-"    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-"    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
+"      vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
+"      vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+"      vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
+"      vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
+"      vec3 cols = row2 + mix(row1, row3, offset.y);\n"
+"      f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
 "#      endif\n"
 "#     endif\n"
 "#    else\n"
-"    f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
+"      f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
 "#    endif\n"
 "#  endif\n"
-"    return f;\n"
+"      return f;\n"
 "}\n"
 "# endif\n"
 "\n"
 "# ifdef USESHADOWMAPCUBE\n"
 "float ShadowMapCompare(vec3 dir)\n"
 "{\n"
-"    // apply depth texture cubemap as light filter\n"
-"    vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
-"    float f;\n"
+"      // apply depth texture cubemap as light filter\n"
+"      vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
+"      float f;\n"
 "#  ifdef USESHADOWSAMPLER\n"
-"    f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
+"      f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
 "#  else\n"
-"    f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
+"      f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
 "#  endif\n"
-"    return f;\n"
+"      return f;\n"
 "}\n"
 "# endif\n"
 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"\n"
+"\n"
 "\n"
 "#ifdef MODE_DEFERREDGEOMETRY\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
+"uniform mat4 ModelViewMatrix;\n"
 "void main(void)\n"
 "{\n"
-"#ifdef USEOFFSETMAPPING\n"
-"      // apply offsetmapping\n"
+"      TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      gl_FrontColor = gl_Color;\n"
+"      TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
+"#endif\n"
+"\n"
+"      // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEOFFSETMAPPING\n"
+"      vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"      VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
+"      VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
+"      VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
+"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main(void)\n"
+"{\n"
+"#ifdef USEOFFSETMAPPING\n"
+"      // apply offsetmapping\n"
 "      vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
 "#define TexCoord TexCoordOffset\n"
 "#endif\n"
@@ -1337,8 +1282,23 @@ static const char *builtinshaderstring =
 "\n"
 "      gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), 1);\n"
 "}\n"
+"#endif // FRAGMENT_SHADER\n"
 "#else // !MODE_DEFERREDGEOMETRY\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 ModelViewMatrix;\n"
+"void main(void)\n"
+"{\n"
+"      ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
+"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
 "uniform mat4 ViewToLight;\n"
 "// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
 "uniform vec2 ScreenToDepth;\n"
@@ -1400,7 +1360,88 @@ static const char *builtinshaderstring =
 "      gl_FragData[1] *= cubecolor;\n"
 "# endif\n"
 "}\n"
+"#endif // FRAGMENT_SHADER\n"
 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform mat4 ModelToLight;\n"
+"#endif\n"
+"void main(void)\n"
+"{\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
+"      gl_FrontColor = gl_Color;\n"
+"#endif\n"
+"      // copy the surface texcoord\n"
+"      TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+"      TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"      // transform vertex position into light attenuation/cubemap space\n"
+"      // (-1 to +1 across the light box)\n"
+"      CubeVector = vec3(ModelToLight * gl_Vertex);\n"
+"\n"
+"# ifdef USEDIFFUSE\n"
+"      // transform unnormalized light direction into tangent space\n"
+"      // (we use unnormalized to ensure that it interpolates correctly and then\n"
+"      //  normalize it per pixel)\n"
+"      vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
+"      LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
+"      LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
+"      LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
+"      LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
+"      LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
+"      LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"      // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEEYEVECTOR\n"
+"      vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+"      EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"      VectorS = gl_MultiTexCoord1.xyz;\n"
+"      VectorT = gl_MultiTexCoord2.xyz;\n"
+"      VectorR = gl_MultiTexCoord3.xyz;\n"
+"#endif\n"
+"\n"
+"      // transform vertex to camera space, using ftransform to match non-VS rendering\n"
+"      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"\n"
+"#ifdef USEREFLECTION\n"
+"      ModelViewProjectionPosition = gl_Position;\n"
+"#endif\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
 "#ifdef USEDEFERREDLIGHTMAP\n"
 "uniform myhalf3 DeferredMod_Diffuse;\n"
 "uniform myhalf3 DeferredMod_Specular;\n"
@@ -1581,8 +1622,12 @@ static const char *builtinshaderstring =
 "#endif\n"
 "\n"
 "#ifdef USEFOG\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"      color.rgb *= myhalf(FogVertex());\n"
+"#else\n"
 "      color.rgb = mix(FogColor, color.rgb, FogVertex());\n"
 "#endif\n"
+"#endif\n"
 "\n"
 "      // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
 "#ifdef USEREFLECTION\n"
@@ -1605,11 +1650,1441 @@ static const char *builtinshaderstring =
 "\n"
 "      gl_FragColor = vec4(color);\n"
 "}\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
 "#endif // !MODE_DEFERREDGEOMETRY\n"
+"#endif // !MODE_WATER\n"
+"#endif // !MODE_REFRACTION\n"
+"#endif // !MODE_BLOOMBLUR\n"
+"#endif // !MODE_GENERIC\n"
+"#endif // !MODE_POSTPROCESS\n"
+"#endif // !MODE_SHOWDEPTH\n"
+"#endif // !MODE_DEPTH_OR_SHADOW\n"
+;
+
+/*
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+*/
+
+const char *builtincgshaderstring =
+"// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
+"// written by Forest 'LordHavoc' Hale\n"
+"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
 "\n"
-"#endif // FRAGMENT_SHADER\n"
+"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
+"# define USEFOG\n"
+"#endif\n"
+"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"#define USELIGHTMAP\n"
+"#endif\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n"
+"#define USEEYEVECTOR\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_DEPTH_OR_SHADOW\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"out float4 gl_Position : POSITION\n"
+")\n"
+"{\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_DEPTH_ORSHADOW\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_SHOWDEPTH\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR0\n"
+")\n"
+"{\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"      gl_FrontColor = float4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_FrontColor : COLOR0,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      gl_FragColor = gl_FrontColor;\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_SHOWDEPTH\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_POSTPROCESS\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord1 : TEXCOORD0,\n"
+"out float2 TexCoord2 : TEXCOORD1\n"
+")\n"
+"{\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"      TexCoord1 = gl_MultiTexCoord0.xy;\n"
+"#ifdef USEBLOOM\n"
+"      TexCoord2 = gl_MultiTexCoord1.xy;\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord1 : TEXCOORD0,\n"
+"float2 TexCoord2 : TEXCOORD1,\n"
+"uniform sampler2D Texture_First,\n"
+"#ifdef USEBLOOM\n"
+"uniform sampler2D Texture_Second,\n"
+"#endif\n"
+"#ifdef USEGAMMARAMPS\n"
+"uniform sampler2D Texture_GammaRamps,\n"
+"#endif\n"
+"#ifdef USESATURATION\n"
+"uniform float Saturation,\n"
+"#endif\n"
+"#ifdef USEVIEWTINT\n"
+"uniform float4 ViewTintColor,\n"
+"#endif\n"
+"uniform float4 UserVec1,\n"
+"uniform float4 UserVec2,\n"
+"uniform float4 UserVec3,\n"
+"uniform float4 UserVec4,\n"
+"uniform float ClientTime,\n"
+"uniform float2 PixelSize,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      gl_FragColor = tex2D(Texture_First, TexCoord1);\n"
+"#ifdef USEBLOOM\n"
+"      gl_FragColor += tex2D(Texture_Second, TexCoord2);\n"
+"#endif\n"
+"#ifdef USEVIEWTINT\n"
+"      gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
+"#endif\n"
+"\n"
+"#ifdef USEPOSTPROCESSING\n"
+"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
+"// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
+"      gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.987688, -0.156434)) * UserVec1.y;\n"
+"      gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.156434, -0.891007)) * UserVec1.y;\n"
+"      gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.891007, -0.453990)) * UserVec1.y;\n"
+"      gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.707107,  0.707107)) * UserVec1.y;\n"
+"      gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.453990,  0.891007)) * UserVec1.y;\n"
+"      gl_FragColor /= (1 + 5 * UserVec1.y);\n"
+"#endif\n"
 "\n"
+"#ifdef USESATURATION\n"
+"      //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
+"      float y = dot(gl_FragColor.rgb, float3(0.299, 0.587, 0.114));\n"
+"      //gl_FragColor = float3(y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
+"      gl_FragColor.rgb = mix(float3(y), gl_FragColor.rgb, Saturation);\n"
+"#endif\n"
+"\n"
+"#ifdef USEGAMMARAMPS\n"
+"      gl_FragColor.r = tex2D(Texture_GammaRamps, float2(gl_FragColor.r, 0)).r;\n"
+"      gl_FragColor.g = tex2D(Texture_GammaRamps, float2(gl_FragColor.g, 0)).g;\n"
+"      gl_FragColor.b = tex2D(Texture_GammaRamps, float2(gl_FragColor.b, 0)).b;\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_POSTPROCESS\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_GENERIC\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_Color : COLOR0,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float2 TexCoord1 : TEXCOORD0,\n"
+"out float2 TexCoord2 : TEXCOORD1\n"
+")\n"
+"{\n"
+"      gl_FrontColor = gl_Color;\n"
+"#ifdef USEDIFFUSE\n"
+"      TexCoord1 = gl_MultiTexCoord0.xy;\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"      TexCoord2 = gl_MultiTexCoord1.xy;\n"
+"#endif\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float4 gl_FrontColor : COLOR,\n"
+"float2 TexCoord1 : TEXCOORD0,\n"
+"float2 TexCoord2 : TEXCOORD1,\n"
+"#ifdef USEDIFFUSE\n"
+"uniform sampler2D Texture_First,\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"uniform sampler2D Texture_Second,\n"
+"#endif\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      gl_FragColor = gl_FrontColor;\n"
+"#ifdef USEDIFFUSE\n"
+"      gl_FragColor *= tex2D(Texture_First, TexCoord1);\n"
+"#endif\n"
+"\n"
+"#ifdef USESPECULAR\n"
+"      float4 tex2 = tex2D(Texture_Second, TexCoord2);\n"
+"# ifdef USECOLORMAPPING\n"
+"      gl_FragColor *= tex2;\n"
+"# endif\n"
+"# ifdef USEGLOW\n"
+"      gl_FragColor += tex2;\n"
+"# endif\n"
+"# ifdef USEVERTEXTEXTUREBLEND\n"
+"      gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
+"# endif\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_GENERIC\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_BLOOMBLUR\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0\n"
+")\n"
+"{\n"
+"      TexCoord = gl_MultiTexCoord0.xy;\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"uniform sampler2D Texture_First,\n"
+"uniform float4 BloomBlur_Parameters,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      int i;\n"
+"      float2 tc = TexCoord;\n"
+"      float3 color = tex2D(Texture_First, tc).rgb;\n"
+"      tc += BloomBlur_Parameters.xy;\n"
+"      for (i = 1;i < SAMPLES;i++)\n"
+"      {\n"
+"              color += tex2D(Texture_First, tc).rgb;\n"
+"              tc += BloomBlur_Parameters.xy;\n"
+"      }\n"
+"      gl_FragColor = float4(color * BloomBlur_Parameters.z + float3(BloomBlur_Parameters.w), 1);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_BLOOMBLUR\n"
+"#ifdef MODE_REFRACTION\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"uniform mat4 TexMatrix,\n"
+"uniform float3 EyePosition,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0,\n"
+"out float3 EyeVector : TEXCOORD1,\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
+")\n"
+"{\n"
+"      TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"      ModelViewProjectionPosition = gl_Position;\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD1,\n"
+"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Refraction,\n"
+"uniform sampler2D Texture_Reflection,\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform float4 RefractColor,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      float2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
+"      //float2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
+"      float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
+"      float2 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
+"      // FIXME temporary hack to detect the case that the reflection\n"
+"      // gets blackened at edges due to leaving the area that contains actual\n"
+"      // content.\n"
+"      // Remove this 'ack once we have a better way to stop this thing from\n"
+"      // 'appening.\n"
+"      float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+"      ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
+"      gl_FragColor = tex2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_REFRACTION\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_WATER\n"
+"#ifdef VERTEX_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"uniform mat4 TexMatrix,\n"
+"uniform float3 EyePosition,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0,\n"
+"out float3 EyeVector : TEXCOORD1,\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
+")\n"
+"{\n"
+"      TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
+"      float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"      ModelViewProjectionPosition = gl_Position;\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD1,\n"
+"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Refraction,\n"
+"uniform sampler2D Texture_Reflection,\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform float4 RefractColor,\n"
+"uniform float4 ReflectColor,\n"
+"uniform float ReflectFactor,\n"
+"uniform float ReflectOffset,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
+"      //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+"      float4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+"      float4 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xyxy * DistortScaleRefractReflect;\n"
+"      // FIXME temporary hack to detect the case that the reflection\n"
+"      // gets blackened at edges due to leaving the area that contains actual\n"
+"      // content.\n"
+"      // Remove this 'ack once we have a better way to stop this thing from\n"
+"      // 'appening.\n"
+"      float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, -0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+"      ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
+"      f       = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, -0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+"      ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
+"      float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
+"      gl_FragColor = mix(tex2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, tex2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_WATER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
+"\n"
+"// fragment shader specific:\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"#ifdef USEFOG\n"
+"float FogVertex(float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler2D Texture_FogMask)\n"
+"{\n"
+"      float fogfrac;\n"
+"#ifdef USEFOGOUTSIDE\n"
+"      fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
+"#else\n"
+"      fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
+"#endif\n"
+"      return float(tex2D(Texture_FogMask, half2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef USEOFFSETMAPPING\n"
+"float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler2D Texture_Normal)\n"
+"{\n"
+"#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
+"      // 14 sample relief mapping: linear search and then binary search\n"
+"      // this basically steps forward a small amount repeatedly until it finds\n"
+"      // itself inside solid, then jitters forward and back using decreasing\n"
+"      // amounts to find the impact\n"
+"      //float3 OffsetVector = float3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1), -1);\n"
+"      //float3 OffsetVector = float3(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1), -1);\n"
+"      float3 OffsetVector = float3(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1), -1);\n"
+"      float3 RT = float3(TexCoord, 1);\n"
+"      OffsetVector *= 0.1;\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector *  step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+"      RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z)          - 0.5);\n"
+"      RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.5    - 0.25);\n"
+"      RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.25   - 0.125);\n"
+"      RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.125  - 0.0625);\n"
+"      RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
+"      return RT.xy;\n"
+"#else\n"
+"      // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
+"      // this basically moves forward the full distance, and then backs up based\n"
+"      // on height of samples\n"
+"      //float2 OffsetVector = float2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1));\n"
+"      //float2 OffsetVector = float2(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1));\n"
+"      float2 OffsetVector = float2(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1));\n"
+"      TexCoord += OffsetVector;\n"
+"      OffsetVector *= 0.333;\n"
+"      TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+"      TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+"      TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+"      return TexCoord;\n"
+"#endif\n"
+"}\n"
+"#endif // USEOFFSETMAPPING\n"
+"\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"# ifndef USESHADOWMAPVSDCT\n"
+"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
+"{\n"
+"      float3 adir = abs(dir);\n"
+"      float2 tc;\n"
+"      float2 offset;\n"
+"      float ma;\n"
+"      if (adir.x > adir.y)\n"
+"      {\n"
+"              if (adir.x > adir.z) // X\n"
+"              {\n"
+"                      ma = adir.x;\n"
+"                      tc = dir.zy;\n"
+"                      offset = float2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
+"              }\n"
+"              else // Z\n"
+"              {\n"
+"                      ma = adir.z;\n"
+"                      tc = dir.xy;\n"
+"                      offset = float2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
+"              }\n"
+"      }\n"
+"      else\n"
+"      {\n"
+"              if (adir.y > adir.z) // Y\n"
+"              {\n"
+"                      ma = adir.y;\n"
+"                      tc = dir.xz;\n"
+"                      offset = float2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
+"              }\n"
+"              else // Z\n"
+"              {\n"
+"                      ma = adir.z;\n"
+"                      tc = dir.xy;\n"
+"                      offset = float2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
+"              }\n"
+"      }\n"
+"\n"
+"      float3 stc = float3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"      stc.xy += offset * ShadowMap_Parameters.y;\n"
+"      stc.z += ShadowMap_Parameters.z;\n"
+"      return stc;\n"
+"}\n"
+"# else\n"
+"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
+"{\n"
+"      float3 adir = abs(dir);\n"
+"      float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
+"      float ma = max(max(adir.x, adir.y), adir.z);\n"
+"      float3 stc = float3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"      stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
+"      stc.z += ShadowMap_Parameters.z;\n"
+"      return stc;\n"
+"}\n"
+"# endif\n"
+"#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"float4 GetShadowMapTCCube(float3 dir, float4 ShadowMap_Parameters)\n"
+"{\n"
+"    float3 adir = abs(dir);\n"
+"    return float4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
+"}\n"
+"#endif\n"
+"\n"
+"# ifdef USESHADOWMAPRECT\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
+"#else\n"
+"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters)\n"
+"#endif\n"
+"{\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"      float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
+"#else\n"
+"      float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
+"#endif\n"
+"      float f;\n"
+"#  ifdef USESHADOWSAMPLER\n"
+"\n"
+"#    ifdef USESHADOWMAPPCF\n"
+"#      define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + float3(x, y, 0.0)).r\n"
+"    f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"#    else\n"
+"    f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
+"#    endif\n"
+"\n"
+"#  else\n"
+"\n"
+"#    ifdef USESHADOWMAPPCF\n"
+"#      if USESHADOWMAPPCF > 1\n"
+"#        define texval(x, y) texRECT(Texture_ShadowMapRect, center + float2(x, y)).r\n"
+"    float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"    float4 row1 = step(shadowmaptc.z, float4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+"    float4 row2 = step(shadowmaptc.z, float4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
+"    float4 row3 = step(shadowmaptc.z, float4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
+"    float4 row4 = step(shadowmaptc.z, float4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
+"    float4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+"    f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"#      else\n"
+"#        define texval(x, y) texRECT(Texture_ShadowMapRect, shadowmaptc.xy + float2(x, y)).r\n"
+"    float2 offset = fract(shadowmaptc.xy);\n"
+"    float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+"    float3 row2 = step(shadowmaptc.z, float3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
+"    float3 row3 = step(shadowmaptc.z, float3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
+"    float3 cols = row2 + mix(row1, row3, offset.y);\n"
+"    f = dot(mix(cols.xy, cols.yz, offset.x), float2(0.25));\n"
+"#      endif\n"
+"#    else\n"
+"    f = step(shadowmaptc.z, texRECT(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
+"#    endif\n"
+"\n"
+"#  endif\n"
+"      return f;\n"
+"}\n"
+"# endif\n"
+"\n"
+"# ifdef USESHADOWMAP2D\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale, samplerCUBE Texture_CubeProjection)\n"
+"#else\n"
+"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale)\n"
+"#endif\n"
+"{\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"      float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
+"#else\n"
+"      float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
+"#endif\n"
+"    float f;\n"
+"\n"
+"#  ifdef USESHADOWSAMPLER\n"
+"#    ifdef USESHADOWMAPPCF\n"
+"#      define texval(x, y) shadow2D(Texture_ShadowMap2D, float3(center + float2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r  \n"
+"    float2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
+"    f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"#    else\n"
+"    f = shadow2D(Texture_ShadowMap2D, float3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
+"#    endif\n"
+"#  else\n"
+"#    ifdef USESHADOWMAPPCF\n"
+"#     if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
+"#      ifdef GL_ARB_texture_gather\n"
+"#        define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n"
+"#      else\n"
+"#        define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x,y)*ShadowMap_TextureScale)\n"
+"#      endif\n"
+"    float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"    center *= ShadowMap_TextureScale;\n"
+"    float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
+"    float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
+"    float4 group3 = step(shadowmaptc.z, texval(-1.0,  1.0));\n"
+"    float4 group4 = step(shadowmaptc.z, texval( 1.0,  1.0));\n"
+"    float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n"
+"                mix(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n"
+"    f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"#     else\n"
+"#      ifdef GL_EXT_gpu_shader4\n"
+"#        define texval(x, y) tex2DOffset(Texture_ShadowMap2D, center, ifloat2(x, y)).r\n"
+"#      else\n"
+"#        define texval(x, y) tex2D(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale).r  \n"
+"#      endif\n"
+"#      if USESHADOWMAPPCF > 1\n"
+"    float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+"    center *= ShadowMap_TextureScale;\n"
+"    float4 row1 = step(shadowmaptc.z, float4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+"    float4 row2 = step(shadowmaptc.z, float4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
+"    float4 row3 = step(shadowmaptc.z, float4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
+"    float4 row4 = step(shadowmaptc.z, float4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
+"    float4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+"    f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"#      else\n"
+"    float2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
+"    float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+"    float3 row2 = step(shadowmaptc.z, float3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
+"    float3 row3 = step(shadowmaptc.z, float3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
+"    float3 cols = row2 + mix(row1, row3, offset.y);\n"
+"    f = dot(mix(cols.xy, cols.yz, offset.x), float2(0.25));\n"
+"#      endif\n"
+"#     endif\n"
+"#    else\n"
+"    f = step(shadowmaptc.z, tex2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
+"#    endif\n"
+"#  endif\n"
+"    return f;\n"
+"}\n"
+"# endif\n"
+"\n"
+"# ifdef USESHADOWMAPCUBE\n"
+"float ShadowMapCompare(float3 dir, samplerCUBE Texture_ShadowMapCube, float4 ShadowMap_Parameters)\n"
+"{\n"
+"    // apply depth texture cubemap as light filter\n"
+"    float4 shadowmaptc = GetShadowMapTCCube(dir, ShadowMap_Parameters);\n"
+"    float f;\n"
+"#  ifdef USESHADOWSAMPLER\n"
+"    f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
+"#  else\n"
+"    f = step(shadowmaptc.w, texCUBE(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
+"#  endif\n"
+"    return f;\n"
+"}\n"
+"# endif\n"
+"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_DEFERREDGEOMETRY\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"float4 gl_Color : COLOR0,\n"
+"#endif\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
+"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
+"uniform mat4 TexMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix,\n"
+"#endif\n"
+"uniform mat4 ModelViewMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float4 TexCoordBoth : TEXCOORD0,\n"
+"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"out float3 VectorR : TEXCOORD7 // direction of R texcoord (surface normal)\n"
+")\n"
+"{\n"
+"      TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      gl_FrontColor = gl_Color;\n"
+"      TexCoordBoth.zw = float2(Backgroundmul(TexMatrix, gl_MultiTexCoord0));\n"
+"#endif\n"
+"\n"
+"      // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEOFFSETMAPPING\n"
+"      float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"      VectorS = mul(ModelViewMatrix, float4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
+"      VectorT = mul(ModelViewMatrix, float4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
+"      VectorR = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float4 TexCoordBoth : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD2,\n"
+"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"uniform sampler2D Texture_Normal,\n"
+"#ifdef USEALPHAKILL\n"
+"uniform sampler2D Texture_Color,\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform sampler2D Texture_SecondaryNormal,\n"
+"#endif\n"
+"#ifdef USEOFFSETMAPPING\n"
+"uniform float OffsetMapping_Scale,\n"
+"#endif\n"
+"uniform half SpecularPower,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      float2 TexCoord = TexCoordBoth.xy;\n"
+"#ifdef USEOFFSETMAPPING\n"
+"      // apply offsetmapping\n"
+"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
+"#define TexCoord TexCoordOffset\n"
+"#endif\n"
+"\n"
+"#ifdef USEALPHAKILL\n"
+"      if (tex2D(Texture_Color, TexCoord).a < 0.5)\n"
+"              discard;\n"
+"#endif\n"
+"\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      float alpha = tex2D(Texture_Color, TexCoord).a;\n"
+"      float terrainblend = clamp(float(gl_FrontColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
+"      //float terrainblend = min(float(gl_FrontColor.a) * alpha * 2.0, float(1.0));\n"
+"      //float terrainblend = float(gl_FrontColor.a) * alpha > 0.5;\n"
+"#endif\n"
+"\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      float3 surfacenormal = mix(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend) - float3(0.5, 0.5, 0.5);\n"
+"#else\n"
+"      float3 surfacenormal = float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5, 0.5, 0.5);\n"
+"#endif\n"
+"\n"
+"      gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), 1);\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"#else // !MODE_DEFERREDGEOMETRY\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"uniform mat4 ModelViewMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 ModelViewPosition : TEXCOORD0\n"
+")\n"
+"{\n"
+"      ModelViewPosition = mul(ModelViewMatrix, gl_Vertex);\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 Pixel : WPOS,\n"
+"float4 ModelViewPosition : TEXCOORD0,\n"
+"uniform mat4 ViewToLight,\n"
+"uniform float2 ScreenToDepth, // ScreenToDepth = float2(Far / (Far - Near), Far * Near / (Near - Far));\n"
+"uniform float3 LightPosition,\n"
+"uniform half3 DeferredColor_Ambient,\n"
+"uniform half3 DeferredColor_Diffuse,\n"
+"#ifdef USESPECULAR\n"
+"uniform half3 DeferredColor_Specular,\n"
+"uniform half SpecularPower,\n"
+"#endif\n"
+"uniform sampler2D Texture_Attenuation,\n"
+"uniform samplerRECT Texture_ScreenDepth,\n"
+"uniform samplerRECT Texture_ScreenNormalMap,\n"
+"\n"
+"#ifdef USESHADOWMAPRECT\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
+"# else\n"
+"uniform samplerRECT Texture_ShadowMapRect,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform sampler2DShadow Texture_ShadowMap2D,\n"
+"# else\n"
+"uniform sampler2D Texture_ShadowMap2D,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"uniform samplerCUBE Texture_CubeProjection,\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
+"# else\n"
+"uniform samplerCUBE Texture_ShadowMapCube,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"uniform float2 ShadowMap_TextureScale,\n"
+"uniform float4 ShadowMap_Parameters,\n"
+"#endif\n"
+"\n"
+"out float4 gl_FragData0 : COLOR0,\n"
+"out float4 gl_FragData1 : COLOR1\n"
+")\n"
+"{\n"
+"      // calculate viewspace pixel position\n"
+"      float3 position;\n"
+"      position.z = ScreenToDepth.y / (texRECT(Texture_ScreenDepth, Pixel).r + ScreenToDepth.x);\n"
+"      position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
+"      // decode viewspace pixel normal\n"
+"      half4 normalmap = texRECT(Texture_ScreenNormalMap, Pixel);\n"
+"      half3 surfacenormal = normalize(normalmap.rgb - half3(0.5,0.5,0.5));\n"
+"      // surfacenormal = pixel normal in viewspace\n"
+"      // LightVector = pixel to light in viewspace\n"
+"      // CubeVector = position in lightspace\n"
+"      // eyevector = pixel to view in viewspace\n"
+"      float3 CubeVector = float3(mul(ViewToLight, float4(position,1)));\n"
+"      half fade = half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
+"#ifdef USEDIFFUSE\n"
+"      // calculate diffuse shading\n"
+"      half3 lightnormal = half3(normalize(LightPosition - position));\n"
+"      half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"      // calculate directional shading\n"
+"      float3 eyevector = position * -1.0;\n"
+"#  ifdef USEEXACTSPECULARMATH\n"
+"      half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n"
+"#  else\n"
+"      half3 specularnormal = normalize(lightnormal + half3(normalize(eyevector)));\n"
+"      half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"#  endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAP2D) || defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE)\n"
+"      fade *= ShadowMapCompare(CubeVector,\n"
+"# if defined(USESHADOWMAP2D)\n"
+"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
+"# endif\n"
+"# if defined(USESHADOWMAPRECT)\n"
+"Texture_ShadowMapRect, ShadowMap_Parameters\n"
+"# endif\n"
+"# if defined(USESHADOWMAPCUBE)\n"
+"Texture_ShadowMapCube, ShadowMap_Parameters\n"
+"# endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+", Texture_CubeProjection\n"
+"#endif\n"
+"      );\n"
+"#endif\n"
+"\n"
+"#ifdef USEDIFFUSE\n"
+"      gl_FragData0 = float4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
+"#else\n"
+"      gl_FragData0 = float4(DeferredColor_Ambient * fade, 1.0);\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"      gl_FragData1 = float4(DeferredColor_Specular * (specular * fade), 1.0);\n"
+"#else\n"
+"      gl_FragData1 = float4(0.0, 0.0, 0.0, 1.0);\n"
+"#endif\n"
+"\n"
+"# ifdef USECUBEFILTER\n"
+"      float3 cubecolor = texCUBE(Texture_Cube, CubeVector).rgb;\n"
+"      gl_FragData0 *= cubecolor;\n"
+"      gl_FragData1 *= cubecolor;\n"
+"# endif\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"#else // !MODE_DEFERREDLIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"#if defined(USEVERTEXTEXTUREBLEND) || defined(MODE_VERTEXCOLOR)\n"
+"float4 gl_Color : COLOR0,\n"
+"#endif\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
+"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
+"float4 gl_MultiTexCoord4 : TEXCOORD4,\n"
+"\n"
+"uniform float3 EyePosition,\n"
+"uniform mat4 TexMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform mat4 ModelToLight,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform float3 LightPosition,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"uniform float3 LightDir,\n"
+"#endif\n"
+"uniform float4 FogPlane,\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"uniform float3 LightPosition,\n"
+"#endif\n"
+"\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float4 TexCoordBoth : TEXCOORD0,\n"
+"#ifdef USELIGHTMAP\n"
+"out float2 TexCoordLightmap : TEXCOORD1,\n"
+"#endif\n"
+"#ifdef USEEYEVECTOR\n"
+"out float3 EyeVector : TEXCOORD2,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"out float3 LightVector : TEXCOORD5,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"out float3 CubeVector : TEXCOORD3,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
+"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"#endif\n"
+"out float4 gl_Position : POSITION\n"
+")\n"
+"{\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
+"      gl_FrontColor = gl_Color;\n"
+"#endif\n"
+"      // copy the surface texcoord\n"
+"      TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      TexCoordBoth.zw = mul(BackgroundTexMatrix, gl_MultiTexCoord0).xy;\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+"      TexCoordLightmap = float2(gl_MultiTexCoord4);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"      // transform vertex position into light attenuation/cubemap space\n"
+"      // (-1 to +1 across the light box)\n"
+"      CubeVector = float3(mul(ModelToLight, gl_Vertex));\n"
+"\n"
+"# ifdef USEDIFFUSE\n"
+"      // transform unnormalized light direction into tangent space\n"
+"      // (we use unnormalized to ensure that it interpolates correctly and then\n"
+"      //  normalize it per pixel)\n"
+"      float3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
+"      LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
+"      LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
+"      LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
+"      LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
+"      LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
+"      LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"      // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEEYEVECTOR\n"
+"      float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+"      EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"      VectorS = gl_MultiTexCoord1.xyz;\n"
+"      VectorT = gl_MultiTexCoord2.xyz;\n"
+"      VectorR = gl_MultiTexCoord3.xyz;\n"
+"#endif\n"
+"\n"
+"      // transform vertex to camera space, using ftransform to match non-VS rendering\n"
+"      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"\n"
+"#ifdef USEREFLECTION\n"
+"      ModelViewProjectionPosition = gl_Position;\n"
+"#endif\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"float2 Pixel : WPOS,\n"
+"#endif\n"
+"float4 gl_FrontColor : COLOR,\n"
+"float4 TexCoordBoth : TEXCOORD0,\n"
+"#ifdef USELIGHTMAP\n"
+"float2 TexCoordLightmap : TEXCOORD1,\n"
+"#endif\n"
+"#ifdef USEEYEVECTOR\n"
+"float3 EyeVector : TEXCOORD2,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"float4 ModelViewProjectionPosition : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"float3 LightVector : TEXCOORD5,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"float3 CubeVector : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"float4 ModelViewPosition : TEXCOORD0,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
+"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"#endif\n"
+"\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Color,\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"uniform sampler2D Texture_Gloss,\n"
+"#endif\n"
+"#ifdef USEGLOW\n"
+"uniform sampler2D Texture_Glow,\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform sampler2D Texture_SecondaryNormal,\n"
+"uniform sampler2D Texture_SecondaryColor,\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"uniform sampler2D Texture_SecondaryGloss,\n"
+"#endif\n"
+"#ifdef USEGLOW\n"
+"uniform sampler2D Texture_SecondaryGlow,\n"
+"#endif\n"
+"#endif\n"
+"#ifdef USECOLORMAPPING\n"
+"uniform sampler2D Texture_Pants,\n"
+"uniform sampler2D Texture_Shirt,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"uniform sampler2D Texture_FogMask,\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+"uniform sampler2D Texture_Lightmap,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"uniform sampler2D Texture_Deluxemap,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"uniform sampler2D Texture_Reflection,\n"
+"#endif\n"
+"\n"
+"//#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"uniform samplerRECT Texture_ScreenDepth,\n"
+"uniform samplerRECT Texture_ScreenNormalMap,\n"
+"//#endif\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"uniform samplerRECT Texture_ScreenDiffuse,\n"
+"uniform samplerRECT Texture_ScreenSpecular,\n"
+"#endif\n"
+"\n"
+"#ifdef USECOLORMAPPING\n"
+"uniform half3 Color_Pants,\n"
+"uniform half3 Color_Shirt,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"uniform float3 FogColor,\n"
+"uniform float FogRangeRecip,\n"
+"uniform float FogPlaneViewDist,\n"
+"uniform float FogHeightFade,\n"
+"#endif\n"
+"\n"
+"#ifdef USEOFFSETMAPPING\n"
+"uniform float OffsetMapping_Scale,\n"
+"#endif\n"
+"\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"uniform half3 DeferredMod_Diffuse,\n"
+"uniform half3 DeferredMod_Specular,\n"
+"#endif\n"
+"uniform half3 Color_Ambient,\n"
+"uniform half3 Color_Diffuse,\n"
+"uniform half3 Color_Specular,\n"
+"uniform half SpecularPower,\n"
+"#ifdef USEGLOW\n"
+"uniform half3 Color_Glow,\n"
+"#endif\n"
+"uniform half Alpha,\n"
+"#ifdef USEREFLECTION\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform half4 ReflectColor,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"uniform half3 LightColor,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform half3 LightColor,\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"uniform sampler2D Texture_Attenuation,\n"
+"uniform samplerCUBE Texture_Cube,\n"
+"\n"
+"#ifdef USESHADOWMAPRECT\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
+"# else\n"
+"uniform samplerRECT Texture_ShadowMapRect,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform sampler2DShadow Texture_ShadowMap2D,\n"
+"# else\n"
+"uniform sampler2D Texture_ShadowMap2D,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"uniform samplerCUBE Texture_CubeProjection,\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
+"# else\n"
+"uniform samplerCUBE Texture_ShadowMapCube,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"uniform float2 ShadowMap_TextureScale,\n"
+"uniform float4 ShadowMap_Parameters,\n"
+"#endif\n"
+"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+"      float2 TexCoord = TexCoordBoth.xy;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      float2 TexCoord2 = TexCoordBoth.zw;\n"
+"#endif\n"
+"#ifdef USEOFFSETMAPPING\n"
+"      // apply offsetmapping\n"
+"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
+"#define TexCoord TexCoordOffset\n"
+"#endif\n"
+"\n"
+"      // combine the diffuse textures (base, pants, shirt)\n"
+"      half4 color = half4(tex2D(Texture_Color, TexCoord));\n"
+"#ifdef USEALPHAKILL\n"
+"      if (color.a < 0.5)\n"
+"              discard;\n"
+"#endif\n"
+"      color.a *= Alpha;\n"
+"#ifdef USECOLORMAPPING\n"
+"      color.rgb += half3(tex2D(Texture_Pants, TexCoord)) * Color_Pants + half3(tex2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      float terrainblend = clamp(half(gl_FrontColor.a) * color.a * 2.0 - 0.5, half(0.0), half(1.0));\n"
+"      //half terrainblend = min(half(gl_FrontColor.a) * color.a * 2.0, half(1.0));\n"
+"      //half terrainblend = half(gl_FrontColor.a) * color.a > 0.5;\n"
+"      color.rgb = half3(mix(float3(tex2D(Texture_SecondaryColor, TexCoord2)), float3(color.rgb), terrainblend));\n"
+"      color.a = 1.0;\n"
+"      //color = mix(half4(1, 0, 0, 1), color, terrainblend);\n"
+"#endif\n"
+"\n"
+"      // get the surface normal\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      half3 surfacenormal = normalize(half3(mix(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend)) - half3(0.5, 0.5, 0.5));\n"
+"#else\n"
+"      half3 surfacenormal = normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5, 0.5, 0.5));\n"
+"#endif\n"
+"\n"
+"      // get the material colors\n"
+"      half3 diffusetex = color.rgb;\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"# ifdef USEVERTEXTEXTUREBLEND\n"
+"      half3 glosstex = half3(mix(float3(tex2D(Texture_SecondaryGloss, TexCoord2)), float3(tex2D(Texture_Gloss, TexCoord)), terrainblend));\n"
+"# else\n"
+"      half3 glosstex = half3(tex2D(Texture_Gloss, TexCoord));\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"      // light source\n"
+"      half3 lightnormal = half3(normalize(LightVector));\n"
+"      half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"      color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
+"#ifdef USESPECULAR\n"
+"#ifdef USEEXACTSPECULARMATH\n"
+"      half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"#else\n"
+"      half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
+"      half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"#endif\n"
+"      color.rgb += glosstex * (specular * Color_Specular);\n"
+"#endif\n"
+"      color.rgb *= LightColor;\n"
+"      color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
+"      color.rgb *= ShadowMapCompare(CubeVector,\n"
+"# if defined(USESHADOWMAP2D)\n"
+"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
+"# endif\n"
+"# if defined(USESHADOWMAPRECT)\n"
+"Texture_ShadowMapRect, ShadowMap_Parameters\n"
+"# endif\n"
+"# if defined(USESHADOWMAPCUBE)\n"
+"Texture_ShadowMapCube, ShadowMap_Parameters\n"
+"# endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+", Texture_CubeProjection\n"
+"#endif\n"
+"      );\n"
+"\n"
+"#endif\n"
+"# ifdef USECUBEFILTER\n"
+"      color.rgb *= half3(texCUBE(Texture_Cube, CubeVector));\n"
+"# endif\n"
+"#endif // MODE_LIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"#define SHADING\n"
+"      half3 lightnormal = half3(normalize(LightVector));\n"
+"#define lightcolor LightColor\n"
+"#endif // MODE_LIGHTDIRECTION\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"#define SHADING\n"
+"      // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
+"      half3 lightnormal_modelspace = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
+"      half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
+"      // convert modelspace light vector to tangentspace\n"
+"      half3 lightnormal;\n"
+"      lightnormal.x = dot(lightnormal_modelspace, half3(VectorS));\n"
+"      lightnormal.y = dot(lightnormal_modelspace, half3(VectorT));\n"
+"      lightnormal.z = dot(lightnormal_modelspace, half3(VectorR));\n"
+"      // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
+"      // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
+"      // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
+"      // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
+"      // to map the luxels to coordinates on the draw surfaces), which also causes\n"
+"      // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
+"      // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
+"      // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
+"      // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
+"      lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
+"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
+"#define SHADING\n"
+"      // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
+"      half3 lightnormal = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
+"      half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
+"#endif\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTMAP\n"
+"      color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
+"#endif // MODE_LIGHTMAP\n"
+"#ifdef MODE_VERTEXCOLOR\n"
+"      color.rgb = diffusetex * (Color_Ambient + half3(gl_FrontColor.rgb) * Color_Diffuse);\n"
+"#endif // MODE_VERTEXCOLOR\n"
+"#ifdef MODE_FLATCOLOR\n"
+"      color.rgb = diffusetex * Color_Ambient;\n"
+"#endif // MODE_FLATCOLOR\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef SHADING\n"
+"# ifdef USEDIFFUSE\n"
+"      half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"#  ifdef USESPECULAR\n"
+"#   ifdef USEEXACTSPECULARMATH\n"
+"      half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"#   else\n"
+"      half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
+"      half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"#   endif\n"
+"      color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n"
+"#  else\n"
+"      color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
+"#  endif\n"
+"# else\n"
+"      color.rgb = diffusetex * Color_Ambient;\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"      color.rgb += diffusetex * half3(texRECT(Texture_ScreenDiffuse, Pixel)) * DeferredMod_Diffuse;\n"
+"      color.rgb += glosstex * half3(texRECT(Texture_ScreenSpecular, Pixel)) * DeferredMod_Specular;\n"
+"      color.rgb = half3(texRECT(Texture_ScreenDepth, Pixel));\n"
+"#endif\n"
+"\n"
+"#ifdef USEGLOW\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"      color.rgb += mix(half3(tex2D(Texture_SecondaryGlow, TexCoord2)), half3(tex2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
+"#else\n"
+"      color.rgb += half3(tex2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
+"#endif\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"      color.rgb *= half(FogVertex());\n"
+"#else\n"
+"      color.rgb = mix(FogColor, float3(color.rgb), FogVertex(EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask));\n"
+"#endif\n"
+"#endif\n"
+"\n"
+"      // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
+"#ifdef USEREFLECTION\n"
+"      float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
+"      //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+"      float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
+"      float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
+"      // FIXME temporary hack to detect the case that the reflection\n"
+"      // gets blackened at edges due to leaving the area that contains actual\n"
+"      // content.\n"
+"      // Remove this 'ack once we have a better way to stop this thing from\n"
+"      // 'appening.\n"
+"      float f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+"      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+"      ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
+"      color.rgb = mix(color.rgb, half3(tex2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
+"#endif\n"
+"\n"
+"      gl_FragColor = float4(color);\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
+"#endif // !MODE_DEFERREDGEOMETRY\n"
 "#endif // !MODE_WATER\n"
 "#endif // !MODE_REFRACTION\n"
 "#endif // !MODE_BLOOMBLUR\n"
@@ -1619,7 +3094,7 @@ static const char *builtinshaderstring =
 "#endif // !MODE_DEPTH_OR_SHADOW\n"
 ;
 
-const char *builtincgshaderstring = "";
+//=======================================================================================================================================================
 
 typedef struct shaderpermutationinfo_s
 {