diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag index cb6a6a5ff..fd989c60f 100644 --- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag +++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag @@ -1,159 +1,159 @@ -#ifdef HARDWARE_SHADOWS - #define SHADOWMAP sampler2DShadow - #define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r -#else - #define SHADOWMAP sampler2D - #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r) -#endif - -#if FILTER_MODE == 0 - #define GETSHADOW Shadow_DoShadowCompare - #define KERNEL 1.0 -#elif FILTER_MODE == 1 - #ifdef HARDWARE_SHADOWS - #define GETSHADOW Shadow_DoShadowCompare - #else - #define GETSHADOW Shadow_DoBilinear_2x2 - #endif - #define KERNEL 1.0 -#elif FILTER_MODE == 2 - #define GETSHADOW Shadow_DoDither_2x2 - #define KERNEL 1.0 -#elif FILTER_MODE == 3 - #define GETSHADOW Shadow_DoPCF - #define KERNEL 4.0 -#elif FILTER_MODE == 4 - #define GETSHADOW Shadow_DoPCF - #define KERNEL 8.0 -#endif - - -uniform SHADOWMAP m_ShadowMap0; -uniform SHADOWMAP m_ShadowMap1; -uniform SHADOWMAP m_ShadowMap2; -uniform SHADOWMAP m_ShadowMap3; - -uniform vec4 m_Splits; - -uniform float m_ShadowIntensity; - -varying vec4 projCoord0; -varying vec4 projCoord1; -varying vec4 projCoord2; -varying vec4 projCoord3; - -varying float shadowPosition; - -float texSize = 1024.0; -const float pixSize = 1.0 / texSize; -const vec2 pixSize2 = vec2(pixSize); - -float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, in vec4 projCoord, in vec2 offset){ - vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2, projCoord.zw); - return SHADOWCOMPARE(tex, coord); -} - -float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){ - return SHADOWCOMPARE(tex, projCoord); -} - -float Shadow_BorderCheck(in vec2 coord){ - // Fastest, "hack" method (uses 4-5 instructions) - vec4 t = vec4(coord.xy, 0.0, 1.0); - t = step(t.wwxy, t.xyzz); - return dot(t,t); -} - -float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){ - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) - return 1.0; - - - float shadow = 0.0; - vec2 o = mod(floor(gl_FragCoord.xy), 2.0); - shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o); - shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, 1.5) + o); - shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, -0.5) + o); - shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, -0.5) + o); - shadow *= 0.25 ; - return shadow; -} - -float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){ - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) - return 1.0; - vec4 gather = vec4(0.0); - gather.x = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 0.0)); - gather.y = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 0.0)); - gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0)); - gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0)); - - vec2 f = fract( projCoord.xy * texSize ); - vec2 mx = mix( gather.xz, gather.yw, f.x ); - return mix( mx.x, mx.y, f.y ); -} - -float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){ - float shadow = 0.0; - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) - return 1.0; - float bound = KERNEL * 0.5 - 0.5; - bound *= PCFEDGE; - for (float y = -bound; y <= bound; y += PCFEDGE){ - for (float x = -bound; x <= bound; x += PCFEDGE){ - shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) + - border, - 0.0, 1.0); - } - } - - shadow = shadow / (KERNEL * KERNEL); - return shadow; -} - -#ifdef DISCARD_ALPHA - #ifdef COLOR_MAP - uniform sampler2D m_ColorMap; - #else - uniform sampler2D m_DiffuseMap; - #endif - uniform float m_AlphaDiscardThreshold; - varying vec2 texCoord; -#endif - -void main(){ - - #ifdef DISCARD_ALPHA - #ifdef COLOR_MAP - float alpha = texture2D(m_ColorMap,texCoord).a; - #else - float alpha = texture2D(m_DiffuseMap,texCoord).a; - #endif - if(alpha<=m_AlphaDiscardThreshold){ - discard; - } - - #endif - - - vec4 shadowPerSplit = vec4(0.0); - shadowPerSplit.x = GETSHADOW(m_ShadowMap0, projCoord0); - shadowPerSplit.y = GETSHADOW(m_ShadowMap1, projCoord1); - shadowPerSplit.z = GETSHADOW(m_ShadowMap2, projCoord2); - shadowPerSplit.w = GETSHADOW(m_ShadowMap3, projCoord3); - - - vec4 less = step( shadowPosition, m_Splits ); - vec4 more = vec4(1.0) - step( shadowPosition, vec4(0.0, m_Splits.xyz) ); - float shadow = dot(shadowPerSplit, less * more ); - - shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity); - - - gl_FragColor = vec4(shadow, shadow, shadow, 1.0); - //gl_FragColor = vec4(alpha, alpha, alpha, 1.0); -} - +#ifdef HARDWARE_SHADOWS + #define SHADOWMAP sampler2DShadow + #define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r +#else + #define SHADOWMAP sampler2D + #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r) +#endif + +#if FILTER_MODE == 0 + #define GETSHADOW Shadow_DoShadowCompare + #define KERNEL 1.0 +#elif FILTER_MODE == 1 + #ifdef HARDWARE_SHADOWS + #define GETSHADOW Shadow_DoShadowCompare + #else + #define GETSHADOW Shadow_DoBilinear_2x2 + #endif + #define KERNEL 1.0 +#elif FILTER_MODE == 2 + #define GETSHADOW Shadow_DoDither_2x2 + #define KERNEL 1.0 +#elif FILTER_MODE == 3 + #define GETSHADOW Shadow_DoPCF + #define KERNEL 4.0 +#elif FILTER_MODE == 4 + #define GETSHADOW Shadow_DoPCF + #define KERNEL 8.0 +#endif + + +uniform SHADOWMAP m_ShadowMap0; +uniform SHADOWMAP m_ShadowMap1; +uniform SHADOWMAP m_ShadowMap2; +uniform SHADOWMAP m_ShadowMap3; + +uniform vec4 m_Splits; + +uniform float m_ShadowIntensity; + +varying vec4 projCoord0; +varying vec4 projCoord1; +varying vec4 projCoord2; +varying vec4 projCoord3; + +varying float shadowPosition; + +const float texSize = 1024.0; +const float pixSize = 1.0 / texSize; +const vec2 pixSize2 = vec2(pixSize); + +float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, in vec4 projCoord, in vec2 offset){ + vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2, projCoord.zw); + return SHADOWCOMPARE(tex, coord); +} + +float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){ + return SHADOWCOMPARE(tex, projCoord); +} + +float Shadow_BorderCheck(in vec2 coord){ + // Fastest, "hack" method (uses 4-5 instructions) + vec4 t = vec4(coord.xy, 0.0, 1.0); + t = step(t.wwxy, t.xyzz); + return dot(t,t); +} + +float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){ + float border = Shadow_BorderCheck(projCoord.xy); + if (border > 0.0) + return 1.0; + + + float shadow = 0.0; + vec2 o = mod(floor(gl_FragCoord.xy), 2.0); + shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o); + shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, 1.5) + o); + shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, -0.5) + o); + shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, -0.5) + o); + shadow *= 0.25 ; + return shadow; +} + +float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){ + float border = Shadow_BorderCheck(projCoord.xy); + if (border > 0.0) + return 1.0; + vec4 gather = vec4(0.0); + gather.x = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 0.0)); + gather.y = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 0.0)); + gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0)); + gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0)); + + vec2 f = fract( projCoord.xy * texSize ); + vec2 mx = mix( gather.xz, gather.yw, f.x ); + return mix( mx.x, mx.y, f.y ); +} + +float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){ + float shadow = 0.0; + float border = Shadow_BorderCheck(projCoord.xy); + if (border > 0.0) + return 1.0; + float bound = KERNEL * 0.5 - 0.5; + bound *= PCFEDGE; + for (float y = -bound; y <= bound; y += PCFEDGE){ + for (float x = -bound; x <= bound; x += PCFEDGE){ + shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) + + border, + 0.0, 1.0); + } + } + + shadow = shadow / (KERNEL * KERNEL); + return shadow; +} + +#ifdef DISCARD_ALPHA + #ifdef COLOR_MAP + uniform sampler2D m_ColorMap; + #else + uniform sampler2D m_DiffuseMap; + #endif + uniform float m_AlphaDiscardThreshold; + varying vec2 texCoord; +#endif + +void main(){ + + #ifdef DISCARD_ALPHA + #ifdef COLOR_MAP + float alpha = texture2D(m_ColorMap,texCoord).a; + #else + float alpha = texture2D(m_DiffuseMap,texCoord).a; + #endif + if(alpha<=m_AlphaDiscardThreshold){ + discard; + } + + #endif + + + vec4 shadowPerSplit = vec4(0.0); + shadowPerSplit.x = GETSHADOW(m_ShadowMap0, projCoord0); + shadowPerSplit.y = GETSHADOW(m_ShadowMap1, projCoord1); + shadowPerSplit.z = GETSHADOW(m_ShadowMap2, projCoord2); + shadowPerSplit.w = GETSHADOW(m_ShadowMap3, projCoord3); + + + vec4 less = step( shadowPosition, m_Splits ); + vec4 more = vec4(1.0) - step( shadowPosition, vec4(0.0, m_Splits.xyz) ); + float shadow = dot(shadowPerSplit, less * more ); + + shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity); + + + gl_FragColor = vec4(shadow, shadow, shadow, 1.0); + //gl_FragColor = vec4(alpha, alpha, alpha, 1.0); +} +