]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
r_fakelight: 1 = use "fake" lighting (falloff-less light source at eye origin) if...
[xonotic/darkplaces.git] / gl_rmain.c
index 52e68fac0e005d4e141aaba5753fc74d4e565fca..52572fdfda690f234efcbaa0fc332b17b6314883 100644 (file)
@@ -92,6 +92,11 @@ cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "
 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
+
+cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
+cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
+#define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
+
 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
@@ -583,14 +588,10 @@ static const char *builtinshaderstring =
 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
 "#define USELIGHTMAP\n"
 "#endif\n"
-"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\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"
@@ -604,10 +605,6 @@ static const char *builtinshaderstring =
 "# 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"
@@ -895,7 +892,7 @@ static const char *builtinshaderstring =
 "      f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
 "      f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
 "      ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-"      gl_FragColor = texture2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
+"      gl_FragColor = vec4(texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * RefractColor;\n"
 "}\n"
 "#endif\n"
 "#else // !MODE_REFRACTION\n"
@@ -959,7 +956,7 @@ static const char *builtinshaderstring =
 "      f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-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(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
+"      gl_FragColor = mix(vec4(texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
 "}\n"
 "#endif\n"
 "#else // !MODE_WATER\n"
@@ -1152,14 +1149,6 @@ static const char *builtinshaderstring =
 "\n"
 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
 "\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform sampler2DRectShadow Texture_ShadowMapRect;\n"
-"# else\n"
-"uniform sampler2DRect Texture_ShadowMapRect;\n"
-"# endif\n"
-"#endif\n"
-"\n"
 "#ifdef USESHADOWMAP2D\n"
 "# ifdef USESHADOWSAMPLER\n"
 "uniform sampler2DShadow Texture_ShadowMap2D;\n"
@@ -1172,20 +1161,12 @@ static const char *builtinshaderstring =
 "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"
+"#if defined(USESHADOWMAP2D)\n"
 "uniform vec2 ShadowMap_TextureScale;\n"
 "uniform vec4 ShadowMap_Parameters;\n"
 "#endif\n"
 "\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "# ifdef USESHADOWMAPORTHO\n"
 "#  define GetShadowMapTC2D(dir) (min(dir, ShadowMap_Parameters.xyz))\n"
 "# else\n"
@@ -1210,63 +1191,7 @@ static const char *builtinshaderstring =
 "}\n"
 "#  endif\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.w + ShadowMap_Parameters.y / max(max(adir.x, adir.y), adir.z));\n"
-"}\n"
-"#endif\n"
-"\n"
-"# ifdef USESHADOWMAPRECT\n"
-"float ShadowMapCompare(vec3 dir)\n"
-"{\n"
-"      vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
-"      float f;\n"
-"#  ifdef USESHADOWSAMPLER\n"
-"\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"
-"#    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) 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"
-"#      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"
-"#      endif\n"
-"#    else\n"
-"      f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
-"#    endif\n"
-"\n"
-"#  endif\n"
-"#  ifdef USESHADOWMAPORTHO\n"
-"      return mix(ShadowMap_Parameters.w, 1.0, f);\n"
-"#  else\n"
-"      return f;\n"
-"#  endif\n"
-"}\n"
-"# endif\n"
+"#endif // defined(USESHADOWMAP2D)\n"
 "\n"
 "# ifdef USESHADOWMAP2D\n"
 "float ShadowMapCompare(vec3 dir)\n"
@@ -1355,21 +1280,6 @@ static const char *builtinshaderstring =
 "#  endif\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"
-"#  ifdef USESHADOWSAMPLER\n"
-"      f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
-"#  else\n"
-"      f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
-"#  endif\n"
-"      return f;\n"
-"}\n"
-"# endif\n"
 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
 "#endif // FRAGMENT_SHADER\n"
 "\n"
@@ -1496,7 +1406,7 @@ static const char *builtinshaderstring =
 "#  endif\n"
 "#endif\n"
 "\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "      fade *= ShadowMapCompare(CubeVector);\n"
 "#endif\n"
 "\n"
@@ -1710,7 +1620,7 @@ static const char *builtinshaderstring =
 "#endif\n"
 "      color.rgb *= LightColor;\n"
 "      color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "      color.rgb *= ShadowMapCompare(CubeVector);\n"
 "#endif\n"
 "# ifdef USECUBEFILTER\n"
@@ -1759,6 +1669,15 @@ static const char *builtinshaderstring =
 "\n"
 "\n"
 "\n"
+"#ifdef MODE_FAKELIGHT\n"
+"#define SHADING\n"
+"myhalf3 lightnormal = myhalf3(normalize(EyeVector));\n"
+"myhalf3 lightcolor = myhalf3(1.0);\n"
+"#endif // MODE_FAKELIGHT\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_LIGHTMAP\n"
 "      color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
 "#endif // MODE_LIGHTMAP\n"
@@ -1891,7 +1810,7 @@ const char *builtincgshaderstring =
 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
 "#define USELIGHTMAP\n"
 "#endif\n"
-"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
 "#define USEEYEVECTOR\n"
 "#endif\n"
 "\n"
@@ -1928,9 +1847,9 @@ const char *builtincgshaderstring =
 ")\n"
 "{\n"
 "//    float3 temp = float3(Depth,Depth*(65536.0/255.0),Depth*(16777216.0/255.0));\n"
-"      float3 temp = float3(Depth,Depth*256.0,Depth*65536.0);\n"
+"      float4 temp = float4(Depth,Depth*256.0,Depth*65536.0,0.0);\n"
 "      temp.yz -= floor(temp.yz);\n"
-"      gl_FragColor = float4(temp,0);\n"
+"      gl_FragColor = temp;\n"
 "//    gl_FragColor = float4(Depth,0,0,0);\n"
 "}\n"
 "#endif\n"
@@ -2097,9 +2016,13 @@ const char *builtincgshaderstring =
 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
 "float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
 "out float4 gl_Position : POSITION,\n"
-"out float4 gl_FrontColor : COLOR,\n"
+"#ifdef USEDIFFUSE\n"
 "out float2 TexCoord1 : TEXCOORD0,\n"
-"out float2 TexCoord2 : TEXCOORD1\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"out float2 TexCoord2 : TEXCOORD1,\n"
+"#endif\n"
+"out float4 gl_FrontColor : COLOR\n"
 ")\n"
 "{\n"
 "#ifdef HLSL\n"
@@ -2247,7 +2170,7 @@ const char *builtincgshaderstring =
 "      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 = lerp(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-"      gl_FragColor = tex2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
+"      gl_FragColor = float4(tex2D(Texture_Refraction, ScreenTexCoord).rgb, 1) * RefractColor;\n"
 "}\n"
 "#endif\n"
 "#else // !MODE_REFRACTION\n"
@@ -2324,7 +2247,7 @@ const char *builtincgshaderstring =
 "      f      *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, -0.01)).rgb) / 0.05);\n"
 "      ScreenTexCoord.zw = lerp(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 = lerp(tex2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, tex2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
+"      gl_FragColor = lerp(float4(tex2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, float4(tex2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
 "}\n"
 "#endif\n"
 "#else // !MODE_WATER\n"
@@ -2402,7 +2325,7 @@ const char *builtincgshaderstring =
 "#endif // USEOFFSETMAPPING\n"
 "\n"
 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "# ifdef USESHADOWMAPORTHO\n"
 "#  define GetShadowMapTC2D(dir, ShadowMap_Parameters) (min(dir, ShadowMap_Parameters.xyz))\n"
 "# else\n"
@@ -2431,71 +2354,7 @@ const char *builtincgshaderstring =
 "}\n"
 "#  endif\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.w + ShadowMap_Parameters.y / 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,0.25,0.25,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 = frac(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 + lerp(row1, row4, offset.y);\n"
