diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index bd70465cb..07698f747 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -92,6 +92,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear; protected CompareMode shadowCompareMode = CompareMode.Hardware; protected Picture[] dispPic; + /** * true if the fallback material should be used, otherwise false */ diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md index 0e9e9850b..1ea351f61 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md @@ -225,8 +225,8 @@ MaterialDef Phong Lighting { Technique PostShadow15{ - VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow15.vert - FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow15.frag + VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md index 8dd6fc5ca..0831c3fe5 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md @@ -147,8 +147,8 @@ MaterialDef Unshaded { Technique PostShadow15{ - VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow15.vert - FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow15.frag + VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.frag b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.frag index 4e42c5784..52bc6e9e4 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.frag @@ -1,4 +1,5 @@ #import "Common/ShaderLib/Shadows.glsllib" +#import "Common/ShaderLib/GLSLCompat.glsllib" #if defined(PSSM) || defined(FADE) varying float shadowPosition; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md index af80bdae3..a6e1dfef7 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.j3md @@ -33,8 +33,8 @@ MaterialDef Post Shadow { } Technique { - VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow15.vert - FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow15.frag + VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag WorldParameters { WorldViewProjectionMatrix diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.vert b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.vert index 482231032..e56e10e55 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow.vert @@ -1,5 +1,7 @@ #import "Common/ShaderLib/Instancing.glsllib" #import "Common/ShaderLib/Skinning.glsllib" +#import "Common/ShaderLib/GLSLCompat.glsllib" + uniform mat4 m_LightViewProjectionMatrix0; uniform mat4 m_LightViewProjectionMatrix1; uniform mat4 m_LightViewProjectionMatrix2; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.frag b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.frag deleted file mode 100644 index 2eb9541e5..000000000 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.frag +++ /dev/null @@ -1,80 +0,0 @@ -#import "Common/ShaderLib/Shadows15.glsllib" - -out vec4 outFragColor; - -#if defined(PSSM) || defined(FADE) -in float shadowPosition; -#endif - -in vec4 projCoord0; -in vec4 projCoord1; -in vec4 projCoord2; -in vec4 projCoord3; - -#ifdef POINTLIGHT - in vec4 projCoord4; - in vec4 projCoord5; - in vec4 worldPos; - uniform vec3 m_LightPos; -#else - #ifndef PSSM - in float lightDot; - #endif -#endif - -#ifdef DISCARD_ALPHA - #ifdef COLOR_MAP - uniform sampler2D m_ColorMap; - #else - uniform sampler2D m_DiffuseMap; - #endif - uniform float m_AlphaDiscardThreshold; - varying vec2 texCoord; -#endif - -#ifdef FADE -uniform vec2 m_FadeInfo; -#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 - - float shadow = 1.0; - #ifdef POINTLIGHT - shadow = getPointLightShadows(worldPos, m_LightPos, - m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3,m_ShadowMap4,m_ShadowMap5, - projCoord0, projCoord1, projCoord2, projCoord3, projCoord4, projCoord5); - #else - #ifdef PSSM - shadow = getDirectionalLightShadows(m_Splits, shadowPosition, - m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3, - projCoord0, projCoord1, projCoord2, projCoord3); - #else - //spotlight - if(lightDot < 0){ - outFragColor = vec4(1.0); - return; - } - shadow = getSpotLightShadows(m_ShadowMap0,projCoord0); - #endif - #endif - - #ifdef FADE - shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y)); - #endif - - shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity); - outFragColor = vec4(shadow, shadow, shadow, 1.0); -} - diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.vert b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.vert deleted file mode 100644 index 20565de7c..000000000 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadow15.vert +++ /dev/null @@ -1,82 +0,0 @@ -#import "Common/ShaderLib/Instancing.glsllib" -#import "Common/ShaderLib/Skinning.glsllib" -uniform mat4 m_LightViewProjectionMatrix0; -uniform mat4 m_LightViewProjectionMatrix1; -uniform mat4 m_LightViewProjectionMatrix2; -uniform mat4 m_LightViewProjectionMatrix3; - - -out vec4 projCoord0; -out vec4 projCoord1; -out vec4 projCoord2; -out vec4 projCoord3; - -#ifdef POINTLIGHT - uniform mat4 m_LightViewProjectionMatrix4; - uniform mat4 m_LightViewProjectionMatrix5; - out vec4 projCoord4; - out vec4 projCoord5; - out vec4 worldPos; -#else - #ifndef PSSM - uniform vec3 m_LightPos; - uniform vec3 m_LightDir; - out float lightDot; - #endif -#endif - -#if defined(PSSM) || defined(FADE) - out float shadowPosition; -#endif -out vec3 lightVec; - -out vec2 texCoord; - -in vec3 inPosition; - -#ifdef DISCARD_ALPHA - in vec2 inTexCoord; -#endif - -const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 0.5, 0.0, - 0.5, 0.5, 0.5, 1.0); - - -void main(){ - vec4 modelSpacePos = vec4(inPosition, 1.0); - - #ifdef NUM_BONES - Skinning_Compute(modelSpacePos); - #endif - gl_Position = TransformWorldViewProjection(modelSpacePos); - - #if defined(PSSM) || defined(FADE) - shadowPosition = gl_Position.z; - #endif - - #ifndef POINTLIGHT - vec4 worldPos=vec4(0.0); - #endif - // get the vertex in world space - worldPos = TransformWorld(modelSpacePos); - - #ifdef DISCARD_ALPHA - texCoord = inTexCoord; - #endif - // populate the light view matrices array and convert vertex to light viewProj space - projCoord0 = biasMat * m_LightViewProjectionMatrix0 * worldPos; - projCoord1 = biasMat * m_LightViewProjectionMatrix1 * worldPos; - projCoord2 = biasMat * m_LightViewProjectionMatrix2 * worldPos; - projCoord3 = biasMat * m_LightViewProjectionMatrix3 * worldPos; - #ifdef POINTLIGHT - projCoord4 = biasMat * m_LightViewProjectionMatrix4 * worldPos; - projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos; - #else - #ifndef PSSM - vec3 lightDir = worldPos.xyz - m_LightPos; - lightDot = dot(m_LightDir,lightDir); - #endif - #endif -} \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter15.frag b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter15.frag index b8dcff90f..d19e9aef4 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter15.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Shadow/PostShadowFilter15.frag @@ -1,5 +1,5 @@ #import "Common/ShaderLib/MultiSample.glsllib" -#import "Common/ShaderLib/Shadows15.glsllib" +#import "Common/ShaderLib/Shadows.glsllib" uniform COLORTEXTURE m_Texture; diff --git a/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib index d2f1a942b..9934db637 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/Shadows.glsllib @@ -1,22 +1,57 @@ -#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 __VERSION__ >= 130 + // Because gpu_shader5 is actually where those + // gather functions are declared to work on shadowmaps + #extension GL_ARB_gpu_shader5 : enable + #define IVEC2 ivec2 + #ifdef HARDWARE_SHADOWS + #define SHADOWMAP sampler2DShadow + #define SHADOWCOMPAREOFFSET(tex,coord,offset) textureProjOffset(tex, coord, offset) + #define SHADOWCOMPARE(tex,coord) textureProj(tex, coord) + #define SHADOWGATHER(tex,coord) textureGather(tex, coord.xy, coord.z) + #else + #define SHADOWMAP sampler2D + #define SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z, textureProjOffset(tex, coord, offset).r) + #define SHADOWCOMPARE(tex,coord) step(coord.z, textureProj(tex, coord).r) + #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy)) + #endif -#if FILTER_MODE == 0 - #define GETSHADOW Shadow_DoShadowCompare - #define KERNEL 1.0 -#elif FILTER_MODE == 1 + #if FILTER_MODE == 0 + #define GETSHADOW Shadow_Nearest + #define KERNEL 1.0 + #elif FILTER_MODE == 1 + #ifdef HARDWARE_SHADOWS + #define GETSHADOW Shadow_Nearest + #else + #define GETSHADOW Shadow_DoBilinear_2x2 + #endif + #define KERNEL 1.0 + #endif +#else + #define IVEC2 vec2 #ifdef HARDWARE_SHADOWS - #define GETSHADOW Shadow_DoShadowCompare + #define SHADOWMAP sampler2DShadow + #define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r #else - #define GETSHADOW Shadow_DoBilinear_2x2 + #define SHADOWMAP sampler2D + #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r) #endif - #define KERNEL 1.0 -#elif FILTER_MODE == 2 + + #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 + #endif + + +#endif + +#if FILTER_MODE == 2 #define GETSHADOW Shadow_DoDither_2x2 #define KERNEL 1.0 #elif FILTER_MODE == 3 @@ -30,14 +65,13 @@ #define KERNEL 8.0 #endif - uniform SHADOWMAP m_ShadowMap0; uniform SHADOWMAP m_ShadowMap1; uniform SHADOWMAP m_ShadowMap2; uniform SHADOWMAP m_ShadowMap3; #ifdef POINTLIGHT -uniform SHADOWMAP m_ShadowMap4; -uniform SHADOWMAP m_ShadowMap5; + uniform SHADOWMAP m_ShadowMap4; + uniform SHADOWMAP m_ShadowMap5; #endif #ifdef PSSM @@ -49,73 +83,91 @@ uniform float m_ShadowIntensity; const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE); float shadowBorderScale = 1.0; -float Shadow_DoShadowCompareOffset(SHADOWMAP tex, vec4 projCoord, vec2 offset){ - vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2 * shadowBorderScale, projCoord.zw); - return SHADOWCOMPARE(tex, coord); -} - -float Shadow_DoShadowCompare(SHADOWMAP tex, vec4 projCoord){ +float Shadow_DoShadowCompare(in SHADOWMAP tex,in vec4 projCoord){ return SHADOWCOMPARE(tex, projCoord); } -float Shadow_BorderCheck(vec2 coord){ +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_Nearest(SHADOWMAP tex, vec4 projCoord){ +float Shadow_Nearest(in SHADOWMAP tex,in vec4 projCoord){ float border = Shadow_BorderCheck(projCoord.xy); if (border > 0.0){ return 1.0; } - return Shadow_DoShadowCompare(tex,projCoord); + return SHADOWCOMPARE(tex, projCoord); +} + +float Shadow_DoShadowCompareOffset(in SHADOWMAP tex,in vec4 projCoord,in vec2 offset){ + vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2 * shadowBorderScale, projCoord.zw); + return SHADOWCOMPARE(tex, coord); } -float Shadow_DoDither_2x2(SHADOWMAP tex, vec4 projCoord){ + +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 ; + IVEC2 o = IVEC2(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(SHADOWMAP tex, vec4 projCoord){ +float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){ float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) + 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 * SHADOWMAP_SIZE ); - vec2 mx = mix( gather.xz, gather.yw, f.x ); - return mix( mx.x, mx.y, f.y ); + #if __VERSION__ >= 130 + #ifdef GL_ARB_gpu_shader5 + vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0); + gather = SHADOWGATHER(tex, coord); + #else + gather.x = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1)); + gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1)); + gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0)); + gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 0)); + #endif + #else + 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)); + #endif + + vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE ); + vec2 mx = mix( gather.wx, gather.zy, f.x ); + return mix( mx.x, mx.y, f.y ); } -float Shadow_DoPCF(SHADOWMAP tex, vec4 projCoord){ +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); + #if __VERSION__ < 130 + shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) + border, 0.0, 1.0); + #else + shadow += Shadow_DoShadowCompareOffset(tex, projCoord, vec2(x,y)); + #endif } } @@ -123,51 +175,51 @@ float Shadow_DoPCF(SHADOWMAP tex, vec4 projCoord){ return shadow; } - //12 tap poisson disk - const vec2 poissonDisk0 = vec2(-0.1711046, -0.425016); - const vec2 poissonDisk1 = vec2(-0.7829809, 0.2162201); - const vec2 poissonDisk2 = vec2(-0.2380269, -0.8835521); - const vec2 poissonDisk3 = vec2(0.4198045, 0.1687819); - const vec2 poissonDisk4 = vec2(-0.684418, -0.3186957); - const vec2 poissonDisk5 = vec2(0.6026866, -0.2587841); - const vec2 poissonDisk6 = vec2(-0.2412762, 0.3913516); - const vec2 poissonDisk7 = vec2(0.4720655, -0.7664126); - const vec2 poissonDisk8 = vec2(0.9571564, 0.2680693); - const vec2 poissonDisk9 = vec2(-0.5238616, 0.802707); - const vec2 poissonDisk10 = vec2(0.5653144, 0.60262); - const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419); - -float Shadow_DoPCFPoisson(SHADOWMAP tex, vec4 projCoord){ +const vec2 poissonDisk0 = vec2(-0.1711046, -0.425016); +const vec2 poissonDisk1 = vec2(-0.7829809, 0.2162201); +const vec2 poissonDisk2 = vec2(-0.2380269, -0.8835521); +const vec2 poissonDisk3 = vec2(0.4198045, 0.1687819); +const vec2 poissonDisk4 = vec2(-0.684418, -0.3186957); +const vec2 poissonDisk5 = vec2(0.6026866, -0.2587841); +const vec2 poissonDisk6 = vec2(-0.2412762, 0.3913516); +const vec2 poissonDisk7 = vec2(0.4720655, -0.7664126); +const vec2 poissonDisk8 = vec2(0.9571564, 0.2680693); +const vec2 poissonDisk9 = vec2(-0.5238616, 0.802707); +const vec2 poissonDisk10 = vec2(0.5653144, 0.60262); +const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419); + + +float Shadow_DoPCFPoisson(in SHADOWMAP tex, in vec4 projCoord){ float shadow = 0.0; float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) + if (border > 0.0){ return 1.0; + } - vec2 texelSize = vec2( 4.0 * PCFEDGE * shadowBorderScale); - - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk0 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk1 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk2 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk3 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk4 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk5 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk6 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk7 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk8 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk9 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk10 * texelSize); - shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk11 * texelSize); - - shadow = shadow * 0.08333333333;//this is divided by 12 - return shadow; -} + vec2 texelSize = pixSize2 * 4.0 * PCFEDGE * shadowBorderScale; + + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk0 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk1 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk2 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk3 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk4 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk5 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk6 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk7 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk8 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk9 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk10 * texelSize, projCoord.zw)); + shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk11 * texelSize, projCoord.zw)); + //this is divided by 12 + return shadow * 0.08333333333; +} -#ifdef POINTLIGHT - float getPointLightShadows(vec4 worldPos,vec3 lightPos, - SHADOWMAP shadowMap0,SHADOWMAP shadowMap1,SHADOWMAP shadowMap2,SHADOWMAP shadowMap3,SHADOWMAP shadowMap4,SHADOWMAP shadowMap5, - vec4 projCoord0,vec4 projCoord1,vec4 projCoord2,vec4 projCoord3,vec4 projCoord4,vec4 projCoord5){ +#ifdef POINTLIGHT + float getPointLightShadows(in vec4 worldPos,in vec3 lightPos, + in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3,in SHADOWMAP shadowMap4,in SHADOWMAP shadowMap5, + in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3,in vec4 projCoord4,in vec4 projCoord5){ float shadow = 1.0; vec3 vect = worldPos.xyz - lightPos; vec3 absv= abs(vect); @@ -190,42 +242,41 @@ float Shadow_DoPCFPoisson(SHADOWMAP tex, vec4 projCoord){ }else{ shadow = GETSHADOW(shadowMap5, projCoord5 / projCoord5.w); } - } + } return shadow; } #else #ifdef PSSM - float getDirectionalLightShadows(vec4 splits,float shadowPosition, - SHADOWMAP shadowMap0,SHADOWMAP shadowMap1,SHADOWMAP shadowMap2,SHADOWMAP shadowMap3, - vec4 projCoord0,vec4 projCoord1,vec4 projCoord2,vec4 projCoord3){ - float shadow = 1.0; + float getDirectionalLightShadows(in vec4 splits,in float shadowPosition, + in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3, + in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3){ + float shadow = 1.0; if(shadowPosition < splits.x){ - shadow = GETSHADOW(shadowMap0, projCoord0 ); + shadow = GETSHADOW(shadowMap0, projCoord0 ); }else if( shadowPosition < splits.y){ shadowBorderScale = 0.5; - shadow = GETSHADOW(shadowMap1, projCoord1); + shadow = GETSHADOW(shadowMap1, projCoord1); }else if( shadowPosition < splits.z){ shadowBorderScale = 0.25; - shadow = GETSHADOW(shadowMap2, projCoord2); + shadow = GETSHADOW(shadowMap2, projCoord2); }else if( shadowPosition < splits.w){ shadowBorderScale = 0.125; - shadow = GETSHADOW(shadowMap3, projCoord3); + shadow = GETSHADOW(shadowMap3, projCoord3); } return shadow; } #else - float getSpotLightShadows(SHADOWMAP shadowMap, vec4 projCoord){ - float shadow = 1.0; + float getSpotLightShadows(in SHADOWMAP shadowMap,in vec4 projCoord){ + float shadow = 1.0; projCoord /= projCoord.w; - shadow = GETSHADOW(shadowMap, projCoord); - + shadow = GETSHADOW(shadowMap,projCoord); + //a small falloff to make the shadow blend nicely into the not lighten - //we translate the texture coordinate value to a -1,1 range so the length + //we translate the texture coordinate value to a -1,1 range so the length //of the texture coordinate vector is actually the radius of the lighten area on the ground projCoord = projCoord * 2.0 - 1.0; float fallOff = ( length(projCoord.xy) - 0.9 ) / 0.1; return mix(shadow,1.0,clamp(fallOff,0.0,1.0)); - } #endif #endif diff --git a/jme3-core/src/main/resources/Common/ShaderLib/Shadows15.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/Shadows15.glsllib deleted file mode 100644 index 5c9e0fa1c..000000000 --- a/jme3-core/src/main/resources/Common/ShaderLib/Shadows15.glsllib +++ /dev/null @@ -1,242 +0,0 @@ -// Because gpu_shader5 is actually where those -// gather functions are declared to work on shadowmaps -#extension GL_ARB_gpu_shader5 : enable - -#ifdef HARDWARE_SHADOWS - #define SHADOWMAP sampler2DShadow - #define SHADOWCOMPAREOFFSET(tex,coord,offset) textureProjOffset(tex, coord, offset) - #define SHADOWCOMPARE(tex,coord) textureProj(tex, coord) - #define SHADOWGATHER(tex,coord) textureGather(tex, coord.xy, coord.z) -#else - #define SHADOWMAP sampler2D - #define SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z, textureProjOffset(tex, coord, offset).r) - #define SHADOWCOMPARE(tex,coord) step(coord.z, textureProj(tex, coord).r) - #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy)) -#endif - - -#if FILTER_MODE == 0 - #define GETSHADOW Shadow_Nearest - #define KERNEL 1.0 -#elif FILTER_MODE == 1 - #ifdef HARDWARE_SHADOWS - #define GETSHADOW Shadow_Nearest - #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_DoPCFPoisson - #define KERNEL 4.0 -#elif FILTER_MODE == 5 - #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; -#ifdef POINTLIGHT -uniform SHADOWMAP m_ShadowMap4; -uniform SHADOWMAP m_ShadowMap5; -#endif - -#ifdef PSSM -uniform vec4 m_Splits; -#endif -uniform float m_ShadowIntensity; - -const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE); -float shadowBorderScale = 1.0; - -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_Nearest(in SHADOWMAP tex, in vec4 projCoord){ - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0){ - return 1.0; - } - return SHADOWCOMPARE(tex,projCoord); -} - -float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){ - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0) - return 1.0; - - vec2 pixSize = pixSize2 * shadowBorderScale; - - float shadow = 0.0; - ivec2 o = ivec2(mod(floor(gl_FragCoord.xy), 2.0)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, 1.5)+o), projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, 1.5)+o), projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2(-1.5, -0.5)+o), projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy+pixSize*(vec2( 0.5, -0.5)+o), projCoord.zw)); - 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; - - #ifdef GL_ARB_gpu_shader5 - vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0); - vec4 gather = SHADOWGATHER(tex, coord); - #else - vec4 gather = vec4(0.0); - gather.x = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1)); - gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1)); - gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0)); - gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 0)); - #endif - - vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE ); - vec2 mx = mix( gather.wx, gather.zy, f.x ); - return mix( mx.x, mx.y, f.y ); -} - -float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){ - - vec2 pixSize = pixSize2 * shadowBorderScale; - 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){ - vec4 coord = vec4(projCoord.xy + vec2(x,y) * pixSize, projCoord.zw); - shadow += SHADOWCOMPARE(tex, coord); - } - } - - shadow = shadow / (KERNEL * KERNEL); - return shadow; -} - - -//12 tap poisson disk - const vec2 poissonDisk0 = vec2(-0.1711046, -0.425016); - const vec2 poissonDisk1 = vec2(-0.7829809, 0.2162201); - const vec2 poissonDisk2 = vec2(-0.2380269, -0.8835521); - const vec2 poissonDisk3 = vec2(0.4198045, 0.1687819); - const vec2 poissonDisk4 = vec2(-0.684418, -0.3186957); - const vec2 poissonDisk5 = vec2(0.6026866, -0.2587841); - const vec2 poissonDisk6 = vec2(-0.2412762, 0.3913516); - const vec2 poissonDisk7 = vec2(0.4720655, -0.7664126); - const vec2 poissonDisk8 = vec2(0.9571564, 0.2680693); - const vec2 poissonDisk9 = vec2(-0.5238616, 0.802707); - const vec2 poissonDisk10 = vec2(0.5653144, 0.60262); - const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419); - - -float Shadow_DoPCFPoisson(in SHADOWMAP tex, in vec4 projCoord){ - - float shadow = 0.0; - float border = Shadow_BorderCheck(projCoord.xy); - if (border > 0.0){ - return 1.0; - } - - vec2 texelSize = pixSize2 * 4.0 * PCFEDGE * shadowBorderScale; - - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk0 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk1 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk2 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk3 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk4 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk5 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk6 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk7 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk8 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk9 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk10 * texelSize, projCoord.zw)); - shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk11 * texelSize, projCoord.zw)); - - //this is divided by 12 - return shadow * 0.08333333333; -} - -#ifdef POINTLIGHT - float getPointLightShadows(in vec4 worldPos,in vec3 lightPos, - in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3,in SHADOWMAP shadowMap4,in SHADOWMAP shadowMap5, - in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3,in vec4 projCoord4,in vec4 projCoord5){ - float shadow = 1.0; - vec3 vect = worldPos.xyz - lightPos; - vec3 absv= abs(vect); - float maxComp = max(absv.x,max(absv.y,absv.z)); - if(maxComp == absv.y){ - if(vect.y < 0.0){ - shadow = GETSHADOW(shadowMap0, projCoord0 / projCoord0.w); - }else{ - shadow = GETSHADOW(shadowMap1, projCoord1 / projCoord1.w); - } - }else if(maxComp == absv.z){ - if(vect.z < 0.0){ - shadow = GETSHADOW(shadowMap2, projCoord2 / projCoord2.w); - }else{ - shadow = GETSHADOW(shadowMap3, projCoord3 / projCoord3.w); - } - }else if(maxComp == absv.x){ - if(vect.x < 0.0){ - shadow = GETSHADOW(shadowMap4, projCoord4 / projCoord4.w); - }else{ - shadow = GETSHADOW(shadowMap5, projCoord5 / projCoord5.w); - } - } - return shadow; - } -#else - #ifdef PSSM - float getDirectionalLightShadows(in vec4 splits,in float shadowPosition, - in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3, - in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3){ - float shadow = 1.0; - if(shadowPosition < splits.x){ - shadow = GETSHADOW(shadowMap0, projCoord0 ); - }else if( shadowPosition < splits.y){ - shadowBorderScale = 0.5; - shadow = GETSHADOW(shadowMap1, projCoord1); - }else if( shadowPosition < splits.z){ - shadowBorderScale = 0.25; - shadow = GETSHADOW(shadowMap2, projCoord2); - }else if( shadowPosition < splits.w){ - shadowBorderScale = 0.125; - shadow = GETSHADOW(shadowMap3, projCoord3); - } - return shadow; - } - #else - float getSpotLightShadows(in SHADOWMAP shadowMap,in vec4 projCoord){ - float shadow = 1.0; - projCoord /= projCoord.w; - shadow = GETSHADOW(shadowMap,projCoord); - - //a small falloff to make the shadow blend nicely into the not lighten - //we translate the texture coordinate value to a -1,1 range so the length - //of the texture coordinate vector is actually the radius of the lighten area on the ground - projCoord = projCoord * 2.0 - 1.0; - float fallOff = ( length(projCoord.xy) - 0.9 ) / 0.1; - return mix(shadow,1.0,clamp(fallOff,0.0,1.0)); - - } - #endif -#endif diff --git a/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java b/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java index 0b930bdc5..8df514fd3 100644 --- a/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java +++ b/jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java @@ -132,11 +132,6 @@ public class TestSpotLightShadows extends SimpleApplication { }, "stop"); inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_1)); - - MaterialDebugAppState s = new MaterialDebugAppState(); - s.registerBinding("Common/MatDefs/Shadow/PostShadow15.frag", rootNode); - s.registerBinding(new KeyTrigger(KeyInput.KEY_R), rootNode); - stateManager.attach(s); flyCam.setDragToRotate(true); }