"// written by Forest 'LordHavoc' Hale\n"
"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
"\n"
+"#ifdef USECELSHADING\n"
+"# define SHADEDIFFUSE myhalf diffuse = cast_myhalf(min(max(float(dot(surfacenormal, lightnormal)) * 2.0, 0.0), 1.0));\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+"# define SHADESPECULAR(specpow) myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), eyenormal))*-1.0, 0.0)), 1.0 + specpow);specular = max(0.0, specular * 10.0 - 9.0);\n"
+"# else\n"
+"# define SHADESPECULAR(specpow) myhalf3 specularnormal = normalize(lightnormal + eyenormal);myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + specpow);specular = max(0.0, specular * 10.0 - 9.0);\n"
+"# endif\n"
+"#else\n"
+"# define SHADEDIFFUSE myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+"# define SHADESPECULAR(specpow) myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), eyenormal))*-1.0, 0.0)), 1.0 + specpow);\n"
+"# else\n"
+"# define SHADESPECULAR(specpow) myhalf3 specularnormal = normalize(lightnormal + eyenormal);myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + specpow);\n"
+"# endif\n"
+"#endif\n"
+"\n"
"#ifdef GLSL130\n"
"precision highp float;\n"
"# ifdef VERTEX_SHADER\n"
"\n"
"void main(void)\n"
"{\n"
+"#ifdef USEALPHAGENVERTEX\n"
+" VertexColor = Attrib_Color;\n"
+"#endif\n"
" TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
" gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
" ModelViewProjectionPosition = gl_Position;\n"
" vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
" //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
" vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
+"#ifdef USEALPHAGENVERTEX\n"
+" vec2 distort = DistortScaleRefractReflect.xy * VertexColor.a;\n"
+" vec4 refractcolor = mix(RefractColor, vec4(1.0, 1.0, 1.0, 1.0), VertexColor.a);\n"
+"#else\n"
+" vec2 distort = DistortScaleRefractReflect.xy;\n"
+" vec4 refractcolor = RefractColor;\n"
+"#endif\n"
" #ifdef USENORMALMAPSCROLLBLEND\n"
" vec3 normal = dp_texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n"
" normal += dp_texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n"
-" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(cast_myhalf3(normal))).xy * DistortScaleRefractReflect.xy;\n"
+" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(cast_myhalf3(normal))).xy * distort;\n"
" #else\n"
-" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(cast_myhalf3(dp_texture2D(Texture_Normal, TexCoord)) - cast_myhalf3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
+" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(cast_myhalf3(dp_texture2D(Texture_Normal, TexCoord)) - cast_myhalf3(0.5))).xy * distort;\n"
" #endif\n"
" // FIXME temporary hack to detect the case that the reflection\n"
" // gets blackened at edges due to leaving the area that contains actual\n"
" f *= min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
" f *= min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
" ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-" dp_FragColor = vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * RefractColor;\n"
+" dp_FragColor = vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * refractcolor;\n"
"}\n"
"#endif\n"
"#else // !MODE_REFRACTION\n"
"\n"
"void main(void)\n"
"{\n"
+"#ifdef USEALPHAGENVERTEX\n"
+" VertexColor = Attrib_Color;\n"
+"#endif\n"
" TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
" vec3 EyeRelative = EyePosition - Attrib_Position.xyz;\n"
" EyeVector.x = dot(EyeRelative, Attrib_TexCoord1.xyz);\n"
" vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
" //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n"
" // slight water animation via 2 layer scrolling (todo: tweak)\n"
+"#ifdef USEALPHAGENVERTEX\n"
+" vec4 distort = DistortScaleRefractReflect * VertexColor.a;\n"
+" float reflectoffset = ReflectOffset * VertexColor.a;\n"
+" float reflectfactor = ReflectFactor * VertexColor.a;\n"
+" vec4 refractcolor = mix(RefractColor, vec4(1.0, 1.0, 1.0, 1.0), VertexColor.a);\n"
+"#else\n"
+" vec4 distort = DistortScaleRefractReflect;\n"
+" float reflectoffset = ReflectOffset;\n"
+" float reflectfactor = ReflectFactor;\n"
+" vec4 refractcolor = RefractColor;\n"
+"#endif\n"
" #ifdef USENORMALMAPSCROLLBLEND\n"
" vec3 normal = dp_texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n"
" normal += dp_texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n"
-" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * DistortScaleRefractReflect;\n"
+" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * distort;\n"
" #else\n"
-" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
+" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * distort;\n"
" #endif\n"
" // FIXME temporary hack to detect the case that the reflection\n"
" // gets blackened at edges due to leaving the area that contains actual\n"
" f *= min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, 0.005)).rgb) / 0.002);\n"
" f *= min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, -0.005)).rgb) / 0.002);\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"
-" dp_FragColor = mix(vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
+" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * reflectfactor + reflectoffset;\n"
+" dp_FragColor = mix(vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * refractcolor, vec4(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
"}\n"
"#endif\n"
"#else // !MODE_WATER\n"
"uniform sampler2D Texture_ScreenNormalMap;\n"
"#endif\n"
"#ifdef USEDEFERREDLIGHTMAP\n"
+"#ifdef USECELOUTLINES\n"
+"uniform sampler2D Texture_ScreenNormalMap;\n"
+"#endif\n"
"uniform sampler2D Texture_ScreenDiffuse;\n"
"uniform sampler2D Texture_ScreenSpecular;\n"
"#endif\n"
" float i;\n"
" // distance-based LOD\n"
"#ifdef USEOFFSETMAPPING_LOD\n"
-" mediump float LODFactor = min(1.0, OffsetMapping_LodDistance / EyeVectorFogDepth.z);\n"
-" mediump vec4 ScaleSteps = vec4(OffsetMapping_ScaleSteps.x, OffsetMapping_ScaleSteps.y * LODFactor, OffsetMapping_ScaleSteps.z / LODFactor, OffsetMapping_ScaleSteps.w * LODFactor);\n"
+" //mediump float LODFactor = min(1.0, OffsetMapping_LodDistance / EyeVectorFogDepth.z);\n"
+" //mediump vec4 ScaleSteps = vec4(OffsetMapping_ScaleSteps.x, OffsetMapping_ScaleSteps.y * LODFactor, OffsetMapping_ScaleSteps.z / LODFactor, OffsetMapping_ScaleSteps.w * LODFactor);\n"
+" mediump float GuessLODFactor = min(1.0, OffsetMapping_LodDistance / EyeVectorFogDepth.z);\n"
+"#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
+" // stupid workaround because 1-step and 2-step reliefmapping is void\n"
+" mediump float LODSteps = max(3.0, ceil(GuessLODFactor * OffsetMapping_ScaleSteps.y));\n"
+"#else\n"
+" mediump float LODSteps = ceil(GuessLODFactor * OffsetMapping_ScaleSteps.y);\n"
+"#endif\n"
+" mediump float LODFactor = LODSteps / OffsetMapping_ScaleSteps.y;\n"
+" mediump vec4 ScaleSteps = vec4(OffsetMapping_ScaleSteps.x, LODSteps, 1.0 / LODSteps, OffsetMapping_ScaleSteps.w * LODFactor);\n"
"#else\n"
" #define ScaleSteps OffsetMapping_ScaleSteps\n"
"#endif\n"
" // surfacenormal = pixel normal in viewspace\n"
" // LightVector = pixel to light in viewspace\n"
" // CubeVector = pixel in lightspace\n"
-" // eyevector = pixel to view in viewspace\n"
+" // eyenormal = pixel to view direction in viewspace\n"
" vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
" myhalf fade = cast_myhalf(dp_texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
"#ifdef USEDIFFUSE\n"
" // calculate diffuse shading\n"
" myhalf3 lightnormal = cast_myhalf3(normalize(LightPosition - position));\n"
-" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"SHADEDIFFUSE\n"
"#endif\n"
"#ifdef USESPECULAR\n"
" // calculate directional shading\n"
-" vec3 eyevector = position * -1.0;\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), 1.0 + SpecularPower * normalmap.a);\n"
-"# else\n"
-" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(eyevector)));\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * normalmap.a);\n"
-"# endif\n"
+" myhalf3 eyenormal = -normalize(cast_myhalf3(position));\n"
+"SHADESPECULAR(SpecularPower * normalmap.a)\n"
"#endif\n"
"\n"
"#if defined(USESHADOWMAP2D)\n"
" diffusetex += cast_myhalf3(offsetMappedTexture2D(Texture_ReflectMask)) * cast_myhalf3(dp_textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n"
"#endif\n"
"\n"
+"#ifdef USESPECULAR\n"
+" myhalf3 eyenormal = normalize(cast_myhalf3(EyeVectorFogDepth.xyz));\n"
+"#endif\n"
+"\n"
"\n"
"\n"
"\n"
" // light source\n"
"#ifdef USEDIFFUSE\n"
" myhalf3 lightnormal = cast_myhalf3(normalize(LightVector));\n"
-" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"SHADEDIFFUSE\n"
" color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
"#ifdef USESPECULAR\n"
-"#ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
-"#else\n"
-" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
-"#endif\n"
+"SHADESPECULAR(SpecularPower * glosstex.a)\n"
" color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
"#endif\n"
"#else\n"
"\n"
"#ifdef SHADING\n"
"# ifdef USEDIFFUSE\n"
-" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"SHADEDIFFUSE\n"
"# ifdef USESPECULAR\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
-"# else\n"
-" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n"
-" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
-"# endif\n"
+"SHADESPECULAR(SpecularPower * glosstex.a)\n"
" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
"# else\n"
" color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
"#endif\n"
"#endif\n"
"\n"
+"#ifdef USECELOUTLINES\n"
+"# ifdef USEDEFERREDLIGHTMAP\n"
+"// vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
+" vec4 ScreenTexCoordStep = vec4(PixelToScreenTexCoord.x, 0.0, 0.0, PixelToScreenTexCoord.y);\n"
+" vec4 DepthNeighbors;\n"
+" float DepthCenter = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord).b;\n"
+" DepthNeighbors.x = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord - ScreenTexCoordStep.xy).b;\n"
+" DepthNeighbors.y = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord + ScreenTexCoordStep.xy).b;\n"
+" DepthNeighbors.z = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord + ScreenTexCoordStep.zw).b;\n"
+" DepthNeighbors.w = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord - ScreenTexCoordStep.zw).b;\n"
+" float DepthAverage = dot(DepthNeighbors, vec4(0.25, 0.25, 0.25, 0.25));\n"
+" float DepthDelta = abs(dot(DepthNeighbors.xy, vec2(-1.0, 1.0))) + abs(dot(DepthNeighbors.zw, vec2(-1.0, 1.0)));\n"
+"// color.rgb = vec3(1.0, 1.0, 1.0);\n"
+" color.rgb *= max(0.25, 1.0 - max(0.0, abs(DepthCenter - DepthAverage) - 0.07 * DepthDelta) / (0.03 + 0.03 * DepthDelta));\n"
+"// color.rgb *= step(abs(DepthCenter - DepthAverage), 0.2 * DepthDelta);\n"
+"# endif\n"
+"#endif\n"
+"\n"
"#ifdef USEFOG\n"
" color.rgb = FogVertex(color);\n"
"#endif\n"