52f0f117ab
reworked deferred rendering to support specular. mrt can be reconfigured by TCs if desired. reworked q3bsp deluxemap code (so it no longer bugs out). fixed a few warnings. updated fteqcc to try to cope with xonotic. still not working (xonotic fails from bound checks). reworked shader conditionals to support elif. added some directives from QF(aka: warsow) git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5158 fc73d0e0-1445-4013-8a0c-d673dee63da5
74 lines
2.2 KiB
GLSL
74 lines
2.2 KiB
GLSL
//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
|