-"      f = dot(lerp(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 = frac(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 + lerp(row1, row3, offset.y);\n"
-"      f = dot(lerp(cols.xy, cols.yz, offset.x), float2(0.25,0.25));\n"
-"#      endif\n"
-"#    else\n"
-"      f = step(shadowmaptc.z, texRECT(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
-"#    endif\n"
-"\n"
-"#  endif\n"
-"#  ifdef USESHADOWMAPORTHO\n"
-"      return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
-"#  else\n"
-"      return f;\n"
-"#  endif\n"
-"}\n"
-"# endif\n"
+"#endif // defined(USESHADOWMAP2D)\n"
 "\n"
 "# ifdef USESHADOWMAP2D\n"
 "#ifdef USESHADOWMAPVSDCT\n"
@@ -2592,21 +2451,6 @@ const char *builtincgshaderstring =
 "#  endif\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) && !defined(USESHADOWMAPORTHO)\n"
 "#endif // FRAGMENT_SHADER\n"
 "\n"
@@ -2635,14 +2479,16 @@ const char *builtincgshaderstring =
 "uniform float3 EyePosition : register(c24),\n"
 "#endif\n"
 "out float4 gl_Position : POSITION,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
 "out float4 gl_FrontColor : COLOR,\n"
+"#endif\n"
 "out float4 TexCoordBoth : TEXCOORD0,\n"
 "#ifdef USEOFFSETMAPPING\n"
 "out float3 EyeVector : TEXCOORD2,\n"
 "#endif\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"
+"out float4 VectorR : TEXCOORD7 // direction of R texcoord (surface normal), Depth value\n"
 ")\n"
 "{\n"
 "      TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
@@ -2665,8 +2511,9 @@ const char *builtincgshaderstring =
 "\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"
+"      VectorR.xyz = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
 "      gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"      VectorR.w = gl_Position.z;\n"
 "}\n"
 "#endif // VERTEX_SHADER\n"
 "\n"
@@ -2677,7 +2524,7 @@ const char *builtincgshaderstring =
 "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"
+"float4 VectorR : TEXCOORD7, // direction of R texcoord (surface normal), Depth value\n"
 "uniform sampler Texture_Normal : register(s0),\n"
 "#ifdef USEALPHAKILL\n"
 "uniform sampler Texture_Color : register(s1),\n"
@@ -2691,7 +2538,12 @@ const char *builtincgshaderstring =
 "uniform float OffsetMapping_Scale : register(c24),\n"
 "#endif\n"
 "uniform half SpecularPower : register(c36),\n"
+"#ifdef HLSL\n"
+"out float4 gl_FragData0 : COLOR0,\n"
+"out float4 gl_FragData1 : COLOR1\n"
+"#else\n"
 "out float4 gl_FragColor : COLOR\n"
+"#endif\n"
 ")\n"
 "{\n"
 "      float2 TexCoord = TexCoordBoth.xy;\n"
@@ -2721,7 +2573,16 @@ const char *builtincgshaderstring =
 "      float a = tex2D(Texture_Gloss, TexCoord).a;\n"
 "#endif\n"
 "\n"
+"#ifdef HLSL\n"
+"      gl_FragData0 = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR.xyz) * 0.5 + float3(0.5, 0.5, 0.5), a);\n"
+"      float Depth = VectorR.w / 256.0;\n"
+"      float4 depthcolor = float4(Depth,Depth*65536.0/255.0,Depth*16777216.0/255.0,0.0);\n"
+"//    float4 depthcolor = float4(Depth,Depth*256.0,Depth*65536.0,0.0);\n"
+"      depthcolor.yz -= floor(depthcolor.yz);\n"
+"      gl_FragData1 = depthcolor;\n"
+"#else\n"
 "      gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), a);\n"
+"#endif\n"
 "}\n"
 "#endif // FRAGMENT_SHADER\n"
 "#else // !MODE_DEFERREDGEOMETRY\n"
@@ -2772,19 +2633,11 @@ const char *builtincgshaderstring =
 "uniform samplerCUBE Texture_Cube : register(s10),\n"
 "#endif\n"
 "\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerRECTShadow Texture_ShadowMapRect : register(s11),\n"
-"# else\n"
-"uniform samplerRECT Texture_ShadowMapRect : register(s11),\n"
-"# endif\n"
-"#endif\n"
-"\n"
 "#ifdef USESHADOWMAP2D\n"
 "# ifdef USESHADOWSAMPLER\n"
-"uniform sampler Texture_ShadowMap2D : register(s11),\n"
+"uniform sampler Texture_ShadowMap2D : register(s15),\n"
 "# else\n"
-"uniform sampler Texture_ShadowMap2D : register(s11),\n"
+"uniform sampler Texture_ShadowMap2D : register(s15),\n"
 "# endif\n"
 "#endif\n"
 "\n"
@@ -2792,15 +2645,7 @@ const char *builtincgshaderstring =
 "uniform samplerCUBE Texture_CubeProjection : register(s12),\n"
 "#endif\n"
 "\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerCUBEShadow Texture_ShadowMapCube : register(s11),\n"
-"# else\n"
-"uniform samplerCUBE Texture_ShadowMapCube : register(s11),\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "uniform float2 ShadowMap_TextureScale : register(c35),\n"
 "uniform float4 ShadowMap_Parameters : register(c34),\n"
 "#endif\n"
@@ -2813,7 +2658,11 @@ const char *builtincgshaderstring =
 "      float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
 "      //ScreenTexCoord.y = ScreenTexCoord.y * -1 + 1; // Cg is opposite?\n"
 "      float3 position;\n"
+"#ifdef HLSL\n"
+"      position.z = texDepth2D(Texture_ScreenDepth, ScreenTexCoord) * 256.0;\n"
+"#else\n"
 "      position.z = ScreenToDepth.y / (texDepth2D(Texture_ScreenDepth, ScreenTexCoord) + ScreenToDepth.x);\n"
+"#endif\n"
 "      position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
 "      // decode viewspace pixel normal\n"
 "      half4 normalmap = half4(tex2D(Texture_ScreenNormalMap, ScreenTexCoord));\n"
@@ -2833,29 +2682,19 @@ const char *builtincgshaderstring =
 "      // 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 * normalmap.a);\n"
+"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a));\n"
 "#  else\n"
 "      half3 specularnormal = half3(normalize(lightnormal + half3(normalize(eyevector))));\n"
-"      half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n"
+"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a));\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"
+"#if defined(USESHADOWMAP2D)\n"
+"      fade *= half(ShadowMapCompare(CubeVector, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
 "#ifdef USESHADOWMAPVSDCT\n"
 ", Texture_CubeProjection\n"
 "#endif\n"
-"      );\n"
+"      ));\n"
 "#endif\n"
 "\n"
 "#ifdef USEDIFFUSE\n"
@@ -2916,8 +2755,9 @@ const char *builtincgshaderstring =
 "#ifdef USESHADOWMAPORTHO\n"
 "uniform float4x4 ShadowMapMatrix : register(c16),\n"
 "#endif\n"
-"\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
 "out float4 gl_FrontColor : COLOR,\n"
+"#endif\n"
 "out float4 TexCoordBoth : TEXCOORD0,\n"
 "#ifdef USELIGHTMAP\n"
 "out float2 TexCoordLightmap : TEXCOORD1,\n"
@@ -2931,7 +2771,7 @@ const char *builtincgshaderstring =
 "#ifdef USEFOG\n"
 "out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
 "#endif\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE) || defined(USEDIFFUSE)\n"
 "out float3 LightVector : TEXCOORD1,\n"
 "#endif\n"
 "#ifdef MODE_LIGHTSOURCE\n"
@@ -3104,6 +2944,8 @@ const char *builtincgshaderstring =
 "uniform sampler Texture_ScreenNormalMap : register(s14),\n"
 "#endif\n"
 "#ifdef USEDEFERREDLIGHTMAP\n"
