Merge branch 'master' of https://github.com/jMonkeyEngine/jmonkeyengine.git
This commit is contained in:
commit
a9a1544681
@ -37,6 +37,7 @@ import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector4f;
|
||||
import com.jme3.post.Filter;
|
||||
@ -44,6 +45,7 @@ import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -74,6 +76,9 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
|
||||
material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");
|
||||
this.shadowRenderer = shadowRenderer;
|
||||
this.shadowRenderer.setPostShadowMaterial(material);
|
||||
|
||||
//this is legacy setting for shadows with backface shadows
|
||||
this.shadowRenderer.setRenderBackFacesShadows(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,7 +131,7 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
|
||||
/**
|
||||
* How far the shadows are rendered in the view
|
||||
*
|
||||
* @see setShadowZExtend(float zFar)
|
||||
* @see #setShadowZExtend(float zFar)
|
||||
* @return shadowZExtend
|
||||
*/
|
||||
public float getShadowZExtend() {
|
||||
@ -248,6 +253,46 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
|
||||
shadowRenderer.setEdgeFilteringMode(filterMode);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* !! WARNING !! this parameter is defaulted to true for the ShadowFilter.
|
||||
* Setting it to true, may produce edges artifacts on shadows. *
|
||||
*
|
||||
* Set to true if you want back faces shadows on geometries.
|
||||
* Note that back faces shadows will be blended over dark lighten areas and may produce overly dark lighting.
|
||||
*
|
||||
* Setting this parameter will override this parameter for ALL materials in the scene.
|
||||
* This also will automatically adjust the faceCullMode and the PolyOffset of the pre shadow pass.
|
||||
* You can modify them by using {@link #getPreShadowForcedRenderState()}
|
||||
*
|
||||
* If you want to set it differently for each material in the scene you have to use the ShadowRenderer instead
|
||||
* of the shadow filter.
|
||||
*
|
||||
* @param renderBackFacesShadows true or false.
|
||||
*/
|
||||
public void setRenderBackFacesShadows(Boolean renderBackFacesShadows) {
|
||||
shadowRenderer.setRenderBackFacesShadows(renderBackFacesShadows);
|
||||
}
|
||||
|
||||
/**
|
||||
* if this filter renders back faces shadows
|
||||
* @return true if this filter renders back faces shadows
|
||||
*/
|
||||
public boolean isRenderBackFacesShadows() {
|
||||
return shadowRenderer.isRenderBackFacesShadows();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the pre shadows pass render state.
|
||||
* use it to adjust the RenderState parameters of the pre shadow pass.
|
||||
* Note that this will be overriden if the preShadow technique in the material has a ForcedRenderState
|
||||
* @return the pre shadow render state.
|
||||
*/
|
||||
public RenderState getPreShadowForcedRenderState() {
|
||||
return shadowRenderer.getPreShadowForcedRenderState();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the the edge filtering mode
|
||||
*
|
||||
|
@ -31,10 +31,6 @@
|
||||
*/
|
||||
package com.jme3.shadow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
@ -42,6 +38,7 @@ import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.export.Savable;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector2f;
|
||||
@ -67,6 +64,10 @@ import com.jme3.texture.Texture.ShadowCompareMode;
|
||||
import com.jme3.texture.Texture2D;
|
||||
import com.jme3.ui.Picture;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* abstract shadow renderer that holds commons feature to have for a shadow
|
||||
* renderer
|
||||
@ -92,6 +93,8 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
|
||||
protected CompareMode shadowCompareMode = CompareMode.Hardware;
|
||||
protected Picture[] dispPic;
|
||||
protected RenderState forcedRenderState = new RenderState();
|
||||
protected Boolean renderBackFacesShadows;
|
||||
|
||||
/**
|
||||
* true if the fallback material should be used, otherwise false
|
||||
@ -182,6 +185,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
setShadowCompareMode(shadowCompareMode);
|
||||
setEdgeFilteringMode(edgeFilteringMode);
|
||||
setShadowIntensity(shadowIntensity);
|
||||
initForcedRenderState();
|
||||
}
|
||||
|
||||
protected void initForcedRenderState() {
|
||||
forcedRenderState.setFaceCullMode(RenderState.FaceCullMode.Front);
|
||||
forcedRenderState.setColorWrite(false);
|
||||
forcedRenderState.setDepthWrite(true);
|
||||
forcedRenderState.setDepthTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,9 +368,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
* rendered in the shadow map
|
||||
*
|
||||
* @param shadowMapIndex the index of the shadow map being rendered
|
||||
* @param sceneOccluders the occluders of the whole scene
|
||||
* @param sceneReceivers the receivers of the whole scene
|
||||
* @param shadowMapOcculders
|
||||
* @param shadowMapOccluders the list of occluders
|
||||
* @return
|
||||
*/
|
||||
protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders);
|
||||
@ -426,9 +435,11 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
|
||||
renderManager.getRenderer().setFrameBuffer(shadowFB[shadowMapIndex]);
|
||||
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||
renderManager.setForcedRenderState(forcedRenderState);
|
||||
|
||||
// render shadow casters to shadow map
|
||||
viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
|
||||
renderManager.setForcedRenderState(null);
|
||||
}
|
||||
boolean debugfrustums = false;
|
||||
|
||||
@ -536,18 +547,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
private void setMatParams(GeometryList l) {
|
||||
//iteration throught all the geometries of the list to gather the materials
|
||||
|
||||
matCache.clear();
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
Material mat = l.get(i).getMaterial();
|
||||
//checking if the material has the post technique and adding it to the material cache
|
||||
if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) {
|
||||
if (!matCache.contains(mat)) {
|
||||
matCache.add(mat);
|
||||
}
|
||||
} else {
|
||||
needsfallBackMaterial = true;
|
||||
}
|
||||
}
|
||||
buildMatCache(l);
|
||||
|
||||
//iterating through the mat cache and setting the parameters
|
||||
for (Material mat : matCache) {
|
||||
@ -567,6 +567,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
if (fadeInfo != null) {
|
||||
mat.setVector2("FadeInfo", fadeInfo);
|
||||
}
|
||||
if(renderBackFacesShadows != null){
|
||||
mat.setBoolean("BackfaceShadows", renderBackFacesShadows);
|
||||
}
|
||||
|
||||
setMaterialParameters(mat);
|
||||
}
|
||||
|
||||
@ -578,6 +582,21 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
|
||||
}
|
||||
|
||||
private void buildMatCache(GeometryList l) {
|
||||
matCache.clear();
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
Material mat = l.get(i).getMaterial();
|
||||
//checking if the material has the post technique and adding it to the material cache
|
||||
if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) {
|
||||
if (!matCache.contains(mat)) {
|
||||
matCache.add(mat);
|
||||
}
|
||||
} else {
|
||||
needsfallBackMaterial = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for internal use only
|
||||
*/
|
||||
@ -590,6 +609,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
if (fadeInfo != null) {
|
||||
postshadowMat.setVector2("FadeInfo", fadeInfo);
|
||||
}
|
||||
if(renderBackFacesShadows != null){
|
||||
postshadowMat.setBoolean("BackfaceShadows", renderBackFacesShadows);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -731,6 +753,48 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
||||
@Deprecated
|
||||
public void setFlushQueues(boolean flushQueues) {}
|
||||
|
||||
|
||||
/**
|
||||
* returns the pre shadows pass render state.
|
||||
* use it to adjust the RenderState parameters of the pre shadow pass.
|
||||
* Note that this will be overriden if the preShadow technique in the material has a ForcedRenderState
|
||||
* @return the pre shadow render state.
|
||||
*/
|
||||
public RenderState getPreShadowForcedRenderState() {
|
||||
return forcedRenderState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if you want back faces shadows on geometries.
|
||||
* Note that back faces shadows will be blended over dark lighten areas and may produce overly dark lighting.
|
||||
*
|
||||
* Also note that setting this parameter will override this parameter for ALL materials in the scene.
|
||||
* You can alternatively change this parameter on a single material using {@link Material#setBoolean(String, boolean)}
|
||||
*
|
||||
* This also will automatically adjust the faceCullMode and the PolyOffset of the pre shadow pass.
|
||||
* You can modify them by using {@link #getPreShadowForcedRenderState()}
|
||||
*
|
||||
* @param renderBackFacesShadows true or false.
|
||||
*/
|
||||
public void setRenderBackFacesShadows(Boolean renderBackFacesShadows) {
|
||||
this.renderBackFacesShadows = renderBackFacesShadows;
|
||||
if(renderBackFacesShadows) {
|
||||
getPreShadowForcedRenderState().setPolyOffset(5, 3);
|
||||
getPreShadowForcedRenderState().setFaceCullMode(RenderState.FaceCullMode.Back);
|
||||
}else{
|
||||
getPreShadowForcedRenderState().setPolyOffset(0, 0);
|
||||
getPreShadowForcedRenderState().setFaceCullMode(RenderState.FaceCullMode.Front);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if this processor renders back faces shadows
|
||||
* @return true if this processor renders back faces shadows
|
||||
*/
|
||||
public boolean isRenderBackFacesShadows() {
|
||||
return renderBackFacesShadows != null?renderBackFacesShadows:false;
|
||||
}
|
||||
|
||||
/**
|
||||
* De-serialize this instance, for example when loading from a J3O file.
|
||||
*
|
||||
|
@ -215,6 +215,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
||||
@Override
|
||||
protected void setMaterialParameters(Material material) {
|
||||
material.setColor("Splits", splits);
|
||||
material.setVector3("LightDir", light.getDirection());
|
||||
if (fadeInfo != null) {
|
||||
material.setVector2("FadeInfo", fadeInfo);
|
||||
}
|
||||
@ -224,6 +225,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
||||
protected void clearMaterialParameters(Material material) {
|
||||
material.clearParam("Splits");
|
||||
material.clearParam("FadeInfo");
|
||||
material.clearParam("LightDir");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,6 +113,8 @@ MaterialDef Phong Lighting {
|
||||
|
||||
//For instancing
|
||||
Boolean UseInstancing
|
||||
|
||||
Boolean BackfaceShadows: false
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -213,14 +215,6 @@ MaterialDef Phong Lighting {
|
||||
INSTANCING : UseInstancing
|
||||
}
|
||||
|
||||
ForcedRenderState {
|
||||
FaceCull Off
|
||||
DepthTest On
|
||||
DepthWrite On
|
||||
PolyOffset 5 3
|
||||
ColorWrite Off
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -233,6 +227,7 @@ MaterialDef Phong Lighting {
|
||||
WorldMatrix
|
||||
ViewProjectionMatrix
|
||||
ViewMatrix
|
||||
NormalMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
@ -247,6 +242,7 @@ MaterialDef Phong Lighting {
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
NUM_BONES : NumberOfBones
|
||||
INSTANCING : UseInstancing
|
||||
BACKFACE_SHADOWS: BackfaceShadows
|
||||
}
|
||||
|
||||
ForcedRenderState {
|
||||
@ -265,6 +261,7 @@ MaterialDef Phong Lighting {
|
||||
WorldMatrix
|
||||
ViewProjectionMatrix
|
||||
ViewMatrix
|
||||
NormalMatrix
|
||||
}
|
||||
|
||||
Defines {
|
||||
|
@ -51,6 +51,8 @@ MaterialDef Unshaded {
|
||||
Float PCFEdge
|
||||
|
||||
Float ShadowMapSize
|
||||
|
||||
Boolean BackfaceShadows: true
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -169,6 +171,7 @@ MaterialDef Unshaded {
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
NUM_BONES : NumberOfBones
|
||||
INSTANCING : UseInstancing
|
||||
BACKFACE_SHADOWS: BackfaceShadows
|
||||
}
|
||||
|
||||
ForcedRenderState {
|
||||
@ -201,6 +204,7 @@ MaterialDef Unshaded {
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
NUM_BONES : NumberOfBones
|
||||
INSTANCING : UseInstancing
|
||||
BACKFACE_SHADOWS: BackfaceShadows
|
||||
}
|
||||
|
||||
ForcedRenderState {
|
||||
|
@ -9,6 +9,9 @@ varying vec4 projCoord0;
|
||||
varying vec4 projCoord1;
|
||||
varying vec4 projCoord2;
|
||||
varying vec4 projCoord3;
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
varying float nDotL;
|
||||
#endif
|
||||
|
||||
#ifdef POINTLIGHT
|
||||
varying vec4 projCoord4;
|
||||
@ -46,9 +49,15 @@ void main(){
|
||||
if(alpha<=m_AlphaDiscardThreshold){
|
||||
discard;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
if(nDotL > 0.0){
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
float shadow = 1.0;
|
||||
|
||||
#ifdef POINTLIGHT
|
||||
@ -73,8 +82,8 @@ void main(){
|
||||
#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);
|
||||
|
||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ MaterialDef Post Shadow {
|
||||
|
||||
Float ShadowMapSize
|
||||
|
||||
Boolean BackfaceShadows: false
|
||||
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -49,6 +51,7 @@ MaterialDef Post Shadow {
|
||||
FADE : FadeInfo
|
||||
PSSM : Splits
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
BACKFACE_SHADOWS: BackfaceShadows
|
||||
}
|
||||
|
||||
RenderState {
|
||||
@ -75,6 +78,7 @@ MaterialDef Post Shadow {
|
||||
FADE : FadeInfo
|
||||
PSSM : Splits
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
BACKFACE_SHADOWS: BackfaceShadows
|
||||
}
|
||||
|
||||
RenderState {
|
||||
|
@ -7,7 +7,6 @@ uniform mat4 m_LightViewProjectionMatrix1;
|
||||
uniform mat4 m_LightViewProjectionMatrix2;
|
||||
uniform mat4 m_LightViewProjectionMatrix3;
|
||||
|
||||
uniform vec3 m_LightPos;
|
||||
|
||||
varying vec4 projCoord0;
|
||||
varying vec4 projCoord1;
|
||||
@ -17,12 +16,14 @@ varying vec4 projCoord3;
|
||||
#ifdef POINTLIGHT
|
||||
uniform mat4 m_LightViewProjectionMatrix4;
|
||||
uniform mat4 m_LightViewProjectionMatrix5;
|
||||
uniform vec3 m_LightPos;
|
||||
varying vec4 projCoord4;
|
||||
varying vec4 projCoord5;
|
||||
varying vec4 worldPos;
|
||||
#else
|
||||
#ifndef PSSM
|
||||
uniform vec3 m_LightDir;
|
||||
#ifndef PSSM
|
||||
uniform vec3 m_LightPos;
|
||||
varying float lightDot;
|
||||
#endif
|
||||
#endif
|
||||
@ -30,12 +31,15 @@ varying vec4 projCoord3;
|
||||
#if defined(PSSM) || defined(FADE)
|
||||
varying float shadowPosition;
|
||||
#endif
|
||||
varying vec3 lightVec;
|
||||
|
||||
varying vec2 texCoord;
|
||||
|
||||
attribute vec3 inPosition;
|
||||
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
attribute vec3 inNormal;
|
||||
varying float nDotL;
|
||||
#endif
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
attribute vec2 inTexCoord;
|
||||
#endif
|
||||
@ -53,6 +57,7 @@ void main(){
|
||||
Skinning_Compute(modelSpacePos);
|
||||
#endif
|
||||
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
||||
vec3 lightDir;
|
||||
|
||||
#if defined(PSSM) || defined(FADE)
|
||||
shadowPosition = gl_Position.z;
|
||||
@ -62,7 +67,7 @@ void main(){
|
||||
vec4 worldPos=vec4(0.0);
|
||||
#endif
|
||||
// get the vertex in world space
|
||||
worldPos = g_WorldMatrix * modelSpacePos;
|
||||
worldPos = TransformWorld(modelSpacePos);
|
||||
|
||||
#ifdef DISCARD_ALPHA
|
||||
texCoord = inTexCoord;
|
||||
@ -77,8 +82,21 @@ void main(){
|
||||
projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos;
|
||||
#else
|
||||
#ifndef PSSM
|
||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
||||
//Spot light
|
||||
lightDir = worldPos.xyz - m_LightPos;
|
||||
lightDot = dot(m_LightDir,lightDir);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
vec3 normal = normalize(TransformWorld(vec4(inNormal,0.0))).xyz;
|
||||
#ifdef POINTLIGHT
|
||||
lightDir = worldPos.xyz - m_LightPos;
|
||||
#else
|
||||
#ifdef PSSM
|
||||
lightDir = m_LightDir;
|
||||
#endif
|
||||
#endif
|
||||
nDotL = dot(normal, lightDir);
|
||||
#endif
|
||||
}
|
@ -18,6 +18,8 @@ uniform mat4 m_LightViewProjectionMatrix1;
|
||||
uniform mat4 m_LightViewProjectionMatrix2;
|
||||
uniform mat4 m_LightViewProjectionMatrix3;
|
||||
|
||||
uniform vec2 g_ResolutionInverse;
|
||||
|
||||
#ifdef POINTLIGHT
|
||||
uniform vec3 m_LightPos;
|
||||
uniform mat4 m_LightViewProjectionMatrix4;
|
||||
@ -39,6 +41,19 @@ vec3 getPosition(in float depth, in vec2 uv){
|
||||
return pos.xyz / pos.w;
|
||||
}
|
||||
|
||||
vec3 approximateNormal(in vec4 worldPos,in vec2 texCoord){
|
||||
float step = g_ResolutionInverse.x ;
|
||||
float stepy = g_ResolutionInverse.y ;
|
||||
float depth2 = texture2D(m_DepthTexture,texCoord + vec2(step,-stepy)).r;
|
||||
float depth3 = texture2D(m_DepthTexture,texCoord + vec2(-step,-stepy)).r;
|
||||
vec4 worldPos2 = vec4(getPosition(depth2,texCoord + vec2(step,-stepy)),1.0);
|
||||
vec4 worldPos3 = vec4(getPosition(depth3,texCoord + vec2(-step,-stepy)),1.0);
|
||||
|
||||
vec3 v1 = (worldPos - worldPos2).xyz;
|
||||
vec3 v2 = (worldPos3 - worldPos2).xyz;
|
||||
return normalize(cross(v1, v2));
|
||||
}
|
||||
|
||||
void main(){
|
||||
#if !defined( RENDER_SHADOWS )
|
||||
gl_FragColor = texture2D(m_Texture,texCoord);
|
||||
@ -48,6 +63,7 @@ void main(){
|
||||
float depth = texture2D(m_DepthTexture,texCoord).r;
|
||||
vec4 color = texture2D(m_Texture,texCoord);
|
||||
|
||||
|
||||
//Discard shadow computation on the sky
|
||||
if(depth == 1.0){
|
||||
gl_FragColor = color;
|
||||
@ -56,6 +72,19 @@ void main(){
|
||||
|
||||
// get the vertex in world space
|
||||
vec4 worldPos = vec4(getPosition(depth,texCoord),1.0);
|
||||
vec3 normal = approximateNormal(worldPos, texCoord);
|
||||
|
||||
vec3 lightDir;
|
||||
#ifdef PSSM
|
||||
lightDir = m_LightDir;
|
||||
#else
|
||||
lightDir = worldPos.xyz - m_LightPos;
|
||||
#endif
|
||||
float ndotl = dot(normal, lightDir);
|
||||
if(ndotl > -0.0){
|
||||
gl_FragColor = color;
|
||||
return;
|
||||
}
|
||||
|
||||
#if (!defined(POINTLIGHT) && !defined(PSSM))
|
||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
||||
|
@ -38,6 +38,7 @@ MaterialDef Post Shadow {
|
||||
Texture2D Texture
|
||||
Texture2D DepthTexture
|
||||
|
||||
Boolean BackfaceShadows: true
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -45,6 +46,7 @@ MaterialDef Post Shadow {
|
||||
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.frag
|
||||
|
||||
WorldParameters {
|
||||
ResolutionInverse
|
||||
}
|
||||
|
||||
Defines {
|
||||
@ -59,7 +61,7 @@ MaterialDef Post Shadow {
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
//if no shadow map don't render shadows
|
||||
RENDER_SHADOWS : ShadowMap0
|
||||
|
||||
BACKFACE_SHADOWS : BackfaceShadows
|
||||
}
|
||||
|
||||
}
|
||||
@ -69,6 +71,7 @@ MaterialDef Post Shadow {
|
||||
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag
|
||||
|
||||
WorldParameters {
|
||||
ResolutionInverse
|
||||
}
|
||||
|
||||
Defines {
|
||||
@ -79,6 +82,7 @@ MaterialDef Post Shadow {
|
||||
FADE : FadeInfo
|
||||
PSSM : Splits
|
||||
POINTLIGHT : LightViewProjectionMatrix5
|
||||
BACKFACE_SHADOWS : BackfaceShadows
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,14 +20,16 @@ uniform mat4 m_LightViewProjectionMatrix1;
|
||||
uniform mat4 m_LightViewProjectionMatrix2;
|
||||
uniform mat4 m_LightViewProjectionMatrix3;
|
||||
|
||||
uniform vec2 g_ResolutionInverse;
|
||||
|
||||
#ifdef POINTLIGHT
|
||||
uniform vec3 m_LightPos;
|
||||
uniform mat4 m_LightViewProjectionMatrix4;
|
||||
uniform mat4 m_LightViewProjectionMatrix5;
|
||||
#else
|
||||
uniform vec3 m_LightDir;
|
||||
#ifndef PSSM
|
||||
uniform vec3 m_LightPos;
|
||||
uniform vec3 m_LightDir;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -41,6 +43,23 @@ vec3 getPosition(in float depth, in vec2 uv){
|
||||
return pos.xyz / pos.w;
|
||||
}
|
||||
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
vec3 approximateNormal(in float depth,in vec4 worldPos,in vec2 texCoord, in int numSample){
|
||||
float step = g_ResolutionInverse.x ;
|
||||
float stepy = g_ResolutionInverse.y ;
|
||||
float depth1 = fetchTextureSample(m_DepthTexture,texCoord + vec2(-step,stepy),numSample).r;
|
||||
float depth2 = fetchTextureSample(m_DepthTexture,texCoord + vec2(step,stepy),numSample).r;
|
||||
vec3 v1, v2;
|
||||
vec4 worldPos1 = vec4(getPosition(depth1,texCoord + vec2(-step,stepy)),1.0);
|
||||
vec4 worldPos2 = vec4(getPosition(depth2,texCoord + vec2(step,stepy)),1.0);
|
||||
|
||||
v1 = normalize((worldPos1 - worldPos)).xyz;
|
||||
v2 = normalize((worldPos2 - worldPos)).xyz;
|
||||
return normalize(cross(v2, v1));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 main_multiSample(in int numSample){
|
||||
float depth = fetchTextureSample(m_DepthTexture,texCoord,numSample).r;//getDepth(m_DepthTexture,texCoord).r;
|
||||
vec4 color = fetchTextureSample(m_Texture,texCoord,numSample);
|
||||
@ -53,8 +72,23 @@ vec4 main_multiSample(in int numSample){
|
||||
// get the vertex in world space
|
||||
vec4 worldPos = vec4(getPosition(depth,texCoord),1.0);
|
||||
|
||||
|
||||
vec3 lightDir;
|
||||
#ifdef PSSM
|
||||
lightDir = m_LightDir;
|
||||
#else
|
||||
lightDir = worldPos.xyz - m_LightPos;
|
||||
#endif
|
||||
|
||||
#ifndef BACKFACE_SHADOWS
|
||||
vec3 normal = approximateNormal(depth, worldPos, texCoord, numSample);
|
||||
float ndotl = dot(normal, lightDir);
|
||||
if(ndotl > 0.0){
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (!defined(POINTLIGHT) && !defined(PSSM))
|
||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
||||
if( dot(m_LightDir,lightDir)<0){
|
||||
return color;
|
||||
}
|
||||
|
@ -40,12 +40,14 @@ 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.RenderState;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.FilterPostProcessor;
|
||||
import com.jme3.post.ssao.SSAOFilter;
|
||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Spatial;
|
||||
@ -69,6 +71,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
private Geometry ground;
|
||||
private Material matGroundU;
|
||||
private Material matGroundL;
|
||||
private AmbientLight al;
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestDirectionalLightShadow app = new TestDirectionalLightShadow();
|
||||
@ -99,7 +102,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
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("Ambient", ColorRGBA.White);
|
||||
mat[1].setColor("Diffuse", ColorRGBA.White.clone());
|
||||
|
||||
|
||||
@ -110,9 +113,14 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
TangentBinormalGenerator.generate(obj[1]);
|
||||
TangentBinormalGenerator.generate(obj[0]);
|
||||
|
||||
Spatial t = obj[0].clone(false);
|
||||
t.setLocalScale(10f);
|
||||
t.setMaterial(mat[1]);
|
||||
rootNode.attachChild(t);
|
||||
t.setLocalTranslation(0, 25, 0);
|
||||
|
||||
for (int i = 0; i < 60; i++) {
|
||||
Spatial t = obj[FastMath.nextRandomInt(0, obj.length - 1)].clone(false);
|
||||
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);
|
||||
@ -142,8 +150,8 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
rootNode.addLight(l);
|
||||
|
||||
|
||||
AmbientLight al = new AmbientLight();
|
||||
al.setColor(ColorRGBA.White.mult(0.5f));
|
||||
al = new AmbientLight();
|
||||
al.setColor(ColorRGBA.White.mult(0.02f));
|
||||
rootNode.addLight(al);
|
||||
|
||||
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
||||
@ -156,8 +164,11 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
@Override
|
||||
public void simpleInitApp() {
|
||||
// put the camera in a bad position
|
||||
cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f));
|
||||
cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f));
|
||||
// cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f));
|
||||
// cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f));
|
||||
|
||||
cam.setLocation(new Vector3f(3.3720117f, 42.838284f, -83.43792f));
|
||||
cam.setRotation(new Quaternion(0.13833192f, -0.08969371f, 0.012581267f, 0.9862358f));
|
||||
|
||||
flyCam.setMoveSpeed(100);
|
||||
|
||||
@ -166,7 +177,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3);
|
||||
dlsr.setLight(l);
|
||||
dlsr.setLambda(0.55f);
|
||||
dlsr.setShadowIntensity(0.6f);
|
||||
dlsr.setShadowIntensity(0.8f);
|
||||
dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||
dlsr.displayDebug();
|
||||
viewPort.addProcessor(dlsr);
|
||||
@ -174,7 +185,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
|
||||
dlsf.setLight(l);
|
||||
dlsf.setLambda(0.55f);
|
||||
dlsf.setShadowIntensity(0.6f);
|
||||
dlsf.setShadowIntensity(0.8f);
|
||||
dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||
dlsf.setEnabled(false);
|
||||
|
||||
@ -205,10 +216,11 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP));
|
||||
inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN));
|
||||
inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P));
|
||||
inputManager.addMapping("backShadows", new KeyTrigger(KeyInput.KEY_B));
|
||||
|
||||
|
||||
inputManager.addListener(this, "lambdaUp", "lambdaDown", "ThicknessUp", "ThicknessDown",
|
||||
"switchGroundMat", "debug", "up", "down", "right", "left", "fwd", "back", "pp", "stabilize", "distance");
|
||||
"switchGroundMat", "debug", "up", "down", "right", "left", "fwd", "back", "pp", "stabilize", "distance", "ShadowUp", "ShadowDown", "backShadows");
|
||||
|
||||
ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort);
|
||||
|
||||
@ -255,12 +267,19 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
||||
dlsf.setLambda(dlsr.getLambda() - 0.01f);
|
||||
System.out.println("Lambda : " + dlsr.getLambda());
|
||||
}
|
||||
|
||||
if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && keyPressed) {
|
||||
al.setColor(ColorRGBA.White.mult((1 - dlsr.getShadowIntensity()) * 0.2f));
|
||||
}
|
||||
|
||||
if (name.equals("debug") && keyPressed) {
|
||||
dlsr.displayFrustum();
|
||||
}
|
||||
|
||||
if (name.equals("backShadows") && keyPressed) {
|
||||
dlsr.setRenderBackFacesShadows(!dlsr.isRenderBackFacesShadows());
|
||||
dlsf.setRenderBackFacesShadows(!dlsf.isRenderBackFacesShadows());
|
||||
}
|
||||
|
||||
if (name.equals("stabilize") && keyPressed) {
|
||||
dlsr.setEnabledStabilization(!dlsr.isEnabledStabilization());
|
||||
dlsf.setEnabledStabilization(!dlsf.isEnabledStabilization());
|
||||
|
@ -32,7 +32,10 @@
|
||||
package jme3test.light;
|
||||
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.light.AmbientLight;
|
||||
import com.jme3.light.PointLight;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.FilterPostProcessor;
|
||||
@ -45,7 +48,7 @@ import com.jme3.shadow.EdgeFilteringMode;
|
||||
import com.jme3.shadow.PointLightShadowFilter;
|
||||
import com.jme3.shadow.PointLightShadowRenderer;
|
||||
|
||||
public class TestPointLightShadows extends SimpleApplication {
|
||||
public class TestPointLightShadows extends SimpleApplication implements ActionListener{
|
||||
public static final int SHADOWMAP_SIZE = 512;
|
||||
|
||||
public static void main(String[] args) {
|
||||
@ -55,6 +58,7 @@ public class TestPointLightShadows extends SimpleApplication {
|
||||
Node lightNode;
|
||||
PointLightShadowRenderer plsr;
|
||||
PointLightShadowFilter plsf;
|
||||
AmbientLight al;
|
||||
|
||||
@Override
|
||||
public void simpleInitApp () {
|
||||
@ -62,8 +66,13 @@ public class TestPointLightShadows extends SimpleApplication {
|
||||
cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f));
|
||||
cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f));
|
||||
|
||||
al = new AmbientLight(ColorRGBA.White.mult(0.02f));
|
||||
rootNode.addLight(al);
|
||||
|
||||
Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o");
|
||||
|
||||
|
||||
|
||||
Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox_1.j3o");
|
||||
scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
|
||||
rootNode.attachChild(scene);
|
||||
rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive);
|
||||
@ -89,6 +98,7 @@ public class TestPointLightShadows extends SimpleApplication {
|
||||
plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
||||
plsr.setShadowZExtend(15);
|
||||
plsr.setShadowZFadeLength(5);
|
||||
plsr.setShadowIntensity(0.9f);
|
||||
// plsr.setFlushQueues(false);
|
||||
//plsr.displayFrustum();
|
||||
plsr.displayDebug();
|
||||
@ -99,18 +109,27 @@ public class TestPointLightShadows extends SimpleApplication {
|
||||
plsf.setLight((PointLight) scene.getLocalLightList().get(0));
|
||||
plsf.setShadowZExtend(15);
|
||||
plsf.setShadowZFadeLength(5);
|
||||
plsf.setShadowIntensity(0.8f);
|
||||
plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
||||
plsf.setEnabled(false);
|
||||
|
||||
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||
fpp.addFilter(plsf);
|
||||
viewPort.addProcessor(fpp);
|
||||
|
||||
inputManager.addListener(this,"ShadowUp","ShadowDown");
|
||||
ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleUpdate(float tpf) {
|
||||
// lightNode.move(FastMath.cos(tpf) * 0.4f, 0, FastMath.sin(tpf) * 0.4f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if ((name.equals("ShadowUp") || name.equals("ShadowDown")) && isPressed) {
|
||||
al.setColor(ColorRGBA.White.mult((1 - plsr.getShadowIntensity()) * 0.2f));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user