From c964caa845812f427f8d462ebf36737aa6339551 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 15 Jun 2010 19:29:24 +0200 Subject: [PATCH] workaround for gl_FrontFacing bug gl_FrontFacing isn't well supported on some Macintosh / ATI combinations. --- Effects/model-default.eff | 22 +++++++++++++---- Shaders/model-default.frag | 46 ++++++++++++++++++++++++++++++++++++ Shaders/model-default.vert | 8 +++++++ Shaders/terrain-default.frag | 2 -- 4 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 Shaders/model-default.frag diff --git a/Effects/model-default.eff b/Effects/model-default.eff index fb3d92c82..ece38c79e 100644 --- a/Effects/model-default.eff +++ b/Effects/model-default.eff @@ -5,6 +5,7 @@ white + false @@ -60,14 +61,23 @@ --> + + vertex-program-two-side + Shaders/model-default.vert - Shaders/default.frag + Shaders/model-default.frag - texture - sampler-2d - 0 + texture + sampler-2d + 0 + + + twoSideHack + bool + vertex-program-two-side + @@ -106,6 +116,10 @@ modulate + diff --git a/Shaders/model-default.frag b/Shaders/model-default.frag new file mode 100644 index 000000000..2cf37e2a1 --- /dev/null +++ b/Shaders/model-default.frag @@ -0,0 +1,46 @@ +// -*-C++-*- + +varying vec4 diffuse, constantColor; +varying vec3 normal, lightDir, halfVector; +varying float fogCoord, alpha; + +uniform bool twoSideHack; + +uniform sampler2D texture; + +float luminance(vec3 color) +{ + return dot(vec3(0.212671, 0.715160, 0.072169), color); +} + +void main() +{ + vec3 n, halfV; + float NdotL, NdotHV, fogFactor; + vec4 color = constantColor; + vec4 texel; + vec4 fragColor; + vec4 specular = vec4(0.0); + n = normalize(normal); + if (twoSideHack && gl_Color.a == 0.0) + n = -n; + NdotL = max(dot(n, lightDir), 0.0); + if (NdotL > 0.0) { + color += diffuse * NdotL; + halfV = normalize(halfVector); + NdotHV = max(dot(n, halfV), 0.0); + if (gl_FrontMaterial.shininess > 0.0) + specular.rgb = (gl_FrontMaterial.specular.rgb + * gl_LightSource[0].specular.rgb + * pow(NdotHV, gl_FrontMaterial.shininess)); + } + color.a = alpha; + // This shouldn't be necessary, but our lighting becomes very + // saturated. Clamping the color before modulating by the texture + // is closer to what the OpenGL fixed function pipeline does. + color = clamp(color, 0.0, 1.0); + texel = texture2D(texture, gl_TexCoord[0].st); + fragColor = color * texel + specular; + fogFactor = exp(-gl_Fog.density * gl_Fog.density * fogCoord * fogCoord); + gl_FragColor = mix(gl_Fog.color, fragColor, fogFactor); +} diff --git a/Shaders/model-default.vert b/Shaders/model-default.vert index 50ba771fc..924f90c38 100644 --- a/Shaders/model-default.vert +++ b/Shaders/model-default.vert @@ -12,6 +12,8 @@ varying vec4 diffuse, constantColor; varying vec3 normal, lightDir, halfVector; varying float alpha, fogCoord; +uniform bool twoSideHack; + void main() { vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; @@ -28,6 +30,12 @@ void main() alpha = gl_FrontMaterial.diffuse.a; else alpha = gl_Color.a; + // Another hack for supporting two-sided lighting without using + // gl_FrontFacing in the fragment shader. + if (twoSideHack) { + gl_FrontColor = vec4(0.0, 0.0, 0.0, 1.0); + gl_BackColor = vec4(0.0, 0.0, 0.0, 0.0); + } constantColor = gl_FrontLightModelProduct.sceneColor + gl_FrontMaterial.ambient * gl_LightSource[0].ambient; fogCoord = abs(ecPosition3.z); diff --git a/Shaders/terrain-default.frag b/Shaders/terrain-default.frag index bd8a59964..ba189d8dd 100644 --- a/Shaders/terrain-default.frag +++ b/Shaders/terrain-default.frag @@ -22,8 +22,6 @@ void main() vec4 specular = vec4(0.0); n = normalize(normal); - if (!gl_FrontFacing) - n = -n; NdotL = max(dot(n, lightDir), 0.0); if (NdotL > 0.0) { color += diffuse * NdotL;