+"uniform sampler Texture_ScreenDepth : register(s13),\n"
+"uniform sampler Texture_ScreenNormalMap : register(s14),\n"
 "uniform sampler Texture_ScreenDiffuse : register(s11),\n"
 "uniform sampler Texture_ScreenSpecular : register(s12),\n"
 "#endif\n"
@@ -3161,19 +3003,11 @@ const char *builtincgshaderstring =
 "\n"
 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
 "\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerRECTShadow Texture_ShadowMapRect : register(s11),\n"
-"# else\n"
-"uniform samplerRECT Texture_ShadowMapRect : register(s11),\n"
-"# endif\n"
-"#endif\n"
-"\n"
 "#ifdef USESHADOWMAP2D\n"
 "# ifdef USESHADOWSAMPLER\n"
-"uniform sampler Texture_ShadowMap2D : register(s11),\n"
+"uniform sampler Texture_ShadowMap2D : register(s15),\n"
 "# else\n"
-"uniform sampler Texture_ShadowMap2D : register(s11),\n"
+"uniform sampler Texture_ShadowMap2D : register(s15),\n"
 "# endif\n"
 "#endif\n"
 "\n"
@@ -3181,15 +3015,7 @@ const char *builtincgshaderstring =
 "uniform samplerCUBE Texture_CubeProjection : register(s12),\n"
 "#endif\n"
 "\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerCUBEShadow Texture_ShadowMapCube : register(s11),\n"
-"# else\n"
-"uniform samplerCUBE Texture_ShadowMapCube : register(s11),\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"#if defined(USESHADOWMAP2D)\n"
 "uniform float2 ShadowMap_TextureScale : register(c35),\n"
 "uniform float4 ShadowMap_Parameters : register(c34),\n"
 "#endif\n"
@@ -3274,18 +3100,8 @@ const char *builtincgshaderstring =
 "#endif\n"
 "      color.rgb *= LightColor;\n"
 "      color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)).r);\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
-"      color.rgb *= half(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"
+"#if defined(USESHADOWMAP2D)\n"
+"      color.rgb *= half(ShadowMapCompare(CubeVector, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
 "#ifdef USESHADOWMAPVSDCT\n"
 ", Texture_CubeProjection\n"
 "#endif\n"
@@ -3298,21 +3114,24 @@ const char *builtincgshaderstring =
 "\n"
 "#ifdef USESHADOWMAP2D\n"
 "#ifdef USESHADOWMAPVSDCT\n"
-"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, float2(0.1,0.1)).rgb);\n"
-"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, GetShadowMapTC2D(CubeVector, ShadowMap_Parameters, Texture_CubeProjection).xy * ShadowMap_TextureScale).rgb);\n"
-"//    color.rgb = half3(GetShadowMapTC2D(CubeVector, ShadowMap_Parameters, Texture_CubeProjection).xyz * float3(ShadowMap_TextureScale,1.0));\n"
-"//    color.r = half(texDepth2D(Texture_ShadowMap2D, GetShadowMapTC2D(CubeVector, ShadowMap_Parameters, Texture_CubeProjection).xy * ShadowMap_TextureScale));\n"
+"//    float3 shadowmaptc = GetShadowMapTC2D(CubeVector, ShadowMap_Parameters, Texture_CubeProjection);\n"
 "#else\n"
 "//    float3 shadowmaptc = GetShadowMapTC2D(CubeVector, ShadowMap_Parameters);\n"
+"#endif\n"
 "//    color.rgb = half3(tex2D(Texture_ShadowMap2D, float2(0.1,0.1)).rgb);\n"
-"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, GetShadowMapTC2D(CubeVector, ShadowMap_Parameters).xy * ShadowMap_TextureScale).rgb);\n"
-"//    color.rgb = half3(GetShadowMapTC2D(CubeVector, ShadowMap_Parameters).xyz * float3(ShadowMap_TextureScale,1.0));\n"
-"//    color.r = half(texDepth2D(Texture_ShadowMap2D, GetShadowMapTC2D(CubeVector, ShadowMap_Parameters).xy * ShadowMap_TextureScale));\n"
+"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale).rgb);\n"
+"//    color.rgb = half3(shadowmaptc.xyz * float3(ShadowMap_TextureScale,1.0));\n"
+"//    color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
+"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, float2(0.1,0.1)).rgb);\n"
+"//    color.rgb = half3(tex2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale).rgb);\n"
+"//    color.rgb = half3(shadowmaptc.xyz * float3(ShadowMap_TextureScale,1.0));\n"
+"//    color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
 "//    color.r = half(shadowmaptc.z - texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
+"//    color.r = half(shadowmaptc.z);\n"
 "//    color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
 "//    color.r = half(shadowmaptc.z);\n"
-"#endif\n"
 "//    color.r = 1;\n"
+"//    color.rgb = abs(CubeVector);\n"
 "#endif\n"
 "//    color.rgb = half3(1,1,1);\n"
 "#endif // MODE_LIGHTSOURCE\n"
@@ -3358,6 +3177,15 @@ const char *builtincgshaderstring =
 "\n"
 "\n"
 "\n"
+"#ifdef MODE_FAKELIGHT\n"
+"#define SHADING\n"
+"half3 lightnormal = half3(normalize(EyeVector));\n"
+"half3 lightcolor = half3(1.0);\n"
+"#endif // MODE_FAKELIGHT\n"
+"\n"
+"\n"
+"\n"
+"\n"
 "#ifdef MODE_LIGHTMAP\n"
 "      color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb) * Color_Diffuse);\n"
 "#endif // MODE_LIGHTMAP\n"
@@ -3391,20 +3219,15 @@ const char *builtincgshaderstring =
 "#endif\n"
 "\n"
 "#ifdef USESHADOWMAPORTHO\n"
-"      color.rgb *= ShadowMapCompare(ShadowMapTC,\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"
-"      );\n"
+"      color.rgb *= half(ShadowMapCompare(ShadowMapTC, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale));\n"
 "#endif\n"
 "\n"
 "#ifdef USEDEFERREDLIGHTMAP\n"
 "      float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
 "      color.rgb += diffusetex * half3(tex2D(Texture_ScreenDiffuse, ScreenTexCoord).rgb) * DeferredMod_Diffuse;\n"
 "      color.rgb += glosstex.rgb * half3(tex2D(Texture_ScreenSpecular, ScreenTexCoord).rgb) * DeferredMod_Specular;\n"
+"//    color.rgb = half3(tex2D(Texture_ScreenDepth, ScreenTexCoord).rgb);\n"
+"//    color.r = half(texDepth2D(Texture_ScreenDepth, ScreenTexCoord)) * 1.0;\n"
 "#endif\n"
 "\n"
 "#ifdef USEGLOW\n"
@@ -3496,19 +3319,17 @@ typedef enum shaderpermutation_e
        SHADERPERMUTATION_REFLECTION = 1<<15, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
        SHADERPERMUTATION_OFFSETMAPPING = 1<<16, ///< adjust texcoords to roughly simulate a displacement mapped surface
        SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<17, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
