From c964caa845812f427f8d462ebf36737aa6339551 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore33@gmail.com> 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 @@ <texture n ="0"> <type>white</type> </texture> + <vertex-program-two-side type="bool">false</vertex-program-two-side> </parameters> <technique n="10"> <predicate> @@ -60,14 +61,23 @@ </internal-format> --> </texture-unit> + <vertex-program-two-side> + <use>vertex-program-two-side</use> + </vertex-program-two-side> <program> <vertex-shader>Shaders/model-default.vert</vertex-shader> - <fragment-shader>Shaders/default.frag</fragment-shader> + <fragment-shader>Shaders/model-default.frag</fragment-shader> </program> <uniform> - <name>texture</name> - <type>sampler-2d</type> - <value type="int">0</value></uniform> + <name>texture</name> + <type>sampler-2d</type> + <value type="int">0</value> + </uniform> + <uniform> + <name>twoSideHack</name> + <type>bool</type> + <value><use>vertex-program-two-side</use></value> + </uniform> </pass> </technique> <technique n="11"> @@ -106,6 +116,10 @@ <mode>modulate</mode> </environment> </texture-unit> + <!-- A two-sided lighting model is set by default near the root + of the scene graph. Perhaps that ought to be set in this + effect? + --> </pass> </technique> </PropertyList> 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;