From dc3ee9ad6e1c14d9d98ccbb6770c1ca6d4372d42 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Sat, 31 Mar 2012 20:32:50 +0200 Subject: [PATCH] Supporting effects and shaders for lights --- Effects/light-point.eff | 102 ++++++++++++++++++++++++++++++++ Effects/light-spot.eff | 123 +++++++++++++++++++++++++++++++++++++++ Shaders/light-point.frag | 57 ++++++++++++++++++ Shaders/light-spot.frag | 70 ++++++++++++++++++++++ Shaders/light-spot.vert | 6 ++ 5 files changed, 358 insertions(+) create mode 100644 Effects/light-point.eff create mode 100644 Effects/light-spot.eff create mode 100644 Shaders/light-point.frag create mode 100644 Shaders/light-spot.frag create mode 100644 Shaders/light-spot.vert diff --git a/Effects/light-point.eff b/Effects/light-point.eff new file mode 100644 index 000000000..332925f61 --- /dev/null +++ b/Effects/light-point.eff @@ -0,0 +1,102 @@ + + + Effects/light-point + + + + + false + false + + front + + 2 + RenderBin + + + one + one + + + 0 + depth-buffer + + + 1 + normal-buffer + + + 2 + diffuse-buffer + + + 3 + spec-emis-buffer + + + Shaders/light-spot.vert + Shaders/light-point.frag + + attenuation + 12 + + + + depth_tex + sampler-2d + 0 + + + normal_tex + sampler-2d + 1 + + + color_tex + sampler-2d + 2 + + + spec_emis_tex + sampler-2d + 3 + + + LightPosition + float-vec4 + light-spot/position + true + + + Ambient + float-vec4 + light-spot/ambient + + + Diffuse + float-vec4 + light-spot/diffuse + + + Specular + float-vec4 + light-spot/specular + + + Attenuation + float-vec3 + light-spot/attenuation + + + Near + float + light-spot/near + + + Far + float + light-spot/far + + + + diff --git a/Effects/light-spot.eff b/Effects/light-spot.eff new file mode 100644 index 000000000..b2501f980 --- /dev/null +++ b/Effects/light-spot.eff @@ -0,0 +1,123 @@ + + + Effects/light-spot + + + + + false + false + + front + + 2 + RenderBin + + + one + one + + + 0 + depth-buffer + + + 1 + normal-buffer + + + 2 + diffuse-buffer + + + 3 + spec-emis-buffer + + + Shaders/light-spot.vert + Shaders/light-spot.frag + + attenuation + 12 + + + + depth_tex + sampler-2d + 0 + + + normal_tex + sampler-2d + 1 + + + color_tex + sampler-2d + 2 + + + spec_emis_tex + sampler-2d + 3 + + + LightPosition + float-vec4 + light-spot/position + true + + + LightDirection + float-vec4 + light-spot/direction + true + + + Ambient + float-vec4 + light-spot/ambient + + + Diffuse + float-vec4 + light-spot/diffuse + + + Specular + float-vec4 + light-spot/specular + + + Attenuation + float-vec3 + light-spot/attenuation + + + Exponent + float + light-spot/exponent + + + Cutoff + float + light-spot/cutoff + + + CosCutoff + float + light-spot/cosCutoff + + + Near + float + light-spot/near + + + Far + float + light-spot/far + + + + diff --git a/Shaders/light-point.frag b/Shaders/light-point.frag new file mode 100644 index 000000000..b5d6915e3 --- /dev/null +++ b/Shaders/light-point.frag @@ -0,0 +1,57 @@ +uniform vec2 fg_BufferSize; +uniform vec3 fg_Planes; + +uniform sampler2D depth_tex; +uniform sampler2D normal_tex; +uniform sampler2D color_tex; +uniform sampler2D spec_emis_tex; +uniform vec4 LightPosition; +uniform vec4 Ambient; +uniform vec4 Diffuse; +uniform vec4 Specular; +uniform vec3 Attenuation; +uniform float Near; +uniform float Far; + +varying vec4 ecPosition; + +void main() { + vec3 ray = ecPosition.xyz / ecPosition.w; + vec3 ecPos3 = ray; + vec3 viewDir = normalize(ray); + vec2 coords = gl_FragCoord.xy / fg_BufferSize; + + float depth = texture2D( depth_tex, coords ).r; + vec3 normal; + normal.xy = texture2D( normal_tex, coords ).rg * 2.0 - vec2(1.0,1.0); + normal.z = sqrt( 1 - dot( normal.xy, normal.xy ) ); + vec4 spec_emis = texture2D( spec_emis_tex, coords ); + + vec3 pos; + pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z); + pos.xy = viewDir.xy * pos.z / viewDir.z; + + if ( pos.z < ecPos3.z ) // Negative direction in z + discard; // Don't light surface outside the light volume + + vec3 VP = LightPosition.xyz - pos; + if ( dot( VP, VP ) > ( Far * Far ) ) + discard; // Don't light surface outside the light volume + + float d = length( VP ); + VP /= d; + + vec3 halfVector = normalize(VP - viewDir); + + float att = 1.0 / (Attenuation.x + Attenuation.y * d + Attenuation.z *d*d); + + float nDotVP = max(0.0, dot(normal, VP)); + float nDotHV = max(0.0, dot(normal, halfVector)); + + vec4 color = texture2D( color_tex, coords ); + vec4 Iamb = Ambient * color * att; + vec4 Idiff = Diffuse * color * att * nDotVP; + vec3 Ispec = pow( nDotHV, spec_emis.y ) * spec_emis.x * att * Specular.rgb; + + gl_FragColor = vec4(Iamb.rgb + Idiff.rgb + Ispec, 1.0); +} diff --git a/Shaders/light-spot.frag b/Shaders/light-spot.frag new file mode 100644 index 000000000..f6e9f593f --- /dev/null +++ b/Shaders/light-spot.frag @@ -0,0 +1,70 @@ +uniform vec2 fg_BufferSize; +uniform vec3 fg_Planes; + +uniform sampler2D depth_tex; +uniform sampler2D normal_tex; +uniform sampler2D color_tex; +uniform sampler2D spec_emis_tex; +uniform vec4 LightPosition; +uniform vec4 LightDirection; +uniform vec4 Ambient; +uniform vec4 Diffuse; +uniform vec4 Specular; +uniform vec3 Attenuation; +uniform float Exponent; +uniform float Cutoff; +uniform float CosCutoff; +uniform float Near; +uniform float Far; + +varying vec4 ecPosition; + +void main() { + vec3 ray = ecPosition.xyz / ecPosition.w; + vec3 ecPos3 = ray; + vec3 viewDir = normalize(ray); + vec2 coords = gl_FragCoord.xy / fg_BufferSize; + + float depth = texture2D( depth_tex, coords ).r; + vec3 normal; + normal.xy = texture2D( normal_tex, coords ).rg * 2.0 - vec2(1.0,1.0); + normal.z = sqrt( 1 - dot( normal.xy, normal.xy ) ); + vec4 spec_emis = texture2D( spec_emis_tex, coords ); + + vec3 pos; + pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z); + pos.xy = viewDir.xy * pos.z / viewDir.z; + + if ( pos.z < ecPos3.z ) // Negative direction in z + discard; // Don't light surface outside the light volume + + vec3 VP = LightPosition.xyz - pos; + if ( dot( VP, VP ) > ( Far * Far ) ) + discard; // Don't light surface outside the light volume + + float d = length( VP ); + VP /= d; + + vec3 halfVector = normalize(VP - viewDir); + + float att = 1.0 / (Attenuation.x + Attenuation.y * d + Attenuation.z *d*d); + float spotDot = dot(-VP, normalize(LightDirection.xyz)); + + float spotAttenuation = 0.0; + if (spotDot < CosCutoff) + spotAttenuation = 0.0; + else + spotAttenuation = pow(spotDot, Exponent); + att *= spotAttenuation; + + float nDotVP = max(0.0, dot(normal, VP)); + float nDotHV = max(0.0, dot(normal, halfVector)); + + vec4 color = texture2D( color_tex, coords ); + vec4 Iamb = Ambient * color * att; + vec4 Idiff = Diffuse * color * att * nDotVP; + vec3 Ispec = pow( nDotHV, spec_emis.y ) * spec_emis.x * att * Specular.rgb; + vec3 Ispec = 0.0; + + gl_FragColor = vec4(Iamb.rgb + Idiff.rgb + Ispec, 1.0); +} diff --git a/Shaders/light-spot.vert b/Shaders/light-spot.vert new file mode 100644 index 000000000..1e8243a55 --- /dev/null +++ b/Shaders/light-spot.vert @@ -0,0 +1,6 @@ +varying vec4 ecPosition; + +void main() { + ecPosition = gl_ModelViewMatrix * gl_Vertex; + gl_Position = ftransform(); +}