-       SHADERPERMUTATION_SHADOWMAPRECT = 1<<18, ///< (lightsource) use shadowmap rectangle texture as light filter
-       SHADERPERMUTATION_SHADOWMAPCUBE = 1<<19, ///< (lightsource) use shadowmap cubemap texture as light filter
-       SHADERPERMUTATION_SHADOWMAP2D = 1<<20, ///< (lightsource) use shadowmap rectangle texture as light filter
-       SHADERPERMUTATION_SHADOWMAPPCF = 1<<21, ///< (lightsource) use percentage closer filtering on shadowmap test results
-       SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<22, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
-       SHADERPERMUTATION_SHADOWSAMPLER = 1<<23, ///< (lightsource) use hardware shadowmap test
-       SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<24, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
-       SHADERPERMUTATION_SHADOWMAPORTHO = 1<<25, //< (lightsource) use orthographic shadowmap projection
-       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<26, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
-       SHADERPERMUTATION_ALPHAKILL = 1<<27, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
-       SHADERPERMUTATION_REFLECTCUBE = 1<<28, ///< fake reflections using global cubemap (not HDRI light probe)
-       SHADERPERMUTATION_LIMIT = 1<<29, ///< size of permutations array
-       SHADERPERMUTATION_COUNT = 29 ///< size of shaderpermutationinfo array
+       SHADERPERMUTATION_SHADOWMAP2D = 1<<18, ///< (lightsource) use shadowmap texture as light filter
+       SHADERPERMUTATION_SHADOWMAPPCF = 1<<19, ///< (lightsource) use percentage closer filtering on shadowmap test results
+       SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<20, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
+       SHADERPERMUTATION_SHADOWSAMPLER = 1<<21, ///< (lightsource) use hardware shadowmap test
+       SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<22, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
+       SHADERPERMUTATION_SHADOWMAPORTHO = 1<<23, //< (lightsource) use orthographic shadowmap projection
+       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
+       SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
+       SHADERPERMUTATION_REFLECTCUBE = 1<<26, ///< fake reflections using global cubemap (not HDRI light probe)
+       SHADERPERMUTATION_LIMIT = 1<<27, ///< size of permutations array
+       SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array
 }
 shaderpermutation_t;
 
