2012-05-09 15:30:53 +00:00
//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.
2017-10-31 22:52:58 +00:00
!!ver 100 450
//FIXME: !!permu FOG
!!samps shadowmap 2
2012-05-09 15:30:53 +00:00
2017-10-31 22:52:58 +00:00
#define USE_ARB_SHADOW
#include "sys/defs.h"
#include "sys/pcf.h"
//s_t0 is the depth
//s_t1 is the normals+spec-exponent
2016-11-20 21:05:10 +00:00
//output should be amount of light hitting the surface.
2012-05-09 15:30:53 +00:00
varying vec4 tf;
#ifdef VERTEX_SHADER
void main()
{
tf = ftetransform();
gl_Position = tf;
}
#endif
#ifdef FRAGMENT_SHADER
2016-11-20 21:05:10 +00:00
2017-10-31 22:52:58 +00:00
#define out_diff fte_fragdata0
#define out_spec fte_fragdata1
2016-11-20 21:05:10 +00:00
2012-05-09 15:30:53 +00:00
vec3 calcLightWorldPos(vec2 screenPos, float depth)
{
2016-11-20 21:05:10 +00:00
vec4 pos = m_invviewprojection * vec4(screenPos.xy, (depth*2.0)-1.0, 1.0);
2012-05-09 15:30:53 +00:00
return pos.xyz / pos.w;
}
void main ()
{
vec3 lightColour = l_lightcolour.rgb;
2017-10-31 22:52:58 +00:00
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);
2012-05-09 15:30:53 +00:00
vec3 norm = data.xyz;
2017-10-31 22:52:58 +00:00
float spec_exponent = data.a;
2012-05-09 15:30:53 +00:00
/* calc where the wall that generated this sample came from */
vec3 worldPos = calcLightWorldPos(fc, depth);
2016-11-20 21:05:10 +00:00
/*we need to know the cube projection (for both cubemaps+shadows)*/
vec4 cubeaxis = l_cubematrix*vec4(worldPos.xyz, 1.0);
2017-10-31 22:52:58 +00:00
/*calc ambient lighting term*/
2012-05-09 15:30:53 +00:00
vec3 lightDir = l_lightposition - worldPos;
2017-10-31 22:52:58 +00:00
float atten = max(1.0 - (dot(lightDir, lightDir)/(l_lightradius*l_lightradius)), 0.0);
/*calc diffuse lighting term*/
2012-05-09 15:30:53 +00:00
lightDir = normalize(lightDir);
2016-11-20 21:05:10 +00:00
float nDotL = dot(norm, lightDir);
2017-10-31 22:52:58 +00:00
float lightDiffuse = max(0.0, nDotL);
2016-11-20 21:05:10 +00:00
2017-10-31 22:52:58 +00:00
/*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);
2017-09-20 11:27:13 +00:00
2017-10-31 22:52:58 +00:00
//fixme: apply fog?
2016-11-20 21:05:10 +00:00
//fixme: cubemap filters
2012-05-09 15:30:53 +00:00
2017-10-31 22:52:58 +00:00
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);
2012-05-09 15:30:53 +00:00
}
#endif