Lighting and Shadows (PSSM only) :
- re introduced the alphaDiscardThreshold as explained in prvious commit. It's not binded to the AlphaTestFallOff fixedfunc binding - Added a small poly offset to post shadow technique, this greatly help in fixing shadow acne. - Added Poisson disc sampling PCF Filtering for shadows - Properly passed the shadow map size as a define in the shaders and remove the hardcoded value - Pssm15 don't use the textureSize function anymore and use the same shadow map size define ( this increased performance quite a bit) - Optimized the shaders code a bit - Better PSSM test git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9750 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
2915316e45
commit
384f4ac1c2
@ -15,6 +15,9 @@ MaterialDef Phong Lighting {
|
|||||||
// Output alpha from the diffuse map
|
// Output alpha from the diffuse map
|
||||||
Boolean UseAlpha
|
Boolean UseAlpha
|
||||||
|
|
||||||
|
// Apha threshold for fragment discarding
|
||||||
|
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
||||||
|
|
||||||
// Normal map is in BC5/ATI2n/LATC/3Dc compression format
|
// Normal map is in BC5/ATI2n/LATC/3Dc compression format
|
||||||
Boolean LATC
|
Boolean LATC
|
||||||
|
|
||||||
@ -115,6 +118,7 @@ MaterialDef Phong Lighting {
|
|||||||
Matrix4 LightViewProjectionMatrix3
|
Matrix4 LightViewProjectionMatrix3
|
||||||
|
|
||||||
Float PCFEdge
|
Float PCFEdge
|
||||||
|
Float ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
@ -157,7 +161,7 @@ MaterialDef Phong Lighting {
|
|||||||
SEPARATE_TEXCOORD : SeparateTexCoord
|
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||||
|
|
||||||
USE_REFLECTION : EnvMap
|
USE_REFLECTION : EnvMap
|
||||||
SPHERE_MAP : EnvMapAsSphereMap
|
SPHERE_MAP : SphereMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +176,8 @@ MaterialDef Phong Lighting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
DIFFUSEMAP : DiffuseMap
|
COLOR_MAP : ColorMap
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
@ -199,11 +204,15 @@ MaterialDef Phong Lighting {
|
|||||||
HARDWARE_SHADOWS : HardwareShadows
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
FILTER_MODE : FilterMode
|
FILTER_MODE : FilterMode
|
||||||
PCFEDGE : PCFEdge
|
PCFEDGE : PCFEdge
|
||||||
DIFFUSEMAP : DiffuseMap
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
COLOR_MAP : ColorMap
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
ForcedRenderState {
|
||||||
Blend Alpha
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,11 +229,15 @@ MaterialDef Phong Lighting {
|
|||||||
HARDWARE_SHADOWS : HardwareShadows
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
FILTER_MODE : FilterMode
|
FILTER_MODE : FilterMode
|
||||||
PCFEDGE : PCFEdge
|
PCFEDGE : PCFEdge
|
||||||
DIFFUSEMAP : DiffuseMap
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
COLOR_MAP : ColorMap
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
ForcedRenderState {
|
||||||
Blend Alpha
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ MaterialDef Post Shadow {
|
|||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
Blend Modulate
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#define GETSHADOW Shadow_DoPCF
|
#define GETSHADOW Shadow_DoPCF
|
||||||
#define KERNEL 4.0
|
#define KERNEL 4.0
|
||||||
#elif FILTER_MODE == 4
|
#elif FILTER_MODE == 4
|
||||||
|
#define GETSHADOW Shadow_DoPCFPoisson
|
||||||
|
#define KERNEL 4
|
||||||
|
#elif FILTER_MODE == 5
|
||||||
#define GETSHADOW Shadow_DoPCF
|
#define GETSHADOW Shadow_DoPCF
|
||||||
#define KERNEL 8.0
|
#define KERNEL 8.0
|
||||||
#endif
|
#endif
|
||||||
@ -44,9 +47,9 @@ varying vec4 projCoord3;
|
|||||||
|
|
||||||
varying float shadowPosition;
|
varying float shadowPosition;
|
||||||
|
|
||||||
const float texSize = 1024.0;
|
|
||||||
const float pixSize = 1.0 / texSize;
|
const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE);
|
||||||
const vec2 pixSize2 = vec2(pixSize);
|
float scale = 1.0;
|
||||||
|
|
||||||
float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, in vec4 projCoord, in vec2 offset){
|
float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, in vec4 projCoord, in vec2 offset){
|
||||||
vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2, projCoord.zw);
|
vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2, projCoord.zw);
|
||||||
@ -90,7 +93,7 @@ float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0));
|
gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0));
|
||||||
gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0));
|
gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0));
|
||||||
|
|
||||||
vec2 f = fract( projCoord.xy * texSize );
|
vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE );
|
||||||
vec2 mx = mix( gather.xz, gather.yw, f.x );
|
vec2 mx = mix( gather.xz, gather.yw, f.x );
|
||||||
return mix( mx.x, mx.y, f.y );
|
return mix( mx.x, mx.y, f.y );
|
||||||
}
|
}
|
||||||
@ -114,39 +117,102 @@ float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef COLOR_MAP
|
|
||||||
uniform sampler2D m_ColorMap;
|
//12 tap poisson disk
|
||||||
varying vec2 texCoord;
|
const vec2 poissonDisk[12] =vec2[12]( vec2(-0.1711046, -0.425016),
|
||||||
#endif
|
vec2(-0.7829809, 0.2162201),
|
||||||
#ifdef DIFFUSEMAP
|
vec2(-0.2380269, -0.8835521),
|
||||||
uniform sampler2D m_DiffuseMap;
|
vec2(0.4198045, 0.1687819),
|
||||||
|
vec2(-0.684418, -0.3186957),
|
||||||
|
vec2(0.6026866, -0.2587841),
|
||||||
|
vec2(-0.2412762, 0.3913516),
|
||||||
|
vec2(0.4720655, -0.7664126),
|
||||||
|
vec2(0.9571564, 0.2680693),
|
||||||
|
vec2(-0.5238616, 0.802707),
|
||||||
|
vec2(0.5653144, 0.60262),
|
||||||
|
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 = vec2( 4.0 * PCFEDGE * scale);
|
||||||
|
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[0] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[1] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[2] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[3] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[4] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[5] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[6] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[7] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[8] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[9] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[10] * texelSize);
|
||||||
|
shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk[11] * texelSize);
|
||||||
|
|
||||||
|
shadow = shadow * 0.08333333333;//this is divided by 12
|
||||||
|
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;
|
varying vec2 texCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
|
|
||||||
float alpha =1.0;
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COLOR_MAP
|
|
||||||
alpha = texture2D(m_ColorMap,texCoord).a;
|
|
||||||
#endif
|
|
||||||
#ifdef DIFFUSEMAP
|
|
||||||
alpha = texture2D(m_DiffuseMap,texCoord).a;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
vec4 shadowPerSplit = vec4(0.0);
|
vec4 shadowPerSplit = vec4(0.0);
|
||||||
shadowPerSplit.x = GETSHADOW(m_ShadowMap0, projCoord0);
|
float shadow;
|
||||||
|
//shadowPosition
|
||||||
|
if(shadowPosition < m_Splits.x){
|
||||||
|
shadow= GETSHADOW(m_ShadowMap0, projCoord0);
|
||||||
|
}else if( shadowPosition < m_Splits.y){
|
||||||
|
scale = 0.5;
|
||||||
|
shadow = GETSHADOW(m_ShadowMap1, projCoord1);
|
||||||
|
}else if( shadowPosition < m_Splits.z){
|
||||||
|
scale = 0.25;
|
||||||
|
shadow= GETSHADOW(m_ShadowMap2, projCoord2);
|
||||||
|
}else if( shadowPosition < m_Splits.w){
|
||||||
|
scale = 0.125;
|
||||||
|
shadow= GETSHADOW(m_ShadowMap3, projCoord3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
shadowPerSplit.x = GETSHADOW(m_ShadowMap0, projCoord0);
|
||||||
shadowPerSplit.y = GETSHADOW(m_ShadowMap1, projCoord1);
|
shadowPerSplit.y = GETSHADOW(m_ShadowMap1, projCoord1);
|
||||||
shadowPerSplit.z = GETSHADOW(m_ShadowMap2, projCoord2);
|
shadowPerSplit.z = GETSHADOW(m_ShadowMap2, projCoord2);
|
||||||
shadowPerSplit.w = GETSHADOW(m_ShadowMap3, projCoord3);
|
shadowPerSplit.w = GETSHADOW(m_ShadowMap3, projCoord3);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
vec4 less = step( shadowPosition, m_Splits );
|
vec4 less = step( shadowPosition, m_Splits );
|
||||||
vec4 more = vec4(1.0) - step( shadowPosition, vec4(0.0, m_Splits.xyz) );
|
vec4 more = vec4(1.0) - step( shadowPosition, vec4(0.0, m_Splits.xyz) );
|
||||||
float shadow = dot(shadowPerSplit, less * more );
|
float shadow = dot(shadowPerSplit, less * more );
|
||||||
|
*/
|
||||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||||
gl_FragColor = vec4(0.0, 0.0, 0.0, min(1.0 - shadow,alpha));
|
|
||||||
|
|
||||||
|
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ MaterialDef Post Shadow {
|
|||||||
Matrix4 LightViewProjectionMatrix3
|
Matrix4 LightViewProjectionMatrix3
|
||||||
|
|
||||||
Float PCFEdge
|
Float PCFEdge
|
||||||
|
|
||||||
|
Float ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
@ -33,10 +35,13 @@ MaterialDef Post Shadow {
|
|||||||
HARDWARE_SHADOWS : HardwareShadows
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
FILTER_MODE : FilterMode
|
FILTER_MODE : FilterMode
|
||||||
PCFEDGE : PCFEdge
|
PCFEDGE : PCFEdge
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
Blend Alpha
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,10 +58,13 @@ MaterialDef Post Shadow {
|
|||||||
HARDWARE_SHADOWS : HardwareShadows
|
HARDWARE_SHADOWS : HardwareShadows
|
||||||
FILTER_MODE : FilterMode
|
FILTER_MODE : FilterMode
|
||||||
PCFEDGE : PCFEdge
|
PCFEDGE : PCFEdge
|
||||||
|
SHADOWMAP_SIZE : ShadowMapSize
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
Blend Alpha
|
Blend Modulate
|
||||||
|
DepthWrite Off
|
||||||
|
PolyOffset -0.1 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ varying float shadowPosition;
|
|||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
|
|
||||||
attribute vec3 inPosition;
|
attribute vec3 inPosition;
|
||||||
#if defined(DIFFUSEMAP) || defined(COLOR_MAP)
|
|
||||||
|
#ifdef DISCARD_ALPHA
|
||||||
attribute vec2 inTexCoord;
|
attribute vec2 inTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ void main(){
|
|||||||
// get the vertex in world space
|
// get the vertex in world space
|
||||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||||
|
|
||||||
#if defined(DIFFUSEMAP) || defined(COLOR_MAP)
|
#ifdef DISCARD_ALPHA
|
||||||
texCoord = inTexCoord;
|
texCoord = inTexCoord;
|
||||||
#endif
|
#endif
|
||||||
// populate the light view matrices array and convert vertex to light viewProj space
|
// populate the light view matrices array and convert vertex to light viewProj space
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#define GETSHADOW Shadow_DoPCF
|
#define GETSHADOW Shadow_DoPCF
|
||||||
#define KERNEL 4
|
#define KERNEL 4
|
||||||
#elif FILTER_MODE == 4
|
#elif FILTER_MODE == 4
|
||||||
|
#define GETSHADOW Shadow_DoPCFPoisson
|
||||||
|
#define KERNEL 4
|
||||||
|
#elif FILTER_MODE == 5
|
||||||
#define GETSHADOW Shadow_DoPCF
|
#define GETSHADOW Shadow_DoPCF
|
||||||
#define KERNEL 8
|
#define KERNEL 8
|
||||||
#endif
|
#endif
|
||||||
@ -51,6 +54,8 @@ in vec4 projCoord1;
|
|||||||
in vec4 projCoord2;
|
in vec4 projCoord2;
|
||||||
in vec4 projCoord3;
|
in vec4 projCoord3;
|
||||||
in float shadowPosition;
|
in float shadowPosition;
|
||||||
|
const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE);
|
||||||
|
float scale = 1.0;
|
||||||
|
|
||||||
float Shadow_BorderCheck(in vec2 coord){
|
float Shadow_BorderCheck(in vec2 coord){
|
||||||
// Fastest, "hack" method (uses 4-5 instructions)
|
// Fastest, "hack" method (uses 4-5 instructions)
|
||||||
@ -64,8 +69,7 @@ float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
if (border > 0.0)
|
if (border > 0.0)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
||||||
ivec2 texSize = textureSize(tex, 0);
|
vec2 pixSize = pixSize2 * scale;
|
||||||
vec2 pixSize = 1.0 / vec2(texSize);
|
|
||||||
|
|
||||||
float shadow = 0.0;
|
float shadow = 0.0;
|
||||||
ivec2 o = ivec2(mod(floor(gl_FragCoord.xy), 2.0));
|
ivec2 o = ivec2(mod(floor(gl_FragCoord.xy), 2.0));
|
||||||
@ -82,7 +86,6 @@ float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
if (border > 0.0)
|
if (border > 0.0)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
||||||
ivec2 texSize = textureSize(tex, 0);
|
|
||||||
#ifdef GL_ARB_gpu_shader5
|
#ifdef GL_ARB_gpu_shader5
|
||||||
vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0);
|
vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0);
|
||||||
vec4 gather = SHADOWGATHER(tex, coord);
|
vec4 gather = SHADOWGATHER(tex, coord);
|
||||||
@ -94,14 +97,14 @@ float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1));
|
gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec2 f = fract( projCoord.xy * texSize );
|
vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE );
|
||||||
vec2 mx = mix( gather.xz, gather.yw, f.x );
|
vec2 mx = mix( gather.xz, gather.yw, f.x );
|
||||||
return mix( mx.x, mx.y, f.y );
|
return mix( mx.x, mx.y, f.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
||||||
float pixSize = 1.0 / textureSize(tex,0).x;
|
|
||||||
|
|
||||||
|
vec2 pixSize = pixSize2 * scale;
|
||||||
float shadow = 0.0;
|
float shadow = 0.0;
|
||||||
float border = Shadow_BorderCheck(projCoord.xy);
|
float border = Shadow_BorderCheck(projCoord.xy);
|
||||||
if (border > 0.0)
|
if (border > 0.0)
|
||||||
@ -121,38 +124,90 @@ float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef COLOR_MAP
|
//12 tap poisson disk
|
||||||
uniform sampler2D m_ColorMap;
|
const vec2 poissonDisk[12] =vec2[12]( vec2(-0.1711046, -0.425016),
|
||||||
varying vec2 texCoord;
|
vec2(-0.7829809, 0.2162201),
|
||||||
#endif
|
vec2(-0.2380269, -0.8835521),
|
||||||
#ifdef DIFFUSEMAP
|
vec2(0.4198045, 0.1687819),
|
||||||
uniform sampler2D m_DiffuseMap;
|
vec2(-0.684418, -0.3186957),
|
||||||
|
vec2(0.6026866, -0.2587841),
|
||||||
|
vec2(-0.2412762, 0.3913516),
|
||||||
|
vec2(0.4720655, -0.7664126),
|
||||||
|
vec2(0.9571564, 0.2680693),
|
||||||
|
vec2(-0.5238616, 0.802707),
|
||||||
|
vec2(0.5653144, 0.60262),
|
||||||
|
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;
|
||||||
|
|
||||||
|
//failed attempt to rotate the poisson disk to add jitter
|
||||||
|
//vec2 jitterFactor = vec2(sin(projCoord.x),cos(projCoord.x));// * 2.0f - 1.0f;
|
||||||
|
|
||||||
|
vec2 texelSize = pixSize2 * 4.0 * PCFEDGE * scale;
|
||||||
|
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[0] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[1] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[2] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[3] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[4] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[5] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[6] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[7] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[8] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[9] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[10] * texelSize, projCoord.zw));
|
||||||
|
shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk[11] * texelSize, projCoord.zw));
|
||||||
|
|
||||||
|
shadow = shadow * 0.08333333333;//this is divided by 12
|
||||||
|
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;
|
varying vec2 texCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
float shadow = 0.0;
|
float shadow = 0.0;
|
||||||
|
|
||||||
float alpha = 1.0;
|
|
||||||
|
|
||||||
#ifdef COLOR_MAP
|
#ifdef DISCARD_ALPHA
|
||||||
alpha = texture2D(m_ColorMap,texCoord).a;
|
#ifdef COLOR_MAP
|
||||||
#endif
|
float alpha = texture2D(m_ColorMap,texCoord).a;
|
||||||
#ifdef DIFFUSEMAP
|
#else
|
||||||
alpha = texture2D(m_DiffuseMap,texCoord).a;
|
float alpha = texture2D(m_DiffuseMap,texCoord).a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(alpha < m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if(shadowPosition < m_Splits.x){
|
if(shadowPosition < m_Splits.x){
|
||||||
shadow = GETSHADOW(m_ShadowMap0, projCoord0);
|
shadow = GETSHADOW(m_ShadowMap0, projCoord0);
|
||||||
}else if( shadowPosition < m_Splits.y){
|
}else if( shadowPosition < m_Splits.y){
|
||||||
|
scale = 0.5;
|
||||||
shadow = GETSHADOW(m_ShadowMap1, projCoord1);
|
shadow = GETSHADOW(m_ShadowMap1, projCoord1);
|
||||||
}else if( shadowPosition < m_Splits.z){
|
}else if( shadowPosition < m_Splits.z){
|
||||||
|
scale = 0.25;
|
||||||
shadow = GETSHADOW(m_ShadowMap2, projCoord2);
|
shadow = GETSHADOW(m_ShadowMap2, projCoord2);
|
||||||
}else if( shadowPosition < m_Splits.w){
|
}else if( shadowPosition < m_Splits.w){
|
||||||
|
scale = 0.125;
|
||||||
shadow = GETSHADOW(m_ShadowMap3, projCoord3);
|
shadow = GETSHADOW(m_ShadowMap3, projCoord3);
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||||
outFragColor = vec4(0.0, 0.0, 0.0, min(1.0 - shadow,alpha));
|
outFragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
#ifdef DISCARD_ALPHA
|
||||||
#ifdef COLOR_MAP
|
#ifdef COLOR_MAP
|
||||||
uniform sampler2D m_ColorMap;
|
uniform sampler2D m_ColorMap;
|
||||||
|
#else
|
||||||
|
uniform sampler2D m_DiffuseMap;
|
||||||
|
#endif
|
||||||
|
uniform float m_AlphaDiscardThreshold;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DIFFUSEMAP
|
|
||||||
uniform sampler2D m_DiffuseMap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
float a = 1.0;
|
#ifdef DISCARD_ALPHA
|
||||||
|
#ifdef COLOR_MAP
|
||||||
|
if (texture2D(m_ColorMap, texCoord).a <= m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (texture2D(m_DiffuseMap, texCoord).a <= m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef COLOR_MAP
|
gl_FragColor = vec4(1.0);
|
||||||
a = texture2D(m_ColorMap, texCoord).a;
|
|
||||||
#endif
|
|
||||||
#ifdef DIFFUSEMAP
|
|
||||||
a = texture2D(m_DiffuseMap, texCoord).a;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gl_FragColor = vec4(a);
|
|
||||||
}
|
}
|
@ -4,15 +4,17 @@ varying vec2 texCoord;
|
|||||||
|
|
||||||
#ifdef DIFFUSEMAP_ALPHA
|
#ifdef DIFFUSEMAP_ALPHA
|
||||||
uniform sampler2D m_DiffuseMap;
|
uniform sampler2D m_DiffuseMap;
|
||||||
|
uniform float m_AlphaDiscardThreshold;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
float alpha= 1.0;
|
|
||||||
#ifdef DIFFUSEMAP_ALPHA
|
#ifdef DIFFUSEMAP_ALPHA
|
||||||
alpha=texture2D(m_DiffuseMap,texCoord).a;
|
if(texture2D(m_DiffuseMap,texCoord).a<m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
gl_FragColor = vec4(normal.xy* 0.5 + 0.5,-normal.z* 0.5 + 0.5, alpha);
|
gl_FragColor = vec4(normal.xy* 0.5 + 0.5,-normal.z* 0.5 + 0.5, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ package com.jme3.shadow;
|
|||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
@ -47,6 +48,7 @@ import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
|||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.scene.debug.WireFrustum;
|
import com.jme3.scene.debug.WireFrustum;
|
||||||
|
import com.jme3.shader.VarType;
|
||||||
import com.jme3.texture.FrameBuffer;
|
import com.jme3.texture.FrameBuffer;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import com.jme3.texture.Texture.MagFilter;
|
import com.jme3.texture.Texture.MagFilter;
|
||||||
@ -93,11 +95,17 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
* at the cost of performance
|
* at the cost of performance
|
||||||
*/
|
*/
|
||||||
PCF4,
|
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
|
* 8x8 percentage-closer filtering is used. Shadows will be smoother
|
||||||
* at the cost of performance
|
* at the cost of performance
|
||||||
*/
|
*/
|
||||||
PCF8
|
PCF8
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,6 +124,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
Hardware;
|
Hardware;
|
||||||
}
|
}
|
||||||
private int nbSplits = 3;
|
private int nbSplits = 3;
|
||||||
|
private float shadowMapSize;
|
||||||
private float lambda = 0.65f;
|
private float lambda = 0.65f;
|
||||||
private float shadowIntensity = 0.7f;
|
private float shadowIntensity = 0.7f;
|
||||||
private float zFarOverride = 0;
|
private float zFarOverride = 0;
|
||||||
@ -172,6 +181,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
assetManager = manager;
|
assetManager = manager;
|
||||||
nbSplits = Math.max(Math.min(nbSplits, 4), 1);
|
nbSplits = Math.max(Math.min(nbSplits, 4), 1);
|
||||||
this.nbSplits = nbSplits;
|
this.nbSplits = nbSplits;
|
||||||
|
shadowMapSize = size;
|
||||||
|
|
||||||
shadowFB = new FrameBuffer[nbSplits];
|
shadowFB = new FrameBuffer[nbSplits];
|
||||||
shadowMaps = new Texture2D[nbSplits];
|
shadowMaps = new Texture2D[nbSplits];
|
||||||
@ -185,6 +195,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
|
|
||||||
preshadowMat = new Material(manager, "Common/MatDefs/Shadow/PreShadow.j3md");
|
preshadowMat = new Material(manager, "Common/MatDefs/Shadow/PreShadow.j3md");
|
||||||
this.postshadowMat = postShadowMat;
|
this.postshadowMat = postShadowMat;
|
||||||
|
postshadowMat.setFloat("ShadowMapSize", size);
|
||||||
|
|
||||||
for (int i = 0; i < nbSplits; i++) {
|
for (int i = 0; i < nbSplits; i++) {
|
||||||
lightViewProjectionsMatrices[i] = new Matrix4f();
|
lightViewProjectionsMatrices[i] = new Matrix4f();
|
||||||
@ -315,7 +326,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
//checking for caps to chosse the appropriate post material technique
|
//checking for caps to chosse the appropriate post material technique
|
||||||
if (renderManager.getRenderer().getCaps().contains(Caps.GLSL150)) {
|
if (renderManager.getRenderer().getCaps().contains(Caps.GLSL150)) {
|
||||||
postTechniqueName = "PostShadow15";
|
postTechniqueName = "PostShadow15";
|
||||||
}else{
|
} else {
|
||||||
postTechniqueName = "PostShadow";
|
postTechniqueName = "PostShadow";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,7 +434,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
renderManager.setCamera(cam, true);
|
renderManager.setCamera(cam, true);
|
||||||
int h = cam.getHeight();
|
int h = cam.getHeight();
|
||||||
for (int i = 0; i < dispPic.length; i++) {
|
for (int i = 0; i < dispPic.length; i++) {
|
||||||
dispPic[i].setPosition(64 * (i + 1) + 128 * i, h / 20f);
|
dispPic[i].setPosition((128 * i) +(150 + 64 * (i + 1) ), h / 20f);
|
||||||
dispPic[i].setWidth(128);
|
dispPic[i].setWidth(128);
|
||||||
dispPic[i].setHeight(128);
|
dispPic[i].setHeight(128);
|
||||||
dispPic[i].updateGeometricState();
|
dispPic[i].updateGeometricState();
|
||||||
@ -449,7 +460,7 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
renderManager.setForcedMaterial(postshadowMat);
|
renderManager.setForcedMaterial(postshadowMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
//forcing the post shadow technique
|
//forcing the post shadow technique and render state
|
||||||
renderManager.setForcedTechnique(postTechniqueName);
|
renderManager.setForcedTechnique(postTechniqueName);
|
||||||
|
|
||||||
//rendering the post shadow pass
|
//rendering the post shadow pass
|
||||||
@ -485,6 +496,9 @@ public class PssmShadowRenderer implements SceneProcessor {
|
|||||||
mat.setInt("FilterMode", filterMode.ordinal());
|
mat.setInt("FilterMode", filterMode.ordinal());
|
||||||
mat.setFloat("PCFEdge", edgesThickness);
|
mat.setFloat("PCFEdge", edgesThickness);
|
||||||
mat.setFloat("ShadowIntensity", shadowIntensity);
|
mat.setFloat("ShadowIntensity", shadowIntensity);
|
||||||
|
if(mat.getParam("ShadowMapSize") == null){
|
||||||
|
mat.setFloat("ShadowMapSize", shadowMapSize);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
needsfallBackMaterial = true;
|
needsfallBackMaterial = true;
|
||||||
}
|
}
|
||||||
|
@ -29,81 +29,118 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jme3test.light;
|
package jme3test.light;
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.font.BitmapText;
|
||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
import com.jme3.input.controls.ActionListener;
|
import com.jme3.input.controls.ActionListener;
|
||||||
import com.jme3.input.controls.KeyTrigger;
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
import com.jme3.scene.control.Control;
|
||||||
import com.jme3.scene.shape.Box;
|
import com.jme3.scene.shape.Box;
|
||||||
import com.jme3.scene.shape.Sphere;
|
import com.jme3.scene.shape.Sphere;
|
||||||
import com.jme3.shadow.PssmShadowRenderer;
|
import com.jme3.shadow.PssmShadowRenderer;
|
||||||
import com.jme3.shadow.PssmShadowRenderer.CompareMode;
|
import com.jme3.shadow.PssmShadowRenderer.CompareMode;
|
||||||
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
|
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
|
||||||
import java.util.Random;
|
import com.jme3.texture.Texture;
|
||||||
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
|
import com.jme3.util.SkyFactory;
|
||||||
|
import com.jme3.util.TangentBinormalGenerator;
|
||||||
|
|
||||||
public class TestPssmShadow extends SimpleApplication implements ActionListener {
|
public class TestPssmShadow extends SimpleApplication implements ActionListener {
|
||||||
|
|
||||||
private Spatial teapot;
|
private Spatial[] obj;
|
||||||
|
private Material[] mat;
|
||||||
private boolean renderShadows = true;
|
private boolean renderShadows = true;
|
||||||
private boolean hardwareShadows = false;
|
private boolean hardwareShadows = false;
|
||||||
private PssmShadowRenderer pssmRenderer;
|
private PssmShadowRenderer pssmRenderer;
|
||||||
|
private Geometry ground;
|
||||||
|
private Material matGroundU;
|
||||||
|
private Material matGroundL;
|
||||||
|
|
||||||
public static void main(String[] args){
|
|
||||||
|
public static void main(String[] args) {
|
||||||
TestPssmShadow app = new TestPssmShadow();
|
TestPssmShadow app = new TestPssmShadow();
|
||||||
app.start();
|
app.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadScene(){
|
public void loadScene() {
|
||||||
Material mat = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
|
obj = new Spatial[2];
|
||||||
Material matSoil = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
|
mat = new Material[2];
|
||||||
matSoil.setColor("Color", ColorRGBA.Cyan);
|
mat[0] = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
|
||||||
|
mat[1] = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
|
||||||
|
mat[1].setBoolean("UseMaterialColors", true);
|
||||||
|
mat[1].setColor("Ambient", ColorRGBA.White.mult(0.5f));
|
||||||
|
mat[1].setColor("Diffuse", ColorRGBA.White.clone());
|
||||||
|
|
||||||
teapot = new Geometry("sphere", new Sphere(30, 30, 2));
|
|
||||||
// teapot = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f));
|
|
||||||
// teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
|
|
||||||
teapot.setLocalTranslation(0,0,10);
|
|
||||||
|
|
||||||
teapot.setMaterial(mat);
|
obj[0] = new Geometry("sphere", new Sphere(30, 30, 2));
|
||||||
teapot.setShadowMode(ShadowMode.CastAndReceive);
|
obj[0].setShadowMode(ShadowMode.CastAndReceive);
|
||||||
rootNode.attachChild(teapot);
|
obj[1] = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f));
|
||||||
|
obj[1].setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
TangentBinormalGenerator.generate(obj[1]);
|
||||||
|
TangentBinormalGenerator.generate(obj[0]);
|
||||||
|
|
||||||
long seed = 1294719330150L; //System.currentTimeMillis();
|
|
||||||
Random random = new Random(seed);
|
|
||||||
System.out.println(seed);
|
|
||||||
|
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 60; i++) {
|
||||||
Spatial t = teapot.clone(false);
|
Spatial t = obj[FastMath.nextRandomInt(0, obj.length - 1)].clone(false);
|
||||||
|
t.setLocalScale(FastMath.nextRandomFloat() * 10f);
|
||||||
|
t.setMaterial(mat[FastMath.nextRandomInt(0, mat.length - 1)]);
|
||||||
rootNode.attachChild(t);
|
rootNode.attachChild(t);
|
||||||
teapot.setLocalTranslation((float) random.nextFloat() * 3, (float) random.nextFloat() * 3, (i + 2));
|
t.setLocalTranslation(FastMath.nextRandomFloat() * 200f, FastMath.nextRandomFloat() * 30f + 20, 30f * (i + 2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry soil = new Geometry("soil", new Box(new Vector3f(0, -13, 550), 800, 10, 700));
|
Box b = new Box(new Vector3f(0, 10, 550), 1000, 2, 1000);
|
||||||
soil.setMaterial(matSoil);
|
b.scaleTextureCoordinates(new Vector2f(10, 10));
|
||||||
soil.setShadowMode(ShadowMode.Receive);
|
ground = new Geometry("soil", b);
|
||||||
rootNode.attachChild(soil);
|
matGroundU = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
|
matGroundU.setColor("Color", ColorRGBA.Green);
|
||||||
|
|
||||||
for (int i = 0; i < 30; i++) {
|
|
||||||
Spatial t = teapot.clone(false);
|
matGroundL = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||||
t.setLocalScale(10.0f);
|
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
|
||||||
rootNode.attachChild(t);
|
grass.setWrap(WrapMode.Repeat);
|
||||||
teapot.setLocalTranslation((float) random.nextFloat() * 300, (float) random.nextFloat() * 30, 30 * (i + 2));
|
matGroundL.setTexture("DiffuseMap", grass);
|
||||||
}
|
|
||||||
|
ground.setMaterial(matGroundL);
|
||||||
|
|
||||||
|
ground.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
rootNode.attachChild(ground);
|
||||||
|
|
||||||
|
DirectionalLight l = new DirectionalLight();
|
||||||
|
l.setDirection(new Vector3f(-1, -1, -1));
|
||||||
|
rootNode.addLight(l);
|
||||||
|
|
||||||
|
AmbientLight al = new AmbientLight();
|
||||||
|
al.setColor(ColorRGBA.White.mult(0.5f));
|
||||||
|
rootNode.addLight(al);
|
||||||
|
|
||||||
|
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
||||||
|
sky.setLocalScale(350);
|
||||||
|
|
||||||
|
rootNode.attachChild(sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
// put the camera in a bad position
|
// put the camera in a bad position
|
||||||
cam.setLocation(new Vector3f(41.59757f, 34.38738f, 11.528807f));
|
cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f));
|
||||||
cam.setRotation(new Quaternion(0.2905285f, 0.3816416f, -0.12772122f, 0.86811876f));
|
cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f));
|
||||||
|
|
||||||
flyCam.setMoveSpeed(100);
|
flyCam.setMoveSpeed(100);
|
||||||
|
|
||||||
loadScene();
|
loadScene();
|
||||||
@ -113,14 +150,22 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
|
|||||||
pssmRenderer.setLambda(0.55f);
|
pssmRenderer.setLambda(0.55f);
|
||||||
pssmRenderer.setShadowIntensity(0.6f);
|
pssmRenderer.setShadowIntensity(0.6f);
|
||||||
pssmRenderer.setCompareMode(CompareMode.Software);
|
pssmRenderer.setCompareMode(CompareMode.Software);
|
||||||
pssmRenderer.setFilterMode(FilterMode.Bilinear);
|
pssmRenderer.setFilterMode(FilterMode.Dither);
|
||||||
pssmRenderer.displayDebug();
|
pssmRenderer.displayDebug();
|
||||||
viewPort.addProcessor(pssmRenderer);
|
viewPort.addProcessor(pssmRenderer);
|
||||||
initInputs();
|
initInputs();
|
||||||
}
|
}
|
||||||
|
BitmapText infoText;
|
||||||
|
|
||||||
|
private void initInputs() {
|
||||||
|
/** Write text on the screen (HUD) */
|
||||||
|
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
|
||||||
|
infoText = new BitmapText(guiFont, false);
|
||||||
|
infoText.setSize(guiFont.getCharSet().getRenderedSize());
|
||||||
|
|
||||||
|
|
||||||
private void initInputs() {
|
|
||||||
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
|
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
|
||||||
|
inputManager.addMapping("changeFiltering", new KeyTrigger(KeyInput.KEY_F));
|
||||||
inputManager.addMapping("ShadowUp", new KeyTrigger(KeyInput.KEY_T));
|
inputManager.addMapping("ShadowUp", new KeyTrigger(KeyInput.KEY_T));
|
||||||
inputManager.addMapping("ShadowDown", new KeyTrigger(KeyInput.KEY_G));
|
inputManager.addMapping("ShadowDown", new KeyTrigger(KeyInput.KEY_G));
|
||||||
inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y));
|
inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y));
|
||||||
@ -128,9 +173,46 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
|
|||||||
inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U));
|
inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U));
|
||||||
inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J));
|
inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J));
|
||||||
inputManager.addMapping("toggleHW", new KeyTrigger(KeyInput.KEY_RETURN));
|
inputManager.addMapping("toggleHW", new KeyTrigger(KeyInput.KEY_RETURN));
|
||||||
inputManager.addListener(this, "lambdaUp", "lambdaDown", "toggleHW", "toggle", "ShadowUp","ShadowDown","ThicknessUp","ThicknessDown");
|
inputManager.addMapping("switchGroundMat", new KeyTrigger(KeyInput.KEY_M));
|
||||||
|
inputManager.addListener(this, "lambdaUp", "lambdaDown", "toggleHW", "toggle", "ShadowUp", "ShadowDown", "ThicknessUp", "ThicknessDown","changeFiltering","switchGroundMat");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void print(String str) {
|
||||||
|
infoText.setText(str);
|
||||||
|
infoText.setLocalTranslation(cam.getWidth() * 0.5f - infoText.getLineWidth() * 0.5f, infoText.getLineHeight(), 0);
|
||||||
|
guiNode.attachChild(infoText);
|
||||||
|
infoText.removeControl(ctrl);
|
||||||
|
infoText.addControl(ctrl);
|
||||||
|
}
|
||||||
|
AbstractControl ctrl = new AbstractControl() {
|
||||||
|
|
||||||
|
float time;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
time += tpf;
|
||||||
|
if (time > 3) {
|
||||||
|
spatial.removeFromParent();
|
||||||
|
spatial.removeControl(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpatial(Spatial spatial) {
|
||||||
|
super.setSpatial(spatial);
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Control cloneForSpatial(Spatial spatial) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
int filteringIndex = 2;
|
||||||
|
|
||||||
public void onAction(String name, boolean keyPressed, float tpf) {
|
public void onAction(String name, boolean keyPressed, float tpf) {
|
||||||
if (name.equals("toggle") && keyPressed) {
|
if (name.equals("toggle") && keyPressed) {
|
||||||
if (renderShadows) {
|
if (renderShadows) {
|
||||||
@ -146,6 +228,13 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
|
|||||||
System.out.println("HW Shadows: " + hardwareShadows);
|
System.out.println("HW Shadows: " + hardwareShadows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.equals("changeFiltering") && keyPressed) {
|
||||||
|
filteringIndex = (filteringIndex + 1) % FilterMode.values().length;
|
||||||
|
FilterMode m = FilterMode.values()[filteringIndex];
|
||||||
|
pssmRenderer.setFilterMode(m);
|
||||||
|
print("Filter mode : " + m.toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (name.equals("lambdaUp") && keyPressed) {
|
if (name.equals("lambdaUp") && keyPressed) {
|
||||||
pssmRenderer.setLambda(pssmRenderer.getLambda() + 0.01f);
|
pssmRenderer.setLambda(pssmRenderer.getLambda() + 0.01f);
|
||||||
System.out.println("Lambda : " + pssmRenderer.getLambda());
|
System.out.println("Lambda : " + pssmRenderer.getLambda());
|
||||||
@ -170,7 +259,13 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
|
|||||||
pssmRenderer.setEdgesThickness(pssmRenderer.getEdgesThickness() - 1);
|
pssmRenderer.setEdgesThickness(pssmRenderer.getEdgesThickness() - 1);
|
||||||
System.out.println("Shadow thickness : " + pssmRenderer.getEdgesThickness());
|
System.out.println("Shadow thickness : " + pssmRenderer.getEdgesThickness());
|
||||||
}
|
}
|
||||||
|
if (name.equals("switchGroundMat") && keyPressed) {
|
||||||
|
if(ground.getMaterial() == matGroundL){
|
||||||
|
ground.setMaterial(matGroundU);
|
||||||
|
}else{
|
||||||
|
ground.setMaterial(matGroundL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class TestTransparentShadow extends SimpleApplication {
|
|||||||
|
|
||||||
geom.rotate(-FastMath.HALF_PI, 0, 0);
|
geom.rotate(-FastMath.HALF_PI, 0, 0);
|
||||||
geom.center();
|
geom.center();
|
||||||
geom.setShadowMode(ShadowMode.Receive);
|
geom.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
rootNode.attachChild(geom);
|
rootNode.attachChild(geom);
|
||||||
|
|
||||||
// create the geometry and attach it
|
// create the geometry and attach it
|
||||||
@ -132,6 +132,6 @@ public class TestTransparentShadow extends SimpleApplication {
|
|||||||
pssmRenderer.setCompareMode(CompareMode.Software);
|
pssmRenderer.setCompareMode(CompareMode.Software);
|
||||||
pssmRenderer.setFilterMode(FilterMode.PCF4);
|
pssmRenderer.setFilterMode(FilterMode.PCF4);
|
||||||
//pssmRenderer.displayDebug();
|
//pssmRenderer.displayDebug();
|
||||||
viewPort.addProcessor(pssmRenderer);
|
viewPort.addProcessor(pssmRenderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
|||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.scene.shape.Quad;
|
import com.jme3.scene.shape.Quad;
|
||||||
|
import com.jme3.util.TangentBinormalGenerator;
|
||||||
|
|
||||||
public class TestTransparentSSAO extends SimpleApplication {
|
public class TestTransparentSSAO extends SimpleApplication {
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ public class TestTransparentSSAO extends SimpleApplication {
|
|||||||
geom.rotate(-FastMath.HALF_PI, 0, 0);
|
geom.rotate(-FastMath.HALF_PI, 0, 0);
|
||||||
geom.center();
|
geom.center();
|
||||||
geom.setShadowMode(ShadowMode.Receive);
|
geom.setShadowMode(ShadowMode.Receive);
|
||||||
|
TangentBinormalGenerator.generate(geom);
|
||||||
rootNode.attachChild(geom);
|
rootNode.attachChild(geom);
|
||||||
|
|
||||||
// create the geometry and attach it
|
// create the geometry and attach it
|
||||||
@ -64,7 +66,7 @@ public class TestTransparentSSAO extends SimpleApplication {
|
|||||||
|
|
||||||
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
|
|
||||||
SSAOFilter ssao = new SSAOFilter(0.49997783f, 42.598858f, 35.999966f, 0.39299846f);
|
SSAOFilter ssao = new SSAOFilter();//0.49997783f, 42.598858f, 35.999966f, 0.39299846f
|
||||||
fpp.addFilter(ssao);
|
fpp.addFilter(ssao);
|
||||||
|
|
||||||
SSAOUI ui = new SSAOUI(inputManager, ssao);
|
SSAOUI ui = new SSAOUI(inputManager, ssao);
|
||||||
|
@ -5,6 +5,7 @@ Material Leaves : Common/MatDefs/Light/Lighting.j3md {
|
|||||||
MaterialParameters {
|
MaterialParameters {
|
||||||
DiffuseMap : Models/Tree/Leaves.png
|
DiffuseMap : Models/Tree/Leaves.png
|
||||||
UseAlpha : true
|
UseAlpha : true
|
||||||
|
AlphaDiscardThreshold : 0.5
|
||||||
UseMaterialColors : true
|
UseMaterialColors : true
|
||||||
Ambient : .5 .5 .5 .5
|
Ambient : .5 .5 .5 .5
|
||||||
Diffuse : 0.7 0.7 0.7 1
|
Diffuse : 0.7 0.7 0.7 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user