@@ -3533,8 +3354,6 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
        {"#define USEREFLECTION\n", " reflection"},
        {"#define USEOFFSETMAPPING\n", " offsetmapping"},
        {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
-       {"#define USESHADOWMAPRECT\n", " shadowmaprect"},
-       {"#define USESHADOWMAPCUBE\n", " shadowmapcube"},
        {"#define USESHADOWMAP2D\n", " shadowmap2d"},
        {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
        {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
@@ -3555,6 +3374,7 @@ typedef enum shadermode_e
        SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
        SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
        SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
+       SHADERMODE_FAKELIGHT, ///< (fakelight) modulate texture by "fake" lighting (no lightmaps, no nothing)
        SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
        SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
        SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
@@ -3577,6 +3397,7 @@ shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
+       {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
@@ -3597,6 +3418,7 @@ shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] =
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"},
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"},
+       {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FAKELIGHT\n", " fakelight"},
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
        {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
@@ -3664,8 +3486,6 @@ typedef struct r_glsl_permutation_s
        int loc_Texture_Cube;
        int loc_Texture_Refraction;
        int loc_Texture_Reflection;
-       int loc_Texture_ShadowMapRect;
-       int loc_Texture_ShadowMapCube;
        int loc_Texture_ShadowMap2D;
        int loc_Texture_CubeProjection;
        int loc_Texture_ScreenDepth;
@@ -3892,8 +3712,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->loc_Texture_Cube               = qglGetUniformLocationARB(p->program, "Texture_Cube");
                p->loc_Texture_Refraction         = qglGetUniformLocationARB(p->program, "Texture_Refraction");
                p->loc_Texture_Reflection         = qglGetUniformLocationARB(p->program, "Texture_Reflection");
-               p->loc_Texture_ShadowMapRect      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapRect");
-               p->loc_Texture_ShadowMapCube      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapCube");
                p->loc_Texture_ShadowMap2D        = qglGetUniformLocationARB(p->program, "Texture_ShadowMap2D");
                p->loc_Texture_CubeProjection     = qglGetUniformLocationARB(p->program, "Texture_CubeProjection");
                p->loc_Texture_ScreenDepth        = qglGetUniformLocationARB(p->program, "Texture_ScreenDepth");
@@ -3976,9 +3794,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                if (p->loc_Texture_Cube            >= 0) qglUniform1iARB(p->loc_Texture_Cube           , GL20TU_CUBE);
                if (p->loc_Texture_Refraction      >= 0) qglUniform1iARB(p->loc_Texture_Refraction     , GL20TU_REFRACTION);
                if (p->loc_Texture_Reflection      >= 0) qglUniform1iARB(p->loc_Texture_Reflection     , GL20TU_REFLECTION);
-               if (p->loc_Texture_ShadowMapRect   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect  , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT);
-               if (p->loc_Texture_ShadowMapCube   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapCube  , GL20TU_SHADOWMAPCUBE);
-               if (p->loc_Texture_ShadowMap2D     >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D    , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D);
+               if (p->loc_Texture_ShadowMap2D     >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D    , GL20TU_SHADOWMAP2D);
                if (p->loc_Texture_CubeProjection  >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
                if (p->loc_Texture_ScreenDepth     >= 0) qglUniform1iARB(p->loc_Texture_ScreenDepth    , GL20TU_SCREENDEPTH);
                if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP);
@@ -4093,8 +3909,6 @@ typedef struct r_cg_permutation_s
        CGparameter fp_Texture_Cube;
        CGparameter fp_Texture_Refraction;
        CGparameter fp_Texture_Reflection;
-       CGparameter fp_Texture_ShadowMapRect;
-       CGparameter fp_Texture_ShadowMapCube;
        CGparameter fp_Texture_ShadowMap2D;
        CGparameter fp_Texture_CubeProjection;
        CGparameter fp_Texture_ScreenDepth;
@@ -4393,8 +4207,6 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un
                p->fp_Texture_Cube               = cgGetNamedParameter(p->fprogram, "Texture_Cube");
                p->fp_Texture_Refraction         = cgGetNamedParameter(p->fprogram, "Texture_Refraction");
                p->fp_Texture_Reflection         = cgGetNamedParameter(p->fprogram, "Texture_Reflection");
-               p->fp_Texture_ShadowMapRect      = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapRect");
-               p->fp_Texture_ShadowMapCube      = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapCube");
                p->fp_Texture_ShadowMap2D        = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D");
                p->fp_Texture_CubeProjection     = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection");
                p->fp_Texture_ScreenDepth        = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth");
@@ -4721,10 +4533,14 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
        int psresult = 0;
        char temp[MAX_INPUTLINE];
        const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
+       qboolean debugshader = gl_paranoid.integer != 0;
        if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
        if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
-       vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
-       psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
+       if (!debugshader)
+       {
+               vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
+               psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
+       }
        if ((!vsbin && vertstring) || (!psbin && fragstring))
        {
                const char* dllnames_d3dx9 [] =
@@ -4752,19 +4568,34 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
                        NULL
                };
                dllhandle_t d3dx9_dll = NULL;
+               HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
+               HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
                HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
                dllfunction_t d3dx9_dllfuncs[] =
                {
+                       {"D3DXCompileShaderFromFileA",  (void **) &qD3DXCompileShaderFromFileA},
+                       {"D3DXPreprocessShader",                (void **) &qD3DXPreprocessShader},
                        {"D3DXCompileShader",                   (void **) &qD3DXCompileShader},
                        {NULL, NULL}
                };
                if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
                {
+                       DWORD shaderflags = 0;
+                       if (debugshader)
+                               shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
                        vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
                        psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
                        if (vertstring && vertstring[0])
                        {
-                               vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, 0, &vsbuffer, &vslog, &vsconstanttable);
+                               if (debugshader)
+                               {
+//                                     vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
+//                                     FS_WriteFile(va("%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
+                                       FS_WriteFile(va("%s_vs.fx", cachename), vertstring, strlen(vertstring));
+                                       vsresult = qD3DXCompileShaderFromFileA(va("%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
+                               }
+                               else
+                                       vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
                                if (vsbuffer)
                                {
                                        vsbinsize = vsbuffer->GetBufferSize();
@@ -4781,7 +4612,15 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
                        }
                        if (fragstring && fragstring[0])
                        {
-                               psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, 0, &psbuffer, &pslog, &psconstanttable);
+                               if (debugshader)
+                               {
+//                                     psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
+//                                     FS_WriteFile(va("%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
+                                       FS_WriteFile(va("%s_ps.fx", cachename), fragstring, strlen(fragstring));
+                                       psresult = qD3DXCompileShaderFromFileA(va("%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
+                               }
+                               else
+                                       psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
                                if (psbuffer)
                                {
                                        psbinsize = psbuffer->GetBufferSize();
@@ -4801,14 +4640,11 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
                else
                        Con_Printf("Unable to compile shader - D3DXCompileShader function not found\n");
        }
-       if (vsbin)
+       if (vsbin && psbin)
        {
                vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
                if (FAILED(vsresult))
                        Con_Printf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
-       }
-       if (psbin)
-       {
                psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
                if (FAILED(psresult))
                        Con_Printf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
@@ -5273,8 +5109,6 @@ extern cvar_t r_shadow_deferred_8bitrange;
 extern rtexture_t *r_shadow_attenuationgradienttexture;
 extern rtexture_t *r_shadow_attenuation2dtexture;
 extern rtexture_t *r_shadow_attenuation3dtexture;
-extern qboolean r_shadow_usingshadowmaprect;
-extern qboolean r_shadow_usingshadowmapcube;
 extern qboolean r_shadow_usingshadowmap2d;
 extern qboolean r_shadow_usingshadowmaportho;
 extern float r_shadow_shadowmap_texturescale[2];
@@ -5282,9 +5116,7 @@ extern float r_shadow_shadowmap_parameters[4];
 extern qboolean r_shadow_shadowmapvsdct;
 extern qboolean r_shadow_shadowmapsampler;
 extern int r_shadow_shadowmappcf;
-extern rtexture_t *r_shadow_shadowmaprectangletexture;
 extern rtexture_t *r_shadow_shadowmap2dtexture;
-extern rtexture_t *r_shadow_shadowmapcubetexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
 extern rtexture_t *r_shadow_shadowmap2dcolortexture;
 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
 extern matrix4x4_t r_shadow_shadowmapmatrix;
@@ -5293,6 +5125,7 @@ extern int r_shadow_prepass_width;
 extern int r_shadow_prepass_height;
 extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
+extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
 extern cvar_t gl_mesh_separatearrays;
@@ -5408,17 +5241,25 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
        {
                // distorted background
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
+               {
                        mode = SHADERMODE_WATER;
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               }
                else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
+               {
                        mode = SHADERMODE_REFRACTION;
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               }
                else
                {
                        mode = SHADERMODE_GENERIC;
                        permutation |= SHADERPERMUTATION_DIFFUSE;
+                       GL_BlendFunc(GL_ONE, GL_ZERO);
+                       allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
                }
                GL_AlphaTest(false);
-               GL_BlendFunc(GL_ONE, GL_ZERO);
-               allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
        }
        else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
        {
@@ -5482,15 +5323,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
                if (rsurface.texture->colormapping)
                        permutation |= SHADERPERMUTATION_COLORMAPPING;
-               if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
-               {
-                       if (r_shadow_usingshadowmaprect)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-                       if (r_shadow_usingshadowmap2d)
-                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
-                       if (r_shadow_usingshadowmapcube)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
-                       else if(r_shadow_shadowmapvsdct)
+               if (r_shadow_usingshadowmap2d)
+               {
+                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+                       if(r_shadow_shadowmapvsdct)
                                permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
 
                        if (r_shadow_shadowmapsampler)
@@ -5535,10 +5371,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
                {
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
-                       if (r_shadow_usingshadowmaprect)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-                       if (r_shadow_usingshadowmap2d)
-                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
                        if (r_shadow_shadowmapsampler)
                                permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
@@ -5590,10 +5423,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
                {
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
-                       if (r_shadow_usingshadowmaprect)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-                       if (r_shadow_usingshadowmap2d)
-                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
                        if (r_shadow_shadowmapsampler)
                                permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
@@ -5640,10 +5470,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
                {
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
-                       if (r_shadow_usingshadowmaprect)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-                       if (r_shadow_usingshadowmap2d)
-                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
                        if (r_shadow_shadowmapsampler)
                                permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
@@ -5689,10 +5516,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
                {
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
-                       if (r_shadow_usingshadowmaprect)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-                       if (r_shadow_usingshadowmap2d)
-                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
                        if (r_shadow_shadowmapsampler)
                                permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
@@ -5707,7 +5531,19 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
                if (rsurface.texture->reflectmasktexture)
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
-               if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
+               if (FAKELIGHT_ENABLED)
+               {
+                       // fake lightmapping (q1bsp, q3bsp, fullbright map)
+                       mode = SHADERMODE_FAKELIGHT;
+                       permutation |= SHADERPERMUTATION_DIFFUSE;
+                       if (specularscale > 0)
+                       {
+                               permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
+                               if (r_shadow_glossexact.integer)
+                                       permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
+                       }
+               }
+               else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
                {
                        // deluxemapping (light direction texture)
                        if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
@@ -5722,7 +5558,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                        permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
                        }
                }
-               else if (r_glsl_deluxemapping.integer >= 2)
+               else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture)
                {
                        // fake deluxemapping (uniform light direction in tangentspace)
                        mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
@@ -5820,8 +5656,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
                        hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
                        hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
-                       hlslPSSetParameter4fv(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f);
-                       hlslPSSetParameter4fv(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f);
+                       hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+                       hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
                        hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
@@ -5829,7 +5665,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
                hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
-               hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3]);
+               hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
                hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
                if (rsurface.texture->pantstexture)
                        hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
@@ -5880,7 +5716,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
-                       R_Mesh_TexBind((permutation & SHADERPERMUTATION_SHADOWMAPORTHO) ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D, (permutation & SHADERPERMUTATION_SHADOWSAMPLER) ? r_shadow_shadowmap2dtexture : r_shadow_shadowmap2dcolortexture);
+                       R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
                        if (rsurface.rtlight)
                        {
                                if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
@@ -5963,8 +5799,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
                        if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
                        if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
-                       if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
-                       if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
+                       if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+                       if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
                        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
@@ -5976,7 +5812,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
 
                if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
-               if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
+               if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
                if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
                if (r_glsl_permutation->loc_Color_Pants >= 0)
                {
@@ -6036,13 +5872,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_glsl_permutation->loc_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
-                       if (r_glsl_permutation->loc_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dtexture                         );
-                       if (r_glsl_permutation->loc_Texture_ShadowMapRect   >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT, r_shadow_shadowmaprectangletexture                  );
+                       if (r_glsl_permutation->loc_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dtexture                         );
                        if (rsurface.rtlight)
                        {
                                if (r_glsl_permutation->loc_Texture_Cube            >= 0) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
-                               if (r_shadow_usingshadowmapcube)
-                                       if (r_glsl_permutation->loc_Texture_ShadowMapCube   >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE     , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
                                if (r_glsl_permutation->loc_Texture_CubeProjection  >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
                        }
                }
@@ -6135,8 +5968,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_cg_permutation->fp_DistortScaleRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);CHECKCGERROR
                        if (r_cg_permutation->fp_ScreenScaleRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);CHECKCGERROR
                        if (r_cg_permutation->fp_ScreenCenterRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);CHECKCGERROR
-                       if (r_cg_permutation->fp_RefractColor) cgGLSetParameter4fv(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f);CHECKCGERROR
-                       if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4fv(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f);CHECKCGERROR
+                       if (r_cg_permutation->fp_RefractColor) cgGLSetParameter4fv(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
+                       if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4fv(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
                        if (r_cg_permutation->fp_ReflectFactor) cgGLSetParameter1f(r_cg_permutation->fp_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);CHECKCGERROR
                        if (r_cg_permutation->fp_ReflectOffset) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);CHECKCGERROR
                        if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
@@ -6144,7 +5977,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_cg_permutation->fp_ShadowMap_TextureScale) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);CHECKCGERROR
                if (r_cg_permutation->fp_ShadowMap_Parameters) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);CHECKCGERROR
                if (r_cg_permutation->fp_Color_Glow) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);CHECKCGERROR
-               if (r_cg_permutation->fp_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3]);CHECKCGERROR
+               if (r_cg_permutation->fp_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));CHECKCGERROR
                if (r_cg_permutation->fp_EyePosition) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
                if (r_cg_permutation->fp_Color_Pants)
                {
@@ -6207,12 +6040,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
                        if (r_cg_permutation->fp_Texture_ShadowMap2D    ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D    , r_shadow_shadowmap2dtexture                         );CHECKCGERROR
-                       if (r_cg_permutation->fp_Texture_ShadowMapRect  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect  , r_shadow_shadowmaprectangletexture                  );CHECKCGERROR
                        if (rsurface.rtlight)
                        {
                                if (r_cg_permutation->fp_Texture_Cube           ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube           , rsurface.rtlight->currentcubemap                    );CHECKCGERROR
-                               if (r_shadow_usingshadowmapcube)
-                                       if (r_cg_permutation->fp_Texture_ShadowMapCube  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube  , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
                                if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture                      );CHECKCGERROR
                        }
                }
@@ -6257,15 +6087,10 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_shadow_glossexact.integer)
                        permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
        }
-       if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
+       if (r_shadow_usingshadowmap2d)
        {
-               if (r_shadow_usingshadowmaprect)
-                       permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
-               if (r_shadow_usingshadowmap2d)
-                       permutation |= SHADERPERMUTATION_SHADOWMAP2D;
-               if (r_shadow_usingshadowmapcube)
-                       permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
-               else if(r_shadow_shadowmapvsdct)
+               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+               if (r_shadow_shadowmapvsdct)
                        permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
 
                if (r_shadow_shadowmapsampler)
@@ -6296,13 +6121,10 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
 
                R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
-               R_Mesh_TexBind(GL20TU_SCREENDEPTH        , r_shadow_prepassgeometrydepthtexture                );
+               R_Mesh_TexBind(GL20TU_SCREENDEPTH        , r_shadow_prepassgeometrydepthcolortexture           );
                R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
                R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
-               R_Mesh_TexBind(GL20TU_SHADOWMAPRECT      , r_shadow_shadowmaprectangletexture                  );
-               if (r_shadow_usingshadowmapcube)
-                       R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE      , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
-               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2dtexture                         );
+               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2dcolortexture                    );
                R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
 #endif
                break;
@@ -6329,9 +6151,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_glsl_permutation->loc_Texture_ScreenDepth       >= 0) R_Mesh_TexBind(GL20TU_SCREENDEPTH        , r_shadow_prepassgeometrydepthtexture                );
                if (r_glsl_permutation->loc_Texture_ScreenNormalMap   >= 0) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
                if (r_glsl_permutation->loc_Texture_Cube              >= 0) R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
-               if (r_glsl_permutation->loc_Texture_ShadowMapRect     >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPRECT      , r_shadow_shadowmaprectangletexture                  );
-               if (r_shadow_usingshadowmapcube)
-                       if (r_glsl_permutation->loc_Texture_ShadowMapCube     >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE      , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
                if (r_glsl_permutation->loc_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2dtexture                         );
                if (r_glsl_permutation->loc_Texture_CubeProjection    >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
                break;
@@ -6353,9 +6172,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_cg_permutation->fp_Texture_ScreenDepth      ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth    , r_shadow_prepassgeometrydepthtexture                );CHECKCGERROR
                if (r_cg_permutation->fp_Texture_ScreenNormalMap  ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture            );CHECKCGERROR
                if (r_cg_permutation->fp_Texture_Cube             ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube           , rsurface.rtlight->currentcubemap                    );CHECKCGERROR
-               if (r_cg_permutation->fp_Texture_ShadowMapRect    ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect  , r_shadow_shadowmaprectangletexture                  );CHECKCGERROR
-               if (r_shadow_usingshadowmapcube)
-                       if (r_cg_permutation->fp_Texture_ShadowMapCube    ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube  , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
                if (r_cg_permutation->fp_Texture_ShadowMap2D      ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D    , r_shadow_shadowmap2dtexture                         );CHECKCGERROR
                if (r_cg_permutation->fp_Texture_CubeProjection   ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture                      );CHECKCGERROR
 #endif
@@ -7426,6 +7242,8 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_fullbrights);
        Cvar_RegisterVariable(&r_wateralpha);
        Cvar_RegisterVariable(&r_dynamic);
+       Cvar_RegisterVariable(&r_fakelight);
+       Cvar_RegisterVariable(&r_fakelight_intensity);
        Cvar_RegisterVariable(&r_fullbright);
        Cvar_RegisterVariable(&r_shadows);
        Cvar_RegisterVariable(&r_shadows_darken);
@@ -7761,30 +7579,68 @@ void R_AnimCache_ClearCache(void)
 void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
 {
        int i;
+
+       // identical memory layout, so no need to allocate...
+       // this also provides the vertexposition structure to everything, e.g.
+       // depth masked rendering currently uses it even if having separate
+       // arrays
+       // NOTE: get rid of this optimization if changing it to e.g. 4f
+       ent->animcache_vertexposition = (r_vertexposition_t *)ent->animcache_vertex3f;
+
+       // TODO:
+       // get rid of following uses of VERTEXPOSITION, change to the array:
+       // R_DrawTextureSurfaceList_Sky if skyrendermasked
+       // R_DrawSurface_TransparentCallback if r_transparentdepthmasking.integer
+       // R_DrawTextureSurfaceList_DepthOnly
+       // R_Q1BSP_DrawShadowMap
+
+       switch(vid.renderpath)
+       {
+       case RENDERPATH_GL20:
+       case RENDERPATH_CGGL:
+               // need the meshbuffers if !gl_mesh_separatearrays.integer
+               if (gl_mesh_separatearrays.integer)
+                       return;
+               break;
+       case RENDERPATH_D3D9:
+       case RENDERPATH_D3D10:
+       case RENDERPATH_D3D11:
+               // always need the meshbuffers
+               break;
+       case RENDERPATH_GL13:
+       case RENDERPATH_GL11:
+               // never need the meshbuffers
+               return;
+       }
+
        if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
                ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
+       /*
        if (!ent->animcache_vertexposition)
                ent->animcache_vertexposition = (r_vertexposition_t *)R_FrameData_Alloc(sizeof(r_vertexposition_t)*numvertices);
+       */
        if (ent->animcache_vertexposition)
        {
+               /*
                for (i = 0;i < numvertices;i++)
-                       VectorCopy(ent->animcache_vertex3f + 3*i, ent->animcache_vertexposition[i].vertex3f);
+                       memcpy(ent->animcache_vertexposition[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
+               */
                // TODO: upload vertex buffer?
        }
        if (ent->animcache_vertexmesh)
        {
                memcpy(ent->animcache_vertexmesh, ent->model->surfmesh.vertexmesh, sizeof(r_vertexmesh_t)*numvertices);
                for (i = 0;i < numvertices;i++)
-                       VectorCopy(ent->animcache_vertex3f + 3*i, ent->animcache_vertexmesh[i].vertex3f);
+                       memcpy(ent->animcache_vertexmesh[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
                if (ent->animcache_svector3f)
                        for (i = 0;i < numvertices;i++)
-                               VectorCopy(ent->animcache_svector3f + 3*i, ent->animcache_vertexmesh[i].svector3f);
+                               memcpy(ent->animcache_vertexmesh[i].svector3f, ent->animcache_svector3f + 3*i, sizeof(float[3]));
                if (ent->animcache_tvector3f)
                        for (i = 0;i < numvertices;i++)
-                               VectorCopy(ent->animcache_tvector3f + 3*i, ent->animcache_vertexmesh[i].tvector3f);
+                               memcpy(ent->animcache_vertexmesh[i].tvector3f, ent->animcache_tvector3f + 3*i, sizeof(float[3]));
                if (ent->animcache_normal3f)
                        for (i = 0;i < numvertices;i++)
-                               VectorCopy(ent->animcache_normal3f + 3*i, ent->animcache_vertexmesh[i].normal3f);
+                               memcpy(ent->animcache_vertexmesh[i].normal3f, ent->animcache_normal3f + 3*i, sizeof(float[3]));
                // TODO: upload vertex buffer?
        }
 }
@@ -8575,12 +8431,8 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno)
        vec3_t normal;
        vec3_t center;
        mplane_t plane;
-       int cam_ent;
        r_waterstate_waterplane_t *p;
        texture_t *t = R_GetCurrentTexture(surface->texture);
-       cam_ent = t->camera_entity;
-       if(!(t->currentmaterialflags & MATERIALFLAG_CAMERA))
-               cam_ent = 0;
 
        // just use the first triangle with a valid normal for any decisions
        VectorClear(normal);
@@ -8735,7 +8587,11 @@ static void R_Water_ProcessPlanes(void)
                                r_waterstate.renderingrefraction = false; // we don't want to hide the player model from these ones
                                CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
                                R_RenderView_UpdateViewVectors();
-                               r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
+                               if(r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
+                               {
+                                       r_refdef.view.usecustompvs = true;
+                                       r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
+                               }
                        }
 
                        PlaneClassify(&r_refdef.view.clipplane);
@@ -8773,8 +8629,11 @@ static void R_Water_ProcessPlanes(void)
                        // also reverse the view matrix
                        Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, 1, -1); // this serves to invert texcoords in the result, as the copied texture is mapped the wrong way round
                        R_RenderView_UpdateViewVectors();
-                       if(p->camera_entity)
+                       if(p->camera_entity && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
+                       {
+                               r_refdef.view.usecustompvs = true;
                                r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
+                       }
                        
                        // camera needs no clipplane
                        r_refdef.view.useclipplane = false;
@@ -9371,6 +9230,10 @@ void R_UpdateVariables(void)
        r_refdef.scene.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer;
        r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
        r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+       if (FAKELIGHT_ENABLED)
+       {
+               r_refdef.lightmapintensity *= r_fakelight_intensity.value;
+       }
        if (r_showsurfaces.integer)
        {
                r_refdef.scene.rtworld = false;
@@ -10444,23 +10307,27 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                        R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
                t->currentskinframe = r_qwskincache[i].skinframe;
                if (t->currentskinframe == NULL)
-                       t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
+                       t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
        }
        else if (t->numskinframes >= 2)
-               t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
+               t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
        if (t->backgroundnumskinframes >= 2)
-               t->backgroundcurrentskinframe = t->backgroundskinframes[(int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
+               t->backgroundcurrentskinframe = t->backgroundskinframes[(unsigned int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
 
        t->currentmaterialflags = t->basematerialflags;
        t->currentalpha = rsurface.colormod[3];
        if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
                t->currentalpha *= r_wateralpha.value;
        if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay)
-               t->currentalpha *= t->r_water_wateralpha;
+               t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later
        if(!r_waterstate.enabled || r_refdef.view.isoverlay)
                t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA);
        if (!(rsurface.ent_flags & RENDER_LIGHT))
                t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
+       else if (FAKELIGHT_ENABLED)
+       {
+                       // no modellight if using fakelight for the map
+       }
        else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
        {
                // pick a model lighting mode
@@ -11242,7 +11109,6 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
        int surfacefirstvertex;
        int surfaceendvertex;
        int surfacenumvertices;
-       int surfaceadjustvertex;
        int needsupdate;
        int i, j;
        qboolean gaps;
@@ -11572,7 +11438,6 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                        surfacefirstvertex = texturesurfacelist[i]->num_firstvertex;
                        surfacenumvertices = texturesurfacelist[i]->num_vertices;
                        surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
-                       surfaceadjustvertex = numvertices - surfacefirstvertex;
                        surfacenumtriangles = texturesurfacelist[i]->num_triangles;
                        // copy only the data requested
                        if ((batchneed & BATCHNEED_VERTEXPOSITION) && rsurface.modelvertexposition)
@@ -11723,6 +11588,7 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                        VectorMAMAMAM(1, center, DotProduct(forward, v), newforward, DotProduct(right, v), newright, DotProduct(up, v), newup, rsurface.array_batchvertex3f + 3*(j+i));
                                }
                        }
+                       // if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
                        Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
                        Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
                        rsurface.batchvertex3f = rsurface.array_batchvertex3f;
@@ -11823,20 +11689,26 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                        }
                                }
                        }
-                       Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
-                       Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
                        rsurface.batchvertex3f = rsurface.array_batchvertex3f;
                        rsurface.batchvertex3f_vertexbuffer = NULL;
                        rsurface.batchvertex3f_bufferoffset = 0;
-                       rsurface.batchsvector3f = rsurface.array_batchsvector3f;
-                       rsurface.batchsvector3f_vertexbuffer = NULL;
-                       rsurface.batchsvector3f_bufferoffset = 0;
-                       rsurface.batchtvector3f = rsurface.array_batchtvector3f;
-                       rsurface.batchtvector3f_vertexbuffer = NULL;
-                       rsurface.batchtvector3f_bufferoffset = 0;
-                       rsurface.batchnormal3f = rsurface.array_batchnormal3f;
-                       rsurface.batchnormal3f_vertexbuffer = NULL;
-                       rsurface.batchnormal3f_bufferoffset = 0;
+                       if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
+                       {
+                               Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
+                               rsurface.batchnormal3f = rsurface.array_batchnormal3f;
+                               rsurface.batchnormal3f_vertexbuffer = NULL;
+                               rsurface.batchnormal3f_bufferoffset = 0;
+                       }
+                       if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+                       {
+                               Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
+                               rsurface.batchsvector3f = rsurface.array_batchsvector3f;
+                               rsurface.batchsvector3f_vertexbuffer = NULL;
+                               rsurface.batchsvector3f_bufferoffset = 0;
+                               rsurface.batchtvector3f = rsurface.array_batchtvector3f;
+                               rsurface.batchtvector3f_vertexbuffer = NULL;
+                               rsurface.batchtvector3f_bufferoffset = 0;
+                       }
                        break;
                case Q3DEFORM_NORMAL:
                        // deform the normals to make reflections wavey
@@ -11850,16 +11722,19 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                normal[2] = rsurface.batchnormal3f[j*3+2] + deform->parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
                                VectorNormalize(normal);
                        }
-                       Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
-                       rsurface.batchsvector3f = rsurface.array_batchsvector3f;
-                       rsurface.batchsvector3f_vertexbuffer = NULL;
-                       rsurface.batchsvector3f_bufferoffset = 0;
-                       rsurface.batchtvector3f = rsurface.array_batchtvector3f;
-                       rsurface.batchtvector3f_vertexbuffer = NULL;
-                       rsurface.batchtvector3f_bufferoffset = 0;
                        rsurface.batchnormal3f = rsurface.array_batchnormal3f;
                        rsurface.batchnormal3f_vertexbuffer = NULL;
                        rsurface.batchnormal3f_bufferoffset = 0;
+                       if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+                       {
+                               Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
+                               rsurface.batchsvector3f = rsurface.array_batchsvector3f;
+                               rsurface.batchsvector3f_vertexbuffer = NULL;
+                               rsurface.batchsvector3f_bufferoffset = 0;
+                               rsurface.batchtvector3f = rsurface.array_batchtvector3f;
+                               rsurface.batchtvector3f_vertexbuffer = NULL;
+                               rsurface.batchtvector3f_bufferoffset = 0;
+                       }
                        break;
                case Q3DEFORM_WAVE:
                        // deform vertex array to make wavey water and flags and such
@@ -11882,20 +11757,24 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                }
                                VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.array_batchvertex3f + 3*j);
                        }
+                       // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
                        Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
-                       Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
                        rsurface.batchvertex3f = rsurface.array_batchvertex3f;
                        rsurface.batchvertex3f_vertexbuffer = NULL;
                        rsurface.batchvertex3f_bufferoffset = 0;
-                       rsurface.batchsvector3f = rsurface.array_batchsvector3f;
-                       rsurface.batchsvector3f_vertexbuffer = NULL;
-                       rsurface.batchsvector3f_bufferoffset = 0;
-                       rsurface.batchtvector3f = rsurface.array_batchtvector3f;
-                       rsurface.batchtvector3f_vertexbuffer = NULL;
-                       rsurface.batchtvector3f_bufferoffset = 0;
                        rsurface.batchnormal3f = rsurface.array_batchnormal3f;
                        rsurface.batchnormal3f_vertexbuffer = NULL;
                        rsurface.batchnormal3f_bufferoffset = 0;
+                       if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+                       {
+                               Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
+                               rsurface.batchsvector3f = rsurface.array_batchsvector3f;
+                               rsurface.batchsvector3f_vertexbuffer = NULL;
+                               rsurface.batchsvector3f_bufferoffset = 0;
+                               rsurface.batchtvector3f = rsurface.array_batchtvector3f;
+                               rsurface.batchtvector3f_vertexbuffer = NULL;
+                               rsurface.batchtvector3f_bufferoffset = 0;
+                       }
                        break;
                case Q3DEFORM_BULGE:
                        // deform vertex array to make the surface have moving bulges
@@ -11904,20 +11783,24 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                                scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + r_refdef.scene.time * deform->parms[2]) * deform->parms[1];
                                VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.array_batchvertex3f + 3*j);
                        }
+                       // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
                        Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
-                       Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
                        rsurface.batchvertex3f = rsurface.array_batchvertex3f;
                        rsurface.batchvertex3f_vertexbuffer = NULL;
                        rsurface.batchvertex3f_bufferoffset = 0;
-                       rsurface.batchsvector3f = rsurface.array_batchsvector3f;
-                       rsurface.batchsvector3f_vertexbuffer = NULL;
-                       rsurface.batchsvector3f_bufferoffset = 0;
-                       rsurface.batchtvector3f = rsurface.array_batchtvector3f;
-                       rsurface.batchtvector3f_vertexbuffer = NULL;
-                       rsurface.batchtvector3f_bufferoffset = 0;
                        rsurface.batchnormal3f = rsurface.array_batchnormal3f;
                        rsurface.batchnormal3f_vertexbuffer = NULL;
                        rsurface.batchnormal3f_bufferoffset = 0;
+                       if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+                       {
+                               Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
+                               rsurface.batchsvector3f = rsurface.array_batchsvector3f;
+                               rsurface.batchsvector3f_vertexbuffer = NULL;
+                               rsurface.batchsvector3f_bufferoffset = 0;
+                               rsurface.batchtvector3f = rsurface.array_batchtvector3f;
+                               rsurface.batchtvector3f_vertexbuffer = NULL;
+                               rsurface.batchtvector3f_bufferoffset = 0;
+                       }
                        break;
                case Q3DEFORM_MOVE:
                        // deform vertex array
@@ -12247,6 +12130,40 @@ static void RSurf_DrawBatch_GL11_ClampColor(void)
        }
 }
 
