|
|
|
@ -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. |
|
|
|
|
* |
|
|
|
|