From 76a11c2d48a7dcfd81e25f0b4f8b939af4242d52 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Sun, 29 Apr 2012 13:35:30 +0200 Subject: [PATCH] Fix bug #750: allow cards or drivers not supporting dynamic indexing in fragment shaders to have simple shadows --- Effects/sunlight.eff | 120 +++++++++++++++++++++++++++++++-- Shaders/sunlight-noshadow.frag | 12 ++-- Shaders/sunlight-simple.frag | 74 ++++++++++++++++++++ Shaders/sunlight-simple.vert | 19 ++++++ 4 files changed, 210 insertions(+), 15 deletions(-) create mode 100644 Shaders/sunlight-simple.frag create mode 100644 Shaders/sunlight-simple.vert diff --git a/Effects/sunlight.eff b/Effects/sunlight.eff index 4a12ce705..1717de1ce 100644 --- a/Effects/sunlight.eff +++ b/Effects/sunlight.eff @@ -4,14 +4,26 @@ /sim/rendering/shadows/filtering - + /sim/rendering/shadows/enabled - - 1.0 - /sim/rendering/shadows/filtering - + + + 2.0 + /sim/rendering/shadows/filtering + + + + 1.0 + /sim/rendering/shadows/filtering + + + 1.0 + /sim/rendering/shadows/num-cascades + + + @@ -96,9 +108,16 @@ --> - + - /sim/rendering/shadows/enabled + + /sim/rendering/shadows/enabled + + + 1.0 + /sim/rendering/shadows/num-cascades + + false @@ -177,6 +196,92 @@ --> + + + /sim/rendering/shadows/enabled + + + false + + false + + + one + one + + + 1 + RenderBin + + + 0 + depth-buffer + + + 1 + normal-buffer + + + 2 + diffuse-buffer + + + 3 + spec-emis-buffer + + + 4 + shadow-buffer + + + Shaders/sunlight-simple.vert + Shaders/sunlight-simple.frag + Shaders/gbuffer-functions.frag + + + depth_tex + sampler-2d + 0 + + + normal_tex + sampler-2d + 1 + + + color_tex + sampler-2d + 2 + + + spec_emis_tex + sampler-2d + 3 + + + shadow_tex + sampler-2d + 4 + + + filtering + int + filtering + + + + false @@ -210,6 +315,7 @@ Shaders/sunlight.vert Shaders/sunlight-noshadow.frag + Shaders/gbuffer-functions.frag depth_tex diff --git a/Shaders/sunlight-noshadow.frag b/Shaders/sunlight-noshadow.frag index 79f5ea664..5e4abf0f2 100644 --- a/Shaders/sunlight-noshadow.frag +++ b/Shaders/sunlight-noshadow.frag @@ -8,23 +8,19 @@ uniform vec4 fg_SunSpecularColor; uniform vec3 fg_SunDirection; uniform vec3 fg_Planes; varying vec3 ray; + +vec3 normal_decode(vec2 enc); + void main() { vec2 coords = gl_TexCoord[0].xy; vec4 spec_emis = texture2D( spec_emis_tex, coords ); if ( spec_emis.a < 0.1 ) discard; - vec3 normal; - normal.xy = texture2D( normal_tex, coords ).rg * 2.0 - vec2(1.0,1.0); - normal.z = sqrt( 1.0 - dot( normal.xy, normal.xy ) ); + vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg); float len = length(normal); normal /= len; vec3 viewDir = normalize(ray); - float depth = texture2D( depth_tex, coords ).r; - vec3 pos; - pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z); - pos.xy = viewDir.xy / viewDir.z * pos.z; - vec4 tint; vec3 lightDir = (fg_ViewMatrix * vec4( fg_SunDirection, 0.0 )).xyz; lightDir = normalize( lightDir ); vec3 color = texture2D( color_tex, coords ).rgb; diff --git a/Shaders/sunlight-simple.frag b/Shaders/sunlight-simple.frag new file mode 100644 index 000000000..4a354c02b --- /dev/null +++ b/Shaders/sunlight-simple.frag @@ -0,0 +1,74 @@ +uniform mat4 fg_ViewMatrix; +uniform sampler2D depth_tex; +uniform sampler2D normal_tex; +uniform sampler2D color_tex; +uniform sampler2D spec_emis_tex; +uniform sampler2DShadow shadow_tex; +uniform vec4 fg_SunDiffuseColor; +uniform vec4 fg_SunSpecularColor; +uniform vec3 fg_SunDirection; +uniform vec3 fg_Planes; +uniform vec4 fg_ShadowDistances; +uniform int filtering; + +varying vec3 ray; +varying vec4 eyePlaneS; +varying vec4 eyePlaneT; +varying vec4 eyePlaneR; +varying vec4 eyePlaneQ; + +vec3 position( vec3 viewdir, float depth ); +vec3 normal_decode(vec2 enc); + +vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint ) +{ + vec4 coords; + if (ecPosition.z > -fg_ShadowDistances.x) { + tint = vec4(0.0,1.0,0.0,1.0); + coords.s = dot( ecPosition, eyePlaneS ); + coords.t = dot( ecPosition, eyePlaneT ); + coords.p = dot( ecPosition, eyePlaneR ); + coords.q = dot( ecPosition, eyePlaneQ ); + } else { + return vec4(1.1,1.1,0.0,1.0); // outside, clamp to border + } + return coords; +} +void main() { + vec2 coords = gl_TexCoord[0].xy; + vec4 spec_emis = texture2D( spec_emis_tex, coords ); + if ( spec_emis.a < 0.1 ) + discard; + vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg); + float len = length(normal); + normal /= len; + vec3 viewDir = normalize(ray); + vec3 pos = position( viewDir, texture2D( depth_tex, coords ).r ); + + vec4 tint; + float shadow; + if (filtering == 2) { + shadow += 0.333 * shadow2DProj( shadow_tex, DynamicShadow( vec4(pos, 1.0), tint ) ).r; + shadow += 0.166 * shadow2DProj( shadow_tex, DynamicShadow( vec4(pos + vec3(-0.003 * pos.z, -0.002 * pos.z, 0), 1.0), tint ) ).r; + shadow += 0.166 * shadow2DProj( shadow_tex, DynamicShadow( vec4(pos + vec3( 0.003 * pos.z, 0.002 * pos.z, 0), 1.0), tint ) ).r; + shadow += 0.166 * shadow2DProj( shadow_tex, DynamicShadow( vec4(pos + vec3(-0.003 * pos.z, 0.002 * pos.z, 0), 1.0), tint ) ).r; + shadow += 0.166 * shadow2DProj( shadow_tex, DynamicShadow( vec4(pos + vec3( 0.003 * pos.z, -0.002 * pos.z, 0), 1.0), tint ) ).r; + } else { + shadow = shadow2DProj( shadow_tex, DynamicShadow( vec4( pos, 1.0 ), tint ) ).r; + } + + vec3 lightDir = (fg_ViewMatrix * vec4( fg_SunDirection, 0.0 )).xyz; + lightDir = normalize( lightDir ); + vec3 color = texture2D( color_tex, coords ).rgb; + vec3 Idiff = clamp( dot( lightDir, normal ), 0.0, 1.0 ) * color * fg_SunDiffuseColor.rgb; + vec3 halfDir = lightDir - viewDir; + len = length( halfDir ); + vec3 Ispec = vec3(0.0); + vec3 Iemis = spec_emis.z * color; + if (len > 0.0001) { + halfDir /= len; + Ispec = pow( clamp( dot( halfDir, normal ), 0.0, 1.0 ), spec_emis.y * 128.0 ) * spec_emis.x * fg_SunSpecularColor.rgb; + } + gl_FragColor = vec4(mix(vec3(0.0), Idiff + Ispec, shadow) + Iemis, 1.0); +// gl_FragColor = mix(tint, vec4(mix(vec3(0.0), Idiff + Ispec, shadow) + Iemis, 1.0), 0.92); +} diff --git a/Shaders/sunlight-simple.vert b/Shaders/sunlight-simple.vert new file mode 100644 index 000000000..7e382596a --- /dev/null +++ b/Shaders/sunlight-simple.vert @@ -0,0 +1,19 @@ +//uniform mat4 fg_ViewMatrixInverse; +uniform mat4 fg_ProjectionMatrixInverse; +varying vec3 ray; +varying vec4 eyePlaneS; +varying vec4 eyePlaneT; +varying vec4 eyePlaneR; +varying vec4 eyePlaneQ; + +void main() { + gl_Position = gl_Vertex; + gl_TexCoord[0] = gl_MultiTexCoord0; +// ray = (fg_ViewMatrixInverse * vec4((fg_ProjectionMatrixInverse * gl_Vertex).xyz, 0.0)).xyz; + ray = (fg_ProjectionMatrixInverse * gl_Vertex).xyz; + + eyePlaneS = gl_EyePlaneS[1]; + eyePlaneT = gl_EyePlaneT[1]; + eyePlaneR = gl_EyePlaneR[1]; + eyePlaneQ = gl_EyePlaneQ[1]; +}