+static void RSurf_DrawBatch_GL11_ApplyFakeLight(void)
+{
+       int i;
+       float f;
+       const float *v;
+       const float *n;
+       float *c;
+       //vec3_t eyedir;
+
+       // fake shading
+       for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, n = rsurface.batchnormal3f + rsurface.batchfirstvertex * 3, c = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, n += 3, c += 4)
+       {
+               f = -DotProduct(r_refdef.view.forward, n);
+               f = max(0, f);
+               f = f * 0.85 + 0.15; // work around so stuff won't get black
+               f *= r_refdef.lightmapintensity;
+               Vector4Set(c, f, f, f, 1);
+       }
+
+       rsurface.passcolor4f = rsurface.array_passcolor4f;
+       rsurface.passcolor4f_vertexbuffer = 0;
+       rsurface.passcolor4f_bufferoffset = 0;
+}
+
+static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
+{
+       RSurf_DrawBatch_GL11_ApplyFakeLight();
+       if (applyfog)   RSurf_DrawBatch_GL11_ApplyFog();
+       if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
+       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
+       GL_Color(r, g, b, a);
+       RSurf_DrawBatch();
+}
+
 static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor)
 {
        int i;
@@ -12363,7 +12280,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_
                        // just to make sure that braindead drivers don't draw
                        // anything despite that colormask...
                        GL_BlendFunc(GL_ZERO, GL_ONE);
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION, texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
                        R_Mesh_PrepareVertices_Position(rsurface.batchnumvertices, rsurface.batchvertexposition, rsurface.batchvertexpositionbuffer);
                }
                else
