diff --git a/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md b/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md
index 23ec35d13..4b9703533 100644
--- a/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md
+++ b/engine/src/core-data/Common/MatDefs/Light/Lighting.j3md
@@ -108,6 +108,9 @@ MaterialDef Phong Lighting {
Texture2D ShadowMap1
Texture2D ShadowMap2
Texture2D ShadowMap3
+ //pointLights
+ Texture2D ShadowMap4
+ Texture2D ShadowMap5
Float ShadowIntensity
Vector4 Splits
@@ -117,6 +120,10 @@ MaterialDef Phong Lighting {
Matrix4 LightViewProjectionMatrix1
Matrix4 LightViewProjectionMatrix2
Matrix4 LightViewProjectionMatrix3
+ //pointLight
+ Matrix4 LightViewProjectionMatrix4
+ Matrix4 LightViewProjectionMatrix5
+ Vector3 LightPos
Float PCFEdge
Float ShadowMapSize
@@ -209,6 +216,8 @@ MaterialDef Phong Lighting {
COLOR_MAP : ColorMap
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
ForcedRenderState {
@@ -235,6 +244,8 @@ MaterialDef Phong Lighting {
COLOR_MAP : ColorMap
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
ForcedRenderState {
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag
index bb2625983..6111f8979 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag
@@ -18,6 +18,12 @@ uniform mat4 m_LightViewProjectionMatrix1;
uniform mat4 m_LightViewProjectionMatrix2;
uniform mat4 m_LightViewProjectionMatrix3;
+#ifdef POINTLIGHT
+ uniform vec3 m_LightPos;
+ uniform mat4 m_LightViewProjectionMatrix4;
+ uniform mat4 m_LightViewProjectionMatrix5;
+#endif
+
#ifdef FADE
uniform vec2 m_FadeInfo;
#endif
@@ -47,23 +53,53 @@ void main(){
vec4 projCoord1 = biasMat * m_LightViewProjectionMatrix1 * worldPos;
vec4 projCoord2 = biasMat * m_LightViewProjectionMatrix2 * worldPos;
vec4 projCoord3 = biasMat * m_LightViewProjectionMatrix3 * worldPos;
+ #ifdef POINTLIGHT
+ vec4 projCoord4 = biasMat * m_LightViewProjectionMatrix4 * worldPos;
+ vec4 projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos;
+ #endif
-
- float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x + m_ViewProjectionMatrixRow2.y * worldPos.y + m_ViewProjectionMatrixRow2.z * worldPos.z + m_ViewProjectionMatrixRow2.w;
-
float shadow = 1.0;
- if(shadowPosition < m_Splits.x){
- shadow = GETSHADOW(m_ShadowMap0, projCoord0);
- }else if( shadowPosition < m_Splits.y){
- shadowBorderScale = 0.5;
- shadow = GETSHADOW(m_ShadowMap1, projCoord1);
- }else if( shadowPosition < m_Splits.z){
- shadowBorderScale = 0.25;
- shadow = GETSHADOW(m_ShadowMap2, projCoord2);
- }else if( shadowPosition < m_Splits.w){
- shadowBorderScale = 0.125;
- shadow = GETSHADOW(m_ShadowMap3, projCoord3);
- }
+ #ifdef PSSM
+ float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x + m_ViewProjectionMatrixRow2.y * worldPos.y + m_ViewProjectionMatrixRow2.z * worldPos.z + m_ViewProjectionMatrixRow2.w;
+
+ if(shadowPosition < m_Splits.x){
+ shadow = GETSHADOW(m_ShadowMap0, projCoord0);
+ }else if( shadowPosition < m_Splits.y){
+ shadowBorderScale = 0.5;
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }else if( shadowPosition < m_Splits.z){
+ shadowBorderScale = 0.25;
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else if( shadowPosition < m_Splits.w){
+ shadowBorderScale = 0.125;
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ #endif
+
+ #ifdef POINTLIGHT
+ vec3 vect = worldPos.xyz - m_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(m_ShadowMap0, projCoord0);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }
+ }else if(maxComp == absv.z){
+ if(vect.z < 0.0){
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ }else if(maxComp == absv.x){
+ if(vect.x < 0.0){
+ shadow = GETSHADOW(m_ShadowMap4, projCoord4);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap5, projCoord5);
+ }
+ }
+ #endif
#ifdef FADE
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md
index 711729aef..356d353db 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md
@@ -8,6 +8,10 @@ MaterialDef Post Shadow {
Texture2D ShadowMap1
Texture2D ShadowMap2
Texture2D ShadowMap3
+ //pointLights
+ Texture2D ShadowMap4
+ Texture2D ShadowMap5
+ Vector3 LightPos
Float ShadowIntensity
Vector4 Splits
@@ -16,7 +20,10 @@ MaterialDef Post Shadow {
Matrix4 LightViewProjectionMatrix0
Matrix4 LightViewProjectionMatrix1
Matrix4 LightViewProjectionMatrix2
- Matrix4 LightViewProjectionMatrix3
+ Matrix4 LightViewProjectionMatrix3
+ //pointLight
+ Matrix4 LightViewProjectionMatrix4
+ Matrix4 LightViewProjectionMatrix5
Float PCFEdge
@@ -48,6 +55,8 @@ MaterialDef Post Shadow {
PCFEDGE : PCFEdge
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
}
@@ -66,6 +75,8 @@ MaterialDef Post Shadow {
PCFEDGE : PCFEdge
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
}
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag
index a331b625a..edae776f7 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag
@@ -20,6 +20,12 @@ uniform mat4 m_LightViewProjectionMatrix1;
uniform mat4 m_LightViewProjectionMatrix2;
uniform mat4 m_LightViewProjectionMatrix3;
+#ifdef POINTLIGHT
+ uniform vec3 m_LightPos;
+ uniform mat4 m_LightViewProjectionMatrix4;
+ uniform mat4 m_LightViewProjectionMatrix5;
+#endif
+
#ifdef FADE
uniform vec2 m_FadeInfo;
#endif
@@ -47,22 +53,53 @@ vec4 main_multiSample(in int numSample){
vec4 projCoord1 = biasMat * m_LightViewProjectionMatrix1 * worldPos;
vec4 projCoord2 = biasMat * m_LightViewProjectionMatrix2 * worldPos;
vec4 projCoord3 = biasMat * m_LightViewProjectionMatrix3 * worldPos;
+ #ifdef POINTLIGHT
+ vec4 projCoord4 = biasMat * m_LightViewProjectionMatrix4 * worldPos;
+ vec4 projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos;
+ #endif
- float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x + m_ViewProjectionMatrixRow2.y * worldPos.y + m_ViewProjectionMatrixRow2.z * worldPos.z + m_ViewProjectionMatrixRow2.w;
-
float shadow = 1.0;
- if(shadowPosition < m_Splits.x){
- shadow = GETSHADOW(m_ShadowMap0, projCoord0);
- }else if( shadowPosition < m_Splits.y){
- shadowBorderScale = 0.5;
- shadow = GETSHADOW(m_ShadowMap1, projCoord1);
- }else if( shadowPosition < m_Splits.z){
- shadowBorderScale = 0.25;
- shadow = GETSHADOW(m_ShadowMap2, projCoord2);
- }else if( shadowPosition < m_Splits.w){
- shadowBorderScale = 0.125;
- shadow = GETSHADOW(m_ShadowMap3, projCoord3);
- }
+ #ifdef PSSM
+ float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x + m_ViewProjectionMatrixRow2.y * worldPos.y + m_ViewProjectionMatrixRow2.z * worldPos.z + m_ViewProjectionMatrixRow2.w;
+
+ if(shadowPosition < m_Splits.x){
+ shadow = GETSHADOW(m_ShadowMap0, projCoord0);
+ }else if( shadowPosition < m_Splits.y){
+ shadowBorderScale = 0.5;
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }else if( shadowPosition < m_Splits.z){
+ shadowBorderScale = 0.25;
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else if( shadowPosition < m_Splits.w){
+ shadowBorderScale = 0.125;
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ #endif
+
+ #ifdef POINTLIGHT
+ vec3 vect = worldPos.xyz - m_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(m_ShadowMap0, projCoord0);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }
+ }else if(maxComp == absv.z){
+ if(vect.z < 0.0){
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ }else if(maxComp == absv.x){
+ if(vect.x < 0.0){
+ shadow = GETSHADOW(m_ShadowMap4, projCoord4);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap5, projCoord5);
+ }
+ }
+ #endif
#ifdef FADE
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag
index e9661e510..82097b93f 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag
@@ -1,11 +1,21 @@
#import "Common/ShaderLib/PssmShadows.glsllib"
+#ifdef PSSM
varying float shadowPosition;
+#endif
+
varying vec4 projCoord0;
varying vec4 projCoord1;
varying vec4 projCoord2;
varying vec4 projCoord3;
+#ifdef POINTLIGHT
+ varying vec4 projCoord4;
+ varying vec4 projCoord5;
+ uniform vec3 m_LightPos;
+ varying vec4 worldPos;
+#endif
+
#ifdef DISCARD_ALPHA
#ifdef COLOR_MAP
uniform sampler2D m_ColorMap;
@@ -35,19 +45,46 @@ void main(){
#endif
float shadow = 1.0;
- if(shadowPosition < m_Splits.x){
- shadow = GETSHADOW(m_ShadowMap0, projCoord0);
- }else if( shadowPosition < m_Splits.y){
- shadowBorderScale = 0.5;
- shadow = GETSHADOW(m_ShadowMap1, projCoord1);
- }else if( shadowPosition < m_Splits.z){
- shadowBorderScale = 0.25;
- shadow = GETSHADOW(m_ShadowMap2, projCoord2);
- }else if( shadowPosition < m_Splits.w){
- shadowBorderScale = 0.125;
- shadow = GETSHADOW(m_ShadowMap3, projCoord3);
- }
-
+ #ifdef PSSM
+ if(shadowPosition < m_Splits.x){
+ shadow = GETSHADOW(m_ShadowMap0, projCoord0);
+ }else if( shadowPosition < m_Splits.y){
+ shadowBorderScale = 0.5;
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }else if( shadowPosition < m_Splits.z){
+ shadowBorderScale = 0.25;
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else if( shadowPosition < m_Splits.w){
+ shadowBorderScale = 0.125;
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ #endif
+
+ #ifdef POINTLIGHT
+ vec3 vect = worldPos.xyz - m_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(m_ShadowMap0, projCoord0);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }
+ }else if(maxComp == absv.z){
+ if(vect.z < 0.0){
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ }else if(maxComp == absv.x){
+ if(vect.x < 0.0){
+ shadow = GETSHADOW(m_ShadowMap4, projCoord4);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap5, projCoord5);
+ }
+ }
+ #endif
+
#ifdef FADE
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
#endif
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.j3md b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.j3md
index f502aaed1..60bf7e3c6 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.j3md
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.j3md
@@ -8,6 +8,9 @@ MaterialDef Post Shadow {
Texture2D ShadowMap1
Texture2D ShadowMap2
Texture2D ShadowMap3
+ //pointLights
+ Texture2D ShadowMap4
+ Texture2D ShadowMap5
Float ShadowIntensity
Vector4 Splits
@@ -17,6 +20,10 @@ MaterialDef Post Shadow {
Matrix4 LightViewProjectionMatrix1
Matrix4 LightViewProjectionMatrix2
Matrix4 LightViewProjectionMatrix3
+ //pointLight
+ Matrix4 LightViewProjectionMatrix4
+ Matrix4 LightViewProjectionMatrix5
+ Vector3 LightPos
Float PCFEdge
@@ -38,6 +45,8 @@ MaterialDef Post Shadow {
PCFEDGE : PCFEdge
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
RenderState {
@@ -62,6 +71,8 @@ MaterialDef Post Shadow {
PCFEDGE : PCFEdge
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
+ PSSM : Splits
+ POINTLIGHT : LightViewProjectionMatrix5
}
RenderState {
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.vert b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.vert
index 2bdfb25b6..2a67c5e2b 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.vert
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.vert
@@ -11,7 +11,17 @@ varying vec4 projCoord1;
varying vec4 projCoord2;
varying vec4 projCoord3;
+#ifdef POINTLIGHT
+uniform mat4 m_LightViewProjectionMatrix4;
+uniform mat4 m_LightViewProjectionMatrix5;
+varying vec4 projCoord4;
+varying vec4 projCoord5;
+varying vec4 worldPos;
+#endif
+
+#ifdef PSSM
varying float shadowPosition;
+#endif
varying vec2 texCoord;
@@ -30,9 +40,12 @@ const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0,
void main(){
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
- shadowPosition = gl_Position.z;
+ #ifdef PSSM
+ shadowPosition = gl_Position.z;
+ vec4 worldPos=vec4(0.0);
+ #endif
// get the vertex in world space
- vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
+ worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
#ifdef DISCARD_ALPHA
texCoord = inTexCoord;
@@ -42,4 +55,8 @@ void main(){
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;
+ #endif
}
\ No newline at end of file
diff --git a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM15.frag b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM15.frag
index f9cdc5eb4..b97bea408 100644
--- a/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM15.frag
+++ b/engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM15.frag
@@ -1,12 +1,23 @@
#import "Common/ShaderLib/PssmShadows15.glsllib"
out vec4 outFragColor;
+
+#ifdef PSSM
in float shadowPosition;
+#endif
+
in vec4 projCoord0;
in vec4 projCoord1;
in vec4 projCoord2;
in vec4 projCoord3;
+#ifdef POINTLIGHT
+ in vec4 projCoord4;
+ in vec4 projCoord5;
+ uniform vec3 m_LightPos;
+ in vec4 worldPos;
+#endif
+
#ifdef DISCARD_ALPHA
#ifdef COLOR_MAP
uniform sampler2D m_ColorMap;
@@ -35,20 +46,53 @@ void main(){
}
#endif
-
float shadow = 1.0;
- if(shadowPosition < m_Splits.x){
- shadow = GETSHADOW(m_ShadowMap0, projCoord0);
- }else if( shadowPosition < m_Splits.y){
- shadowBorderScale = 0.5;
- shadow = GETSHADOW(m_ShadowMap1, projCoord1);
- }else if( shadowPosition < m_Splits.z){
- shadowBorderScale = 0.25;
- shadow = GETSHADOW(m_ShadowMap2, projCoord2);
- }else if( shadowPosition < m_Splits.w){
- shadowBorderScale = 0.125;
- shadow = GETSHADOW(m_ShadowMap3, projCoord3);
- }
+ #ifdef PSSM
+ if(shadowPosition < m_Splits.x){
+ shadow = GETSHADOW(m_ShadowMap0, projCoord0);
+ }else if( shadowPosition < m_Splits.y){
+ shadowBorderScale = 0.5;
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+ }else if( shadowPosition < m_Splits.z){
+ shadowBorderScale = 0.25;
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+ }else if( shadowPosition < m_Splits.w){
+ shadowBorderScale = 0.125;
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+ }
+ #endif
+
+
+ #ifdef POINTLIGHT
+ vec3 vect = worldPos.xyz - m_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(m_ShadowMap0, projCoord0);
+outFragColor = vec4(projCoord0.z);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+outFragColor = vec4(projCoord1.z);
+ }
+ }else if(maxComp == absv.z){
+ if(vect.z < 0.0){
+ shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+outFragColor =vec4(projCoord2.z);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap3, projCoord3);
+outFragColor = vec4(projCoord3.z);
+ }
+ }else if(maxComp == absv.x){
+ if(vect.x < 0.0){
+ shadow = GETSHADOW(m_ShadowMap4, projCoord4);
+outFragColor = vec4(projCoord4.z);
+ }else{
+ shadow = GETSHADOW(m_ShadowMap5, projCoord5);
+outFragColor = vec4(projCoord5.z);
+ }
+ }
+ #endif
#ifdef FADE
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
diff --git a/engine/src/core-data/Common/ShaderLib/PssmShadows.glsllib b/engine/src/core-data/Common/ShaderLib/PssmShadows.glsllib
index 1e53d86f3..9ead707ab 100644
--- a/engine/src/core-data/Common/ShaderLib/PssmShadows.glsllib
+++ b/engine/src/core-data/Common/ShaderLib/PssmShadows.glsllib
@@ -3,7 +3,7 @@
#define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r
#else
#define SHADOWMAP sampler2D
- #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r)
+ #define SHADOWCOMPARE(tex,coord) step(coord.z / coord.w, texture2DProj(tex, coord).r)
#endif
#if FILTER_MODE == 0
@@ -35,8 +35,14 @@ 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;
@@ -53,10 +59,16 @@ float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){
}
float Shadow_BorderCheck(in vec2 coord){
+#ifdef PSSM
// 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);
+#else
+//fix me this is a big fat hack to avoid issues whith point lights,
+//this function fail to return correct values, but it works with PSSM
+ return 0.0;
+#endif
}
float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
diff --git a/engine/src/core-data/Common/ShaderLib/PssmShadows15.glsllib b/engine/src/core-data/Common/ShaderLib/PssmShadows15.glsllib
index f52213003..6dd071229 100644
--- a/engine/src/core-data/Common/ShaderLib/PssmShadows15.glsllib
+++ b/engine/src/core-data/Common/ShaderLib/PssmShadows15.glsllib
@@ -9,8 +9,8 @@
#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 SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z / coord.w, textureProjOffset(tex, coord, offset).r)
+ #define SHADOWCOMPARE(tex,coord) step(coord.z / coord.w, textureProj(tex, coord).r)
#define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy))
#endif
@@ -45,18 +45,30 @@ 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){
+#ifdef PSSM
// 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);
+#else
+//fix me this is a big fat hack to avoid issues whith point lights,
+//this function fail to return correct values, but it works with PSSM
+ return 0.0;
+#endif
}
float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
@@ -90,7 +102,7 @@ float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0));
gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1));
gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1));
- #endif
+ #endif
vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE );
vec2 mx = mix( gather.xz, gather.yw, f.x );
diff --git a/engine/src/core/com/jme3/shadow/PointLightShadowFilter.java b/engine/src/core/com/jme3/shadow/PointLightShadowFilter.java
new file mode 100644
index 000000000..966d03726
--- /dev/null
+++ b/engine/src/core/com/jme3/shadow/PointLightShadowFilter.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.shadow;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.light.PointLight;
+import com.jme3.material.Material;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector4f;
+import com.jme3.post.Filter;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.shadow.PointLightShadowRenderer.CompareMode;
+import com.jme3.shadow.PointLightShadowRenderer.FilterMode;
+import com.jme3.texture.FrameBuffer;
+import java.io.IOException;
+
+/**
+ *
+ * This Filter does basically the same as a PointLightShadowRenderer except it renders
+ * the post shadow pass as a fulscreen quad pass instead of a geometry pass.
+ * It's mostly faster than PointLightShadowRenderer as long as you have more than a about ten shadow recieving objects.
+ * The expense is the draw back that the shadow Recieve mode set on spatial is ignored.
+ * So basically all and only objects that render depth in the scene receive shadows.
+ * See this post for more details http://jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/#post-191599
+ *
+ * API is basically the same as the PssmShadowRenderer;
+ *
+ * @author Rémy Bouquet aka Nehon
+ */
+public class PointLightShadowFilter extends Filter {
+
+ private PointLightShadowRenderer plRenderer;
+ private ViewPort viewPort;
+
+ /**
+ * Creates a PSSM Shadow Filter
+ * More info on the technique at http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html
+ * @param manager the application asset manager
+ * @param size the size of the rendered shadowmaps (512,1024,2048, etc...)
+ * @param nbSplits the number of shadow maps rendered (the more shadow maps the more quality, the less fps).
+ */
+ public PointLightShadowFilter(AssetManager manager, int size) {
+ super("Post Shadow");
+ material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");
+ plRenderer = new PointLightShadowRenderer(manager, size, material);
+ plRenderer.needsfallBackMaterial = true;
+ }
+
+ @Override
+ protected Material getMaterial() {
+ return material;
+ }
+
+ @Override
+ protected boolean isRequiresDepthTexture() {
+ return true;
+ }
+
+ public Material getShadowMaterial() {
+ return material;
+ }
+ Vector4f tmpv = new Vector4f();
+
+ @Override
+ protected void preFrame(float tpf) {
+ plRenderer.preFrame(tpf);
+ material.setMatrix4("ViewProjectionMatrixInverse", viewPort.getCamera().getViewProjectionMatrix().invert());
+ Matrix4f m = viewPort.getCamera().getViewProjectionMatrix();
+ material.setVector4("ViewProjectionMatrixRow2", tmpv.set(m.m20, m.m21, m.m22, m.m23));
+
+ }
+
+ @Override
+ protected void postQueue(RenderQueue queue) {
+ plRenderer.postQueue(queue);
+ }
+
+ @Override
+ protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
+ plRenderer.setPostShadowParams();
+ }
+
+ @Override
+ protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
+ plRenderer.initialize(renderManager, vp);
+ this.viewPort = vp;
+ }
+
+ /**
+ * gets the point light used to cast shadows with this processor
+ *
+ * @return the point light
+ */
+ public PointLight getLight() {
+ return plRenderer.getLight();
+ }
+
+ /**
+ * sets the light to use for casting shadows with this processor
+ *
+ * @param light the point light
+ */
+ public void setLight(PointLight light) {
+ plRenderer.setLight(light);
+ }
+
+ /**
+ * returns the shdaow intensity
+ * @see #setShadowIntensity(float shadowIntensity)
+ * @return shadowIntensity
+ */
+ public float getShadowIntensity() {
+ return plRenderer.getShadowIntensity();
+ }
+
+ /**
+ * Set the shadowIntensity, the value should be between 0 and 1,
+ * a 0 value gives a bright and invisilble shadow,
+ * a 1 value gives a pitch black shadow,
+ * default is 0.7
+ * @param shadowIntensity the darkness of the shadow
+ */
+ final public void setShadowIntensity(float shadowIntensity) {
+ plRenderer.setShadowIntensity(shadowIntensity);
+ }
+
+ /**
+ * returns the edges thickness
+ * @see #setEdgesThickness(int edgesThickness)
+ * @return edgesThickness
+ */
+ public int getEdgesThickness() {
+ return plRenderer.getEdgesThickness();
+ }
+
+ /**
+ * Sets the shadow edges thickness. default is 1, setting it to lower values can help to reduce the jagged effect of the shadow edges
+ * @param edgesThickness
+ */
+ public void setEdgesThickness(int edgesThickness) {
+ plRenderer.setEdgesThickness(edgesThickness);
+ }
+
+ /**
+ * returns true if the PssmRenderer flushed the shadow queues
+ * @return flushQueues
+ */
+ public boolean isFlushQueues() {
+ return plRenderer.isFlushQueues();
+ }
+
+ /**
+ * Set this to false if you want to use several PssmRederers to have multiple shadows cast by multiple light sources.
+ * Make sure the last PssmRenderer in the stack DO flush the queues, but not the others
+ * @param flushQueues
+ */
+ public void setFlushQueues(boolean flushQueues) {
+ plRenderer.setFlushQueues(flushQueues);
+ }
+
+ /**
+ * sets the shadow compare mode see {@link CompareMode} for more info
+ * @param compareMode
+ */
+ final public void setCompareMode(CompareMode compareMode) {
+ plRenderer.setCompareMode(compareMode);
+ }
+
+ /**
+ * Sets the filtering mode for shadow edges see {@link FilterMode} for more info
+ * @param filterMode
+ */
+ final public void setFilterMode(FilterMode filterMode) {
+ plRenderer.setFilterMode(filterMode);
+ }
+
+ /**
+ * Define the length over which the shadow will fade out when using a shadowZextend
+ * @param length the fade length in world units
+ */
+ public void setShadowZFadeLength(float length){
+ plRenderer.setShadowZFadeLength(length);
+ }
+
+ /**
+ * get the length over which the shadow will fade out when using a shadowZextend
+ * @return the fade length in world units
+ */
+ public float getShadowZFadeLength(){
+ return plRenderer.getShadowZFadeLength();
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule oc = ex.getCapsule(this);
+
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule ic = im.getCapsule(this);
+
+ }
+}
diff --git a/engine/src/core/com/jme3/shadow/PointLightShadowRenderer.java b/engine/src/core/com/jme3/shadow/PointLightShadowRenderer.java
new file mode 100644
index 000000000..331b7d9e8
--- /dev/null
+++ b/engine/src/core/com/jme3/shadow/PointLightShadowRenderer.java
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.shadow;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.light.PointLight;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.post.SceneProcessor;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.Caps;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.GeometryList;
+import com.jme3.renderer.queue.OpaqueComparator;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.debug.WireFrustum;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture.MagFilter;
+import com.jme3.texture.Texture.MinFilter;
+import com.jme3.texture.Texture.ShadowCompareMode;
+import com.jme3.texture.Texture2D;
+import com.jme3.ui.Picture;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * PssmShadow renderer use Parrallel Split Shadow Mapping technique (pssm)
+ * It splits the view frustum in several parts and compute a shadow map for each
+ * one.
splits are distributed so that the closer they are from the camera,
+ * the smaller they are to maximize the resolution used of the shadow map.
+ * This result in a better quality shadow than standard shadow mapping.
for
+ * more informations on this read this http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html
+ *
FilterMode
specifies how shadows are filtered
+ */
+ public enum FilterMode {
+
+ /**
+ * Shadows are not filtered. Nearest sample is used, causing in blocky
+ * shadows.
+ */
+ Nearest,
+ /**
+ * Bilinear filtering is used. Has the potential of being hardware
+ * accelerated on some GPUs
+ */
+ Bilinear,
+ /**
+ * Dither-based sampling is used, very cheap but can look bad at low
+ * resolutions.
+ */
+ Dither,
+ /**
+ * 4x4 percentage-closer filtering is used. Shadows will be smoother at
+ * the cost of performance
+ */
+ PCF4,
+ /**
+ * 8x8 percentage-closer filtering is used. Shadows will be smoother at
+ * the cost of performance
+ */
+ PCFPOISSON,
+ /**
+ * 8x8 percentage-closer filtering is used. Shadows will be smoother at
+ * the cost of performance
+ */
+ PCF8
+ }
+
+ /**
+ * Specifies the shadow comparison mode
+ */
+ public enum CompareMode {
+
+ /**
+ * Shadow depth comparisons are done by using shader code
+ */
+ Software,
+ /**
+ * Shadow depth comparisons are done by using the GPU's dedicated
+ * shadowing pipeline.
+ */
+ Hardware;
+ }
+ protected final int CAM_NUMBER = 6;
+ protected PointLight light;
+ //common
+ protected float shadowMapSize;
+ protected float shadowIntensity = 0.7f;
+ protected float zFarOverride = 0;
+ protected RenderManager renderManager;
+ protected ViewPort viewPort;
+ protected FrameBuffer[] shadowFB;
+ protected Texture2D[] shadowMaps;
+ protected Texture2D dummyTex;
+ protected Camera[] shadowCams;
+ protected Material preshadowMat;
+ protected Material postshadowMat;
+ protected GeometryList splitOccluders = new GeometryList(new OpaqueComparator());
+ protected Matrix4f[] lightViewProjectionsMatrices;
+ protected boolean noOccluders = false;
+ protected AssetManager assetManager;
+ protected boolean debug = false;
+ protected float edgesThickness = 1.0f;
+ protected FilterMode filterMode;
+ protected CompareMode compareMode;
+ protected Picture[] dispPic;
+ protected boolean flushQueues = true;
+ // define if the fallback material should be used.
+ protected boolean needsfallBackMaterial = false;
+ //Name of the post material technique
+ protected String postTechniqueName = "PostShadow";
+ //flags to know when to change params in the materials
+ protected boolean applyHWShadows = true;
+ protected boolean applyFilterMode = true;
+ protected boolean applyPCFEdge = true;
+ protected boolean applyShadowIntensity = true;
+ //a list of material of the post shadow queue geometries.
+ protected List