//this shader is a light shader. ideally drawn with a quad covering the entire region //the output is contribution from this light (which will be additively blended) //you can blame Electro for much of the maths in here. !!ver 100 450 //FIXME: !!permu FOG !!samps shadowmap 2 #define USE_ARB_SHADOW #include "sys/defs.h" #include "sys/pcf.h" //s_t0 is the depth //s_t1 is the normals+spec-exponent //output should be amount of light hitting the surface. varying vec4 tf; #ifdef VERTEX_SHADER void main() { tf = ftetransform(); gl_Position = tf; } #endif #ifdef FRAGMENT_SHADER #define out_diff fte_fragdata0 #define out_spec fte_fragdata1 vec3 calcLightWorldPos(vec2 screenPos, float depth) { vec4 pos = m_invviewprojection * vec4(screenPos.xy, (depth*2.0)-1.0, 1.0); return pos.xyz / pos.w; } void main () { vec3 lightColour = l_lightcolour.rgb; vec2 fc = tf.xy / tf.w; vec2 gc = (1.0 + fc) / 2.0; float depth = texture2D(s_t0, gc).r; vec4 data = texture2D(s_t1, gc); vec3 norm = data.xyz; float spec_exponent = data.a; /* calc where the wall that generated this sample came from */ vec3 worldPos = calcLightWorldPos(fc, depth); /*we need to know the cube projection (for both cubemaps+shadows)*/ vec4 cubeaxis = l_cubematrix*vec4(worldPos.xyz, 1.0); /*calc ambient lighting term*/ vec3 lightDir = l_lightposition - worldPos; float atten = max(1.0 - (dot(lightDir, lightDir)/(l_lightradius*l_lightradius)), 0.0); /*calc diffuse lighting term*/ lightDir = normalize(lightDir); float nDotL = dot(norm, lightDir); float lightDiffuse = max(0.0, nDotL); /*calc specular lighting term*/ vec3 halfdir = normalize(normalize(e_eyepos - worldPos) + lightDir); //ASSUMPTION: e_eyepos requires an identity modelmatrix (true for world+sprites, but usually not for models/bsps) float spec = pow(max(dot(halfdir, norm), 0.0), spec_exponent); //fixme: apply fog? //fixme: cubemap filters float shadows = ShadowmapFilter(s_shadowmap, cubeaxis); lightColour *= atten; out_diff = vec4(lightColour * (l_lightcolourscale.x + l_lightcolourscale.y*lightDiffuse*shadows), 1.0); out_spec = vec4(lightColour * l_lightcolourscale.z*spec*shadows, 1.0); } #endif