Added an option to not render backfaces shadows with the shadow renderer and the shadow filter. It's the default for the renderer but not for the filter as it may have some edges artifacts.
This commit is contained in:
parent
32be69f3e6
commit
dff4befafb
jme3-core/src/main
java/com/jme3/shadow
resources/Common/MatDefs
jme3-examples/src/main/java/jme3test/light
@ -37,6 +37,7 @@ import com.jme3.export.JmeExporter;
|
|||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
import com.jme3.math.Vector4f;
|
import com.jme3.math.Vector4f;
|
||||||
import com.jme3.post.Filter;
|
import com.jme3.post.Filter;
|
||||||
@ -44,6 +45,7 @@ import com.jme3.renderer.RenderManager;
|
|||||||
import com.jme3.renderer.ViewPort;
|
import com.jme3.renderer.ViewPort;
|
||||||
import com.jme3.renderer.queue.RenderQueue;
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
import com.jme3.texture.FrameBuffer;
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
|
||||||
import java.io.IOException;
|
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");
|
material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");
|
||||||
this.shadowRenderer = shadowRenderer;
|
this.shadowRenderer = shadowRenderer;
|
||||||
this.shadowRenderer.setPostShadowMaterial(material);
|
this.shadowRenderer.setPostShadowMaterial(material);
|
||||||
|
|
||||||
|
//this is legacy setting for shadows with backface shadows
|
||||||
|
this.shadowRenderer.setRenderBackFacesShadows(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,7 +131,7 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
|
|||||||
/**
|
/**
|
||||||
* How far the shadows are rendered in the view
|
* How far the shadows are rendered in the view
|
||||||
*
|
*
|
||||||
* @see setShadowZExtend(float zFar)
|
* @see #setShadowZExtend(float zFar)
|
||||||
* @return shadowZExtend
|
* @return shadowZExtend
|
||||||
*/
|
*/
|
||||||
public float getShadowZExtend() {
|
public float getShadowZExtend() {
|
||||||
@ -248,6 +253,46 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
|
|||||||
shadowRenderer.setEdgeFilteringMode(filterMode);
|
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
|
* returns the the edge filtering mode
|
||||||
*
|
*
|
||||||
|
@ -31,10 +31,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.shadow;
|
package com.jme3.shadow;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
import com.jme3.export.JmeExporter;
|
import com.jme3.export.JmeExporter;
|
||||||
@ -42,6 +38,7 @@ import com.jme3.export.JmeImporter;
|
|||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
import com.jme3.export.Savable;
|
import com.jme3.export.Savable;
|
||||||
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.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
@ -67,6 +64,10 @@ import com.jme3.texture.Texture.ShadowCompareMode;
|
|||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
import com.jme3.ui.Picture;
|
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
|
* abstract shadow renderer that holds commons feature to have for a shadow
|
||||||
* renderer
|
* renderer
|
||||||
@ -92,6 +93,8 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
|
protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
|
||||||
protected CompareMode shadowCompareMode = CompareMode.Hardware;
|
protected CompareMode shadowCompareMode = CompareMode.Hardware;
|
||||||
protected Picture[] dispPic;
|
protected Picture[] dispPic;
|
||||||
|
protected RenderState forcedRenderState = new RenderState();
|
||||||
|
protected Boolean renderBackFacesShadows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if the fallback material should be used, otherwise false
|
* true if the fallback material should be used, otherwise false
|
||||||
@ -182,6 +185,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
setShadowCompareMode(shadowCompareMode);
|
setShadowCompareMode(shadowCompareMode);
|
||||||
setEdgeFilteringMode(edgeFilteringMode);
|
setEdgeFilteringMode(edgeFilteringMode);
|
||||||
setShadowIntensity(shadowIntensity);
|
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
|
* rendered in the shadow map
|
||||||
*
|
*
|
||||||
* @param shadowMapIndex the index of the shadow map being rendered
|
* @param shadowMapIndex the index of the shadow map being rendered
|
||||||
* @param sceneOccluders the occluders of the whole scene
|
* @param shadowMapOccluders the list of occluders
|
||||||
* @param sceneReceivers the receivers of the whole scene
|
|
||||||
* @param shadowMapOcculders
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders);
|
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().setFrameBuffer(shadowFB[shadowMapIndex]);
|
||||||
renderManager.getRenderer().clearBuffers(true, true, true);
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
|
renderManager.setForcedRenderState(forcedRenderState);
|
||||||
|
|
||||||
// render shadow casters to shadow map
|
// render shadow casters to shadow map
|
||||||
viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
|
viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
|
||||||
|
renderManager.setForcedRenderState(null);
|
||||||
}
|
}
|
||||||
boolean debugfrustums = false;
|
boolean debugfrustums = false;
|
||||||
|
|
||||||
@ -536,18 +547,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
private void setMatParams(GeometryList l) {
|
private void setMatParams(GeometryList l) {
|
||||||
//iteration throught all the geometries of the list to gather the materials
|
//iteration throught all the geometries of the list to gather the materials
|
||||||
|
|
||||||
matCache.clear();
|
buildMatCache(l);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//iterating through the mat cache and setting the parameters
|
//iterating through the mat cache and setting the parameters
|
||||||
for (Material mat : matCache) {
|
for (Material mat : matCache) {
|
||||||
@ -567,6 +567,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
if (fadeInfo != null) {
|
if (fadeInfo != null) {
|
||||||
mat.setVector2("FadeInfo", fadeInfo);
|
mat.setVector2("FadeInfo", fadeInfo);
|
||||||
}
|
}
|
||||||
|
if(renderBackFacesShadows != null){
|
||||||
|
mat.setBoolean("BackfaceShadows", renderBackFacesShadows);
|
||||||
|
}
|
||||||
|
|
||||||
setMaterialParameters(mat);
|
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
|
* for internal use only
|
||||||
*/
|
*/
|
||||||
@ -588,7 +607,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
postshadowMat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
|
postshadowMat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
|
||||||
}
|
}
|
||||||
if (fadeInfo != null) {
|
if (fadeInfo != null) {
|
||||||
postshadowMat.setVector2("FadeInfo", fadeInfo);
|
postshadowMat.setVector2("FadeInfo", fadeInfo);
|
||||||
|
}
|
||||||
|
if(renderBackFacesShadows != null){
|
||||||
|
postshadowMat.setBoolean("BackfaceShadows", renderBackFacesShadows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,6 +753,48 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public void setFlushQueues(boolean flushQueues) {}
|
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.
|
* De-serialize this instance, for example when loading from a J3O file.
|
||||||
*
|
*
|
||||||
|
@ -215,6 +215,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
|||||||
@Override
|
@Override
|
||||||
protected void setMaterialParameters(Material material) {
|
protected void setMaterialParameters(Material material) {
|
||||||
material.setColor("Splits", splits);
|
material.setColor("Splits", splits);
|
||||||
|
material.setVector3("LightDir", light.getDirection());
|
||||||
if (fadeInfo != null) {
|
if (fadeInfo != null) {
|
||||||
material.setVector2("FadeInfo", fadeInfo);
|
material.setVector2("FadeInfo", fadeInfo);
|
||||||
}
|
}
|
||||||
@ -224,6 +225,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
|||||||
protected void clearMaterialParameters(Material material) {
|
protected void clearMaterialParameters(Material material) {
|
||||||
material.clearParam("Splits");
|
material.clearParam("Splits");
|
||||||
material.clearParam("FadeInfo");
|
material.clearParam("FadeInfo");
|
||||||
|
material.clearParam("LightDir");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,6 +113,8 @@ MaterialDef Phong Lighting {
|
|||||||
|
|
||||||
//For instancing
|
//For instancing
|
||||||
Boolean UseInstancing
|
Boolean UseInstancing
|
||||||
|
|
||||||
|
Boolean BackfaceShadows: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
@ -213,14 +215,6 @@ MaterialDef Phong Lighting {
|
|||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
}
|
}
|
||||||
|
|
||||||
ForcedRenderState {
|
|
||||||
FaceCull Off
|
|
||||||
DepthTest On
|
|
||||||
DepthWrite On
|
|
||||||
PolyOffset 5 3
|
|
||||||
ColorWrite Off
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -233,6 +227,7 @@ MaterialDef Phong Lighting {
|
|||||||
WorldMatrix
|
WorldMatrix
|
||||||
ViewProjectionMatrix
|
ViewProjectionMatrix
|
||||||
ViewMatrix
|
ViewMatrix
|
||||||
|
NormalMatrix
|
||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
@ -247,6 +242,7 @@ MaterialDef Phong Lighting {
|
|||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
NUM_BONES : NumberOfBones
|
NUM_BONES : NumberOfBones
|
||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
|
BACKFACE_SHADOWS: BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
ForcedRenderState {
|
ForcedRenderState {
|
||||||
@ -265,6 +261,7 @@ MaterialDef Phong Lighting {
|
|||||||
WorldMatrix
|
WorldMatrix
|
||||||
ViewProjectionMatrix
|
ViewProjectionMatrix
|
||||||
ViewMatrix
|
ViewMatrix
|
||||||
|
NormalMatrix
|
||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
|
@ -51,6 +51,8 @@ MaterialDef Unshaded {
|
|||||||
Float PCFEdge
|
Float PCFEdge
|
||||||
|
|
||||||
Float ShadowMapSize
|
Float ShadowMapSize
|
||||||
|
|
||||||
|
Boolean BackfaceShadows: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
@ -169,6 +171,7 @@ MaterialDef Unshaded {
|
|||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
NUM_BONES : NumberOfBones
|
NUM_BONES : NumberOfBones
|
||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
|
BACKFACE_SHADOWS: BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
ForcedRenderState {
|
ForcedRenderState {
|
||||||
@ -201,6 +204,7 @@ MaterialDef Unshaded {
|
|||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
NUM_BONES : NumberOfBones
|
NUM_BONES : NumberOfBones
|
||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
|
BACKFACE_SHADOWS: BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
ForcedRenderState {
|
ForcedRenderState {
|
||||||
|
@ -9,6 +9,9 @@ varying vec4 projCoord0;
|
|||||||
varying vec4 projCoord1;
|
varying vec4 projCoord1;
|
||||||
varying vec4 projCoord2;
|
varying vec4 projCoord2;
|
||||||
varying vec4 projCoord3;
|
varying vec4 projCoord3;
|
||||||
|
#ifndef BACKFACE_SHADOWS
|
||||||
|
varying float nDotL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef POINTLIGHT
|
#ifdef POINTLIGHT
|
||||||
varying vec4 projCoord4;
|
varying vec4 projCoord4;
|
||||||
@ -46,9 +49,15 @@ void main(){
|
|||||||
if(alpha<=m_AlphaDiscardThreshold){
|
if(alpha<=m_AlphaDiscardThreshold){
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BACKFACE_SHADOWS
|
||||||
|
if(nDotL > 0.0){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
float shadow = 1.0;
|
float shadow = 1.0;
|
||||||
|
|
||||||
#ifdef POINTLIGHT
|
#ifdef POINTLIGHT
|
||||||
@ -71,11 +80,11 @@ void main(){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FADE
|
#ifdef FADE
|
||||||
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
|
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
|
||||||
#endif
|
#endif
|
||||||
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
|
||||||
|
|
||||||
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
|
||||||
|
gl_FragColor = vec4(shadow, shadow, shadow, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ MaterialDef Post Shadow {
|
|||||||
Float PCFEdge
|
Float PCFEdge
|
||||||
|
|
||||||
Float ShadowMapSize
|
Float ShadowMapSize
|
||||||
|
|
||||||
|
Boolean BackfaceShadows: false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +51,7 @@ MaterialDef Post Shadow {
|
|||||||
FADE : FadeInfo
|
FADE : FadeInfo
|
||||||
PSSM : Splits
|
PSSM : Splits
|
||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
|
BACKFACE_SHADOWS: BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
@ -75,6 +78,7 @@ MaterialDef Post Shadow {
|
|||||||
FADE : FadeInfo
|
FADE : FadeInfo
|
||||||
PSSM : Splits
|
PSSM : Splits
|
||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
|
BACKFACE_SHADOWS: BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
|
@ -7,7 +7,6 @@ uniform mat4 m_LightViewProjectionMatrix1;
|
|||||||
uniform mat4 m_LightViewProjectionMatrix2;
|
uniform mat4 m_LightViewProjectionMatrix2;
|
||||||
uniform mat4 m_LightViewProjectionMatrix3;
|
uniform mat4 m_LightViewProjectionMatrix3;
|
||||||
|
|
||||||
uniform vec3 m_LightPos;
|
|
||||||
|
|
||||||
varying vec4 projCoord0;
|
varying vec4 projCoord0;
|
||||||
varying vec4 projCoord1;
|
varying vec4 projCoord1;
|
||||||
@ -17,12 +16,14 @@ varying vec4 projCoord3;
|
|||||||
#ifdef POINTLIGHT
|
#ifdef POINTLIGHT
|
||||||
uniform mat4 m_LightViewProjectionMatrix4;
|
uniform mat4 m_LightViewProjectionMatrix4;
|
||||||
uniform mat4 m_LightViewProjectionMatrix5;
|
uniform mat4 m_LightViewProjectionMatrix5;
|
||||||
|
uniform vec3 m_LightPos;
|
||||||
varying vec4 projCoord4;
|
varying vec4 projCoord4;
|
||||||
varying vec4 projCoord5;
|
varying vec4 projCoord5;
|
||||||
varying vec4 worldPos;
|
varying vec4 worldPos;
|
||||||
#else
|
#else
|
||||||
|
uniform vec3 m_LightDir;
|
||||||
#ifndef PSSM
|
#ifndef PSSM
|
||||||
uniform vec3 m_LightDir;
|
uniform vec3 m_LightPos;
|
||||||
varying float lightDot;
|
varying float lightDot;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -30,12 +31,15 @@ varying vec4 projCoord3;
|
|||||||
#if defined(PSSM) || defined(FADE)
|
#if defined(PSSM) || defined(FADE)
|
||||||
varying float shadowPosition;
|
varying float shadowPosition;
|
||||||
#endif
|
#endif
|
||||||
varying vec3 lightVec;
|
|
||||||
|
|
||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
|
|
||||||
attribute vec3 inPosition;
|
attribute vec3 inPosition;
|
||||||
|
|
||||||
|
#ifndef BACKFACE_SHADOWS
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
varying float nDotL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DISCARD_ALPHA
|
#ifdef DISCARD_ALPHA
|
||||||
attribute vec2 inTexCoord;
|
attribute vec2 inTexCoord;
|
||||||
#endif
|
#endif
|
||||||
@ -53,16 +57,17 @@ void main(){
|
|||||||
Skinning_Compute(modelSpacePos);
|
Skinning_Compute(modelSpacePos);
|
||||||
#endif
|
#endif
|
||||||
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
||||||
|
vec3 lightDir;
|
||||||
|
|
||||||
#if defined(PSSM) || defined(FADE)
|
#if defined(PSSM) || defined(FADE)
|
||||||
shadowPosition = gl_Position.z;
|
shadowPosition = gl_Position.z;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef POINTLIGHT
|
#ifndef POINTLIGHT
|
||||||
vec4 worldPos=vec4(0.0);
|
vec4 worldPos=vec4(0.0);
|
||||||
#endif
|
#endif
|
||||||
// get the vertex in world space
|
// get the vertex in world space
|
||||||
worldPos = g_WorldMatrix * modelSpacePos;
|
worldPos = TransformWorld(modelSpacePos);
|
||||||
|
|
||||||
#ifdef DISCARD_ALPHA
|
#ifdef DISCARD_ALPHA
|
||||||
texCoord = inTexCoord;
|
texCoord = inTexCoord;
|
||||||
@ -77,8 +82,21 @@ void main(){
|
|||||||
projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos;
|
projCoord5 = biasMat * m_LightViewProjectionMatrix5 * worldPos;
|
||||||
#else
|
#else
|
||||||
#ifndef PSSM
|
#ifndef PSSM
|
||||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
//Spot light
|
||||||
|
lightDir = worldPos.xyz - m_LightPos;
|
||||||
lightDot = dot(m_LightDir,lightDir);
|
lightDot = dot(m_LightDir,lightDir);
|
||||||
#endif
|
#endif
|
||||||
#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_LightViewProjectionMatrix2;
|
||||||
uniform mat4 m_LightViewProjectionMatrix3;
|
uniform mat4 m_LightViewProjectionMatrix3;
|
||||||
|
|
||||||
|
uniform vec2 g_ResolutionInverse;
|
||||||
|
|
||||||
#ifdef POINTLIGHT
|
#ifdef POINTLIGHT
|
||||||
uniform vec3 m_LightPos;
|
uniform vec3 m_LightPos;
|
||||||
uniform mat4 m_LightViewProjectionMatrix4;
|
uniform mat4 m_LightViewProjectionMatrix4;
|
||||||
@ -39,6 +41,19 @@ vec3 getPosition(in float depth, in vec2 uv){
|
|||||||
return pos.xyz / pos.w;
|
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(){
|
void main(){
|
||||||
#if !defined( RENDER_SHADOWS )
|
#if !defined( RENDER_SHADOWS )
|
||||||
gl_FragColor = texture2D(m_Texture,texCoord);
|
gl_FragColor = texture2D(m_Texture,texCoord);
|
||||||
@ -48,6 +63,7 @@ void main(){
|
|||||||
float depth = texture2D(m_DepthTexture,texCoord).r;
|
float depth = texture2D(m_DepthTexture,texCoord).r;
|
||||||
vec4 color = texture2D(m_Texture,texCoord);
|
vec4 color = texture2D(m_Texture,texCoord);
|
||||||
|
|
||||||
|
|
||||||
//Discard shadow computation on the sky
|
//Discard shadow computation on the sky
|
||||||
if(depth == 1.0){
|
if(depth == 1.0){
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
@ -56,6 +72,19 @@ void main(){
|
|||||||
|
|
||||||
// get the vertex in world space
|
// get the vertex in world space
|
||||||
vec4 worldPos = vec4(getPosition(depth,texCoord),1.0);
|
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))
|
#if (!defined(POINTLIGHT) && !defined(PSSM))
|
||||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
vec3 lightDir = worldPos.xyz - m_LightPos;
|
||||||
|
@ -38,13 +38,15 @@ MaterialDef Post Shadow {
|
|||||||
Texture2D Texture
|
Texture2D Texture
|
||||||
Texture2D DepthTexture
|
Texture2D DepthTexture
|
||||||
|
|
||||||
|
Boolean BackfaceShadows: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
VertexShader GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.vert
|
VertexShader GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.vert
|
||||||
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.frag
|
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadowFilter15.frag
|
||||||
|
|
||||||
WorldParameters {
|
WorldParameters {
|
||||||
|
ResolutionInverse
|
||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
@ -59,7 +61,7 @@ MaterialDef Post Shadow {
|
|||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
//if no shadow map don't render shadows
|
//if no shadow map don't render shadows
|
||||||
RENDER_SHADOWS : ShadowMap0
|
RENDER_SHADOWS : ShadowMap0
|
||||||
|
BACKFACE_SHADOWS : BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -68,7 +70,8 @@ MaterialDef Post Shadow {
|
|||||||
VertexShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert
|
VertexShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.vert
|
||||||
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag
|
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadowFilter.frag
|
||||||
|
|
||||||
WorldParameters {
|
WorldParameters {
|
||||||
|
ResolutionInverse
|
||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
@ -79,6 +82,7 @@ MaterialDef Post Shadow {
|
|||||||
FADE : FadeInfo
|
FADE : FadeInfo
|
||||||
PSSM : Splits
|
PSSM : Splits
|
||||||
POINTLIGHT : LightViewProjectionMatrix5
|
POINTLIGHT : LightViewProjectionMatrix5
|
||||||
|
BACKFACE_SHADOWS : BackfaceShadows
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,16 @@ uniform mat4 m_LightViewProjectionMatrix1;
|
|||||||
uniform mat4 m_LightViewProjectionMatrix2;
|
uniform mat4 m_LightViewProjectionMatrix2;
|
||||||
uniform mat4 m_LightViewProjectionMatrix3;
|
uniform mat4 m_LightViewProjectionMatrix3;
|
||||||
|
|
||||||
|
uniform vec2 g_ResolutionInverse;
|
||||||
|
|
||||||
#ifdef POINTLIGHT
|
#ifdef POINTLIGHT
|
||||||
uniform vec3 m_LightPos;
|
uniform vec3 m_LightPos;
|
||||||
uniform mat4 m_LightViewProjectionMatrix4;
|
uniform mat4 m_LightViewProjectionMatrix4;
|
||||||
uniform mat4 m_LightViewProjectionMatrix5;
|
uniform mat4 m_LightViewProjectionMatrix5;
|
||||||
#else
|
#else
|
||||||
|
uniform vec3 m_LightDir;
|
||||||
#ifndef PSSM
|
#ifndef PSSM
|
||||||
uniform vec3 m_LightPos;
|
uniform vec3 m_LightPos;
|
||||||
uniform vec3 m_LightDir;
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -41,6 +43,23 @@ vec3 getPosition(in float depth, in vec2 uv){
|
|||||||
return pos.xyz / pos.w;
|
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){
|
vec4 main_multiSample(in int numSample){
|
||||||
float depth = fetchTextureSample(m_DepthTexture,texCoord,numSample).r;//getDepth(m_DepthTexture,texCoord).r;
|
float depth = fetchTextureSample(m_DepthTexture,texCoord,numSample).r;//getDepth(m_DepthTexture,texCoord).r;
|
||||||
vec4 color = fetchTextureSample(m_Texture,texCoord,numSample);
|
vec4 color = fetchTextureSample(m_Texture,texCoord,numSample);
|
||||||
@ -52,12 +71,27 @@ vec4 main_multiSample(in int numSample){
|
|||||||
|
|
||||||
// get the vertex in world space
|
// get the vertex in world space
|
||||||
vec4 worldPos = vec4(getPosition(depth,texCoord),1.0);
|
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))
|
#if (!defined(POINTLIGHT) && !defined(PSSM))
|
||||||
vec3 lightDir = worldPos.xyz - m_LightPos;
|
if( dot(m_LightDir,lightDir)<0){
|
||||||
if( dot(m_LightDir,lightDir)<0){
|
return color;
|
||||||
return color;
|
}
|
||||||
}
|
|
||||||
#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
|
||||||
|
@ -40,12 +40,14 @@ import com.jme3.input.controls.KeyTrigger;
|
|||||||
import com.jme3.light.AmbientLight;
|
import com.jme3.light.AmbientLight;
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
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.FastMath;
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
|
import com.jme3.post.ssao.SSAOFilter;
|
||||||
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;
|
||||||
@ -69,6 +71,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
private Geometry ground;
|
private Geometry ground;
|
||||||
private Material matGroundU;
|
private Material matGroundU;
|
||||||
private Material matGroundL;
|
private Material matGroundL;
|
||||||
|
private AmbientLight al;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
TestDirectionalLightShadow app = new TestDirectionalLightShadow();
|
TestDirectionalLightShadow app = new TestDirectionalLightShadow();
|
||||||
@ -99,7 +102,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
mat[0] = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
|
mat[0] = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
|
||||||
mat[1] = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
|
mat[1] = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
|
||||||
mat[1].setBoolean("UseMaterialColors", true);
|
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());
|
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[1]);
|
||||||
TangentBinormalGenerator.generate(obj[0]);
|
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++) {
|
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.setLocalScale(FastMath.nextRandomFloat() * 10f);
|
||||||
t.setMaterial(mat[FastMath.nextRandomInt(0, mat.length - 1)]);
|
t.setMaterial(mat[FastMath.nextRandomInt(0, mat.length - 1)]);
|
||||||
rootNode.attachChild(t);
|
rootNode.attachChild(t);
|
||||||
@ -142,8 +150,8 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
rootNode.addLight(l);
|
rootNode.addLight(l);
|
||||||
|
|
||||||
|
|
||||||
AmbientLight al = new AmbientLight();
|
al = new AmbientLight();
|
||||||
al.setColor(ColorRGBA.White.mult(0.5f));
|
al.setColor(ColorRGBA.White.mult(0.02f));
|
||||||
rootNode.addLight(al);
|
rootNode.addLight(al);
|
||||||
|
|
||||||
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
||||||
@ -156,8 +164,11 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
@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(65.25412f, 44.38738f, 9.087874f));
|
// cam.setLocation(new Vector3f(65.25412f, 44.38738f, 9.087874f));
|
||||||
cam.setRotation(new Quaternion(0.078139365f, 0.050241485f, -0.003942559f, 0.9956679f));
|
// 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);
|
flyCam.setMoveSpeed(100);
|
||||||
|
|
||||||
@ -166,7 +177,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3);
|
dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3);
|
||||||
dlsr.setLight(l);
|
dlsr.setLight(l);
|
||||||
dlsr.setLambda(0.55f);
|
dlsr.setLambda(0.55f);
|
||||||
dlsr.setShadowIntensity(0.6f);
|
dlsr.setShadowIntensity(0.8f);
|
||||||
dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||||
dlsr.displayDebug();
|
dlsr.displayDebug();
|
||||||
viewPort.addProcessor(dlsr);
|
viewPort.addProcessor(dlsr);
|
||||||
@ -174,7 +185,7 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
|
dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
|
||||||
dlsf.setLight(l);
|
dlsf.setLight(l);
|
||||||
dlsf.setLambda(0.55f);
|
dlsf.setLambda(0.55f);
|
||||||
dlsf.setShadowIntensity(0.6f);
|
dlsf.setShadowIntensity(0.8f);
|
||||||
dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
|
||||||
dlsf.setEnabled(false);
|
dlsf.setEnabled(false);
|
||||||
|
|
||||||
@ -205,10 +216,11 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
|
|||||||
inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP));
|
inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP));
|
||||||
inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN));
|
inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN));
|
||||||
inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P));
|
inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P));
|
||||||
|
inputManager.addMapping("backShadows", new KeyTrigger(KeyInput.KEY_B));
|
||||||
|
|
||||||
|
|
||||||
inputManager.addListener(this, "lambdaUp", "lambdaDown", "ThicknessUp", "ThicknessDown",
|
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);
|
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);
|
dlsf.setLambda(dlsr.getLambda() - 0.01f);
|
||||||
System.out.println("Lambda : " + dlsr.getLambda());
|
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) {
|
if (name.equals("debug") && keyPressed) {
|
||||||
dlsr.displayFrustum();
|
dlsr.displayFrustum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.equals("backShadows") && keyPressed) {
|
||||||
|
dlsr.setRenderBackFacesShadows(!dlsr.isRenderBackFacesShadows());
|
||||||
|
dlsf.setRenderBackFacesShadows(!dlsf.isRenderBackFacesShadows());
|
||||||
|
}
|
||||||
|
|
||||||
if (name.equals("stabilize") && keyPressed) {
|
if (name.equals("stabilize") && keyPressed) {
|
||||||
dlsr.setEnabledStabilization(!dlsr.isEnabledStabilization());
|
dlsr.setEnabledStabilization(!dlsr.isEnabledStabilization());
|
||||||
dlsf.setEnabledStabilization(!dlsf.isEnabledStabilization());
|
dlsf.setEnabledStabilization(!dlsf.isEnabledStabilization());
|
||||||
|
@ -32,7 +32,10 @@
|
|||||||
package jme3test.light;
|
package jme3test.light;
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.input.controls.ActionListener;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
import com.jme3.light.PointLight;
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
@ -45,7 +48,7 @@ import com.jme3.shadow.EdgeFilteringMode;
|
|||||||
import com.jme3.shadow.PointLightShadowFilter;
|
import com.jme3.shadow.PointLightShadowFilter;
|
||||||
import com.jme3.shadow.PointLightShadowRenderer;
|
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 final int SHADOWMAP_SIZE = 512;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -55,15 +58,21 @@ public class TestPointLightShadows extends SimpleApplication {
|
|||||||
Node lightNode;
|
Node lightNode;
|
||||||
PointLightShadowRenderer plsr;
|
PointLightShadowRenderer plsr;
|
||||||
PointLightShadowFilter plsf;
|
PointLightShadowFilter plsf;
|
||||||
|
AmbientLight al;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp () {
|
||||||
flyCam.setMoveSpeed(10);
|
flyCam.setMoveSpeed(10);
|
||||||
cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f));
|
cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f));
|
||||||
cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f));
|
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);
|
scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
|
||||||
rootNode.attachChild(scene);
|
rootNode.attachChild(scene);
|
||||||
rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive);
|
rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive);
|
||||||
@ -89,6 +98,7 @@ public class TestPointLightShadows extends SimpleApplication {
|
|||||||
plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
||||||
plsr.setShadowZExtend(15);
|
plsr.setShadowZExtend(15);
|
||||||
plsr.setShadowZFadeLength(5);
|
plsr.setShadowZFadeLength(5);
|
||||||
|
plsr.setShadowIntensity(0.9f);
|
||||||
// plsr.setFlushQueues(false);
|
// plsr.setFlushQueues(false);
|
||||||
//plsr.displayFrustum();
|
//plsr.displayFrustum();
|
||||||
plsr.displayDebug();
|
plsr.displayDebug();
|
||||||
@ -99,18 +109,27 @@ public class TestPointLightShadows extends SimpleApplication {
|
|||||||
plsf.setLight((PointLight) scene.getLocalLightList().get(0));
|
plsf.setLight((PointLight) scene.getLocalLightList().get(0));
|
||||||
plsf.setShadowZExtend(15);
|
plsf.setShadowZExtend(15);
|
||||||
plsf.setShadowZFadeLength(5);
|
plsf.setShadowZFadeLength(5);
|
||||||
|
plsf.setShadowIntensity(0.8f);
|
||||||
plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
|
||||||
plsf.setEnabled(false);
|
plsf.setEnabled(false);
|
||||||
|
|
||||||
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
fpp.addFilter(plsf);
|
fpp.addFilter(plsf);
|
||||||
viewPort.addProcessor(fpp);
|
viewPort.addProcessor(fpp);
|
||||||
|
inputManager.addListener(this,"ShadowUp","ShadowDown");
|
||||||
ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort);
|
ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleUpdate(float tpf) {
|
public void simpleUpdate(float tpf) {
|
||||||
// lightNode.move(FastMath.cos(tpf) * 0.4f, 0, FastMath.sin(tpf) * 0.4f);
|
// 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