@@ -12371,7 +12288,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_
                        R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
                        // fog sky
                        GL_BlendFunc(GL_ONE, GL_ZERO);
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
                        GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1);
                        R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
                }
@@ -12497,6 +12414,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface
                        R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
                        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
                                RSurf_DrawBatch_GL11_VertexShade(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
+                       else if (FAKELIGHT_ENABLED)
+                               RSurf_DrawBatch_GL11_FakeLight(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
                        else if (rsurface.uselightmaptexture)
                                RSurf_DrawBatch_GL11_Lightmap(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
                        else
@@ -12582,6 +12501,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface
                                R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
                                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
                                        RSurf_DrawBatch_GL11_VertexShade(1, 1, 1, 1, false, false);
+                               else if (FAKELIGHT_ENABLED)
+                                       RSurf_DrawBatch_GL11_FakeLight(1, 1, 1, 1, false, false);
                                else if (rsurface.uselightmaptexture)
                                        RSurf_DrawBatch_GL11_Lightmap(1, 1, 1, 1, false, false);
                                else
@@ -12733,6 +12654,14 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const
                        RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor);
                        r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
                }
+               else if (FAKELIGHT_ENABLED)
+               {
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
+
+                       r_refdef.lightmapintensity = r_fakelight_intensity.value;
+                       RSurf_DrawBatch_GL11_ApplyFakeLight();
+                       r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
+               }
                else
                {
                        RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
@@ -12967,7 +12896,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const
                surface = rsurface.modelsurfaces + surfacelist[i];
                texture = surface->texture;
                rsurface.texture = R_GetCurrentTexture(texture);
-               rsurface.lightmaptexture = surface->lightmaptexture;
+               rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surface->lightmaptexture;
                rsurface.deluxemaptexture = surface->deluxemaptexture;
                rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
                // scan ahead until we find a different texture
@@ -13073,7 +13002,7 @@ void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, in
                // use skin 1 instead)
                texture = surfacelist[i]->texture;
                rsurface.texture = R_GetCurrentTexture(texture);
-               rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
+               rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surfacelist[i]->lightmaptexture;
                rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
                rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass;
                if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
@@ -13137,7 +13066,7 @@ void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurfa
                // use skin 1 instead)
                texture = surfacelist[i]->texture;
                rsurface.texture = R_GetCurrentTexture(texture);
-               rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
+               rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surfacelist[i]->lightmaptexture;
                rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
                rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass;
                if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))