All shadow renderers/filters are now properly savables
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10005 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
dd2b82c881
commit
b88350a069
@ -32,6 +32,11 @@
|
||||
package com.jme3.shadow;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.export.Savable;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Matrix4f;
|
||||
@ -49,7 +54,6 @@ import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.debug.WireFrustum;
|
||||
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.texture.Texture.MagFilter;
|
||||
@ -57,14 +61,17 @@ import com.jme3.texture.Texture.MinFilter;
|
||||
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
|
||||
* abstract shadow renderer that holds commons feature to have for a shadow
|
||||
* renderer
|
||||
*
|
||||
* @author Rémy Bouquet aka Nehon
|
||||
*/
|
||||
public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
public abstract class AbstractShadowRenderer implements SceneProcessor, Savable {
|
||||
|
||||
protected int nbShadowMaps = 1;
|
||||
protected float shadowMapSize;
|
||||
@ -80,8 +87,8 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
protected AssetManager assetManager;
|
||||
protected boolean debug = false;
|
||||
protected float edgesThickness = 1.0f;
|
||||
protected EdgeFilteringMode edgeFilteringMode;
|
||||
protected CompareMode shadowCompareMode;
|
||||
protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
|
||||
protected CompareMode shadowCompareMode = CompareMode.Hardware;
|
||||
protected Picture[] dispPic;
|
||||
protected boolean flushQueues = true;
|
||||
// define if the fallback material should be used.
|
||||
@ -95,8 +102,17 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
|
||||
protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator());
|
||||
|
||||
|
||||
/**
|
||||
* Create an abstract shadow renderer, this is to be called in extending classes
|
||||
* used for serialization
|
||||
*/
|
||||
protected AbstractShadowRenderer(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an abstract shadow renderer, this is to be called in extending
|
||||
* classes
|
||||
*
|
||||
* @param assetManager the application asset manager
|
||||
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
|
||||
* etc...)
|
||||
@ -106,9 +122,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) {
|
||||
|
||||
this.assetManager = assetManager;
|
||||
this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
|
||||
this.nbShadowMaps = nbShadowMaps;
|
||||
this.shadowMapSize = shadowMapSize;
|
||||
init(assetManager, nbShadowMaps, shadowMapSize);
|
||||
|
||||
}
|
||||
|
||||
private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize) {
|
||||
this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
|
||||
shadowFB = new FrameBuffer[nbShadowMaps];
|
||||
shadowMaps = new Texture2D[nbShadowMaps];
|
||||
dispPic = new Picture[nbShadowMaps];
|
||||
@ -137,14 +158,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
dispPic[i].setTexture(assetManager, shadowMaps[i], false);
|
||||
}
|
||||
|
||||
setShadowCompareMode(CompareMode.Hardware);
|
||||
setEdgeFilteringMode(EdgeFilteringMode.Bilinear);
|
||||
setShadowIntensity(0.7f);
|
||||
|
||||
setShadowCompareMode(shadowCompareMode);
|
||||
setEdgeFilteringMode(edgeFilteringMode);
|
||||
setShadowIntensity(shadowIntensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the post shadow material for this renderer
|
||||
*
|
||||
* @param postShadowMat
|
||||
*/
|
||||
protected final void setPostShadowMaterial(Material postShadowMat) {
|
||||
@ -159,10 +180,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filtering mode for shadow edges see {@link FilterMode} for more
|
||||
* info
|
||||
* Sets the filtering mode for shadow edges see {@link EdgeFilteringMode}
|
||||
* for more info
|
||||
*
|
||||
* @param filterMode
|
||||
* @param EdgeFilteringMode
|
||||
*/
|
||||
final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
|
||||
if (filterMode == null) {
|
||||
@ -206,11 +227,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
*/
|
||||
final public void setShadowCompareMode(CompareMode compareMode) {
|
||||
if (compareMode == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (this.shadowCompareMode == compareMode) {
|
||||
return;
|
||||
throw new IllegalArgumentException("Shadow compare mode cannot be null");
|
||||
}
|
||||
|
||||
this.shadowCompareMode = compareMode;
|
||||
@ -290,30 +307,37 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* This mehtod is called once per frame.
|
||||
* it is responsible for updating the shadow cams according to the light view.
|
||||
* This mehtod is called once per frame. it is responsible for updating the
|
||||
* shadow cams according to the light view.
|
||||
*
|
||||
* @param viewCam the scene cam
|
||||
*/
|
||||
protected abstract void updateShadowCams(Camera viewCam);
|
||||
|
||||
/**
|
||||
* this method must return the geomtryList that contains the oclluders to be rendered in the shadow map
|
||||
* this method must return the geomtryList that contains the oclluders to be
|
||||
* 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 recievers of the whole scene
|
||||
* @return
|
||||
*/
|
||||
protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers,GeometryList shadowMapOccluders);
|
||||
protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers, GeometryList shadowMapOccluders);
|
||||
|
||||
/**
|
||||
* return the shadow camera to use for rendering the shadow map according the given index
|
||||
* return the shadow camera to use for rendering the shadow map according
|
||||
* the given index
|
||||
*
|
||||
* @param shadowMapIndex the index of the shadow map being rendered
|
||||
* @return the shadowCam
|
||||
*/
|
||||
protected abstract Camera getShadowCam(int shadowMapIndex);
|
||||
|
||||
/**
|
||||
* responsible for displaying the frustum of the shadow cam for debug purpose
|
||||
* responsible for displaying the frustum of the shadow cam for debug
|
||||
* purpose
|
||||
*
|
||||
* @param shadowMapIndex
|
||||
*/
|
||||
protected void doDisplayFrustumDebug(int shadowMapIndex) {
|
||||
@ -355,7 +379,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
|
||||
protected void renderShadowMap(int shadowMapIndex, GeometryList occluders, GeometryList receivers) {
|
||||
shadowMapOccluders = getOccludersToRender(shadowMapIndex, occluders, receivers,shadowMapOccluders);
|
||||
shadowMapOccluders = getOccludersToRender(shadowMapIndex, occluders, receivers, shadowMapOccluders);
|
||||
Camera shadowCam = getShadowCam(shadowMapIndex);
|
||||
|
||||
//saving light view projection matrix for this split
|
||||
@ -407,7 +431,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
|
||||
lightReceivers = getReceivers(sceneReceivers, lightReceivers);
|
||||
|
||||
if (lightReceivers.size()!=0) {
|
||||
if (lightReceivers.size() != 0) {
|
||||
//setting params to recieving geometry list
|
||||
setMatParams();
|
||||
|
||||
@ -422,7 +446,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
|
||||
//rendering the post shadow pass
|
||||
viewPort.getQueue().renderShadowQueue(lightReceivers, renderManager, cam, true);
|
||||
if(flushQueues){
|
||||
if (flushQueues) {
|
||||
sceneReceivers.clear();
|
||||
}
|
||||
|
||||
@ -436,8 +460,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called once per frame and is responsible of setting the material
|
||||
* parameters than sub class may need to set on the post material
|
||||
* This method is called once per frame and is responsible of setting the
|
||||
* material parameters than sub class may need to set on the post material
|
||||
*
|
||||
* @param material the materail to use for the post shadow pass
|
||||
*/
|
||||
protected abstract void setMaterialParameters(Material material);
|
||||
@ -571,4 +596,30 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
|
||||
public void setFlushQueues(boolean flushQueues) {
|
||||
this.flushQueues = flushQueues;
|
||||
}
|
||||
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
InputCapsule ic = (InputCapsule) im.getCapsule(this);
|
||||
assetManager = im.getAssetManager();
|
||||
nbShadowMaps = ic.readInt("nbShadowMaps", 1);
|
||||
shadowMapSize = ic.readInt("shadowMapSize", 0);
|
||||
shadowIntensity = ic.readFloat("shadowIntensity", 0.7f);
|
||||
edgeFilteringMode = ic.readEnum("edgeFilteringMode", EdgeFilteringMode.class, EdgeFilteringMode.Bilinear);
|
||||
shadowCompareMode = ic.readEnum("shadowCompareMode", CompareMode.class, CompareMode.Hardware);
|
||||
flushQueues = ic.readBoolean("flushQueues", false);
|
||||
init(assetManager, nbShadowMaps, (int) shadowMapSize);
|
||||
edgesThickness = ic.readFloat("edgesThickness", 1.0f);
|
||||
postshadowMat.setFloat("PCFEdge", edgesThickness);
|
||||
|
||||
}
|
||||
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
|
||||
oc.write(nbShadowMaps, "nbShadowMaps", 1);
|
||||
oc.write(shadowMapSize, "shadowMapSize", 0);
|
||||
oc.write(shadowIntensity, "shadowIntensity", 0.7f);
|
||||
oc.write(edgeFilteringMode, "edgeFilteringMode", EdgeFilteringMode.Bilinear);
|
||||
oc.write(shadowCompareMode, "shadowCompareMode", CompareMode.Hardware);
|
||||
oc.write(flushQueues, "flushQueues", false);
|
||||
oc.write(edgesThickness, "edgesThickness", 1.0f);
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ import java.io.IOException;
|
||||
*/
|
||||
public class DirectionalLightShadowFilter extends AbstractShadowFilter<DirectionalLightShadowRenderer> {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DirectionalLightShadowFilter Shadow Filter More info on the
|
||||
* technique at <a
|
||||
@ -162,6 +160,7 @@ public class DirectionalLightShadowFilter extends AbstractShadowFilter<Direction
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(shadowRenderer, "shadowRenderer", null);
|
||||
|
||||
}
|
||||
|
||||
@ -169,6 +168,6 @@ public class DirectionalLightShadowFilter extends AbstractShadowFilter<Direction
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
|
||||
shadowRenderer = (DirectionalLightShadowRenderer) ic.readSavable("shadowRenderer", null);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,10 @@
|
||||
package com.jme3.shadow;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.light.DirectionalLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
@ -39,8 +43,8 @@ import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.GeometryList;
|
||||
import com.jme3.renderer.queue.OpaqueComparator;
|
||||
import com.jme3.scene.Node;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DirectionalLightShadowRenderer renderer use Parrallel Split Shadow Mapping
|
||||
@ -66,25 +70,39 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
||||
protected Vector2f fadeInfo;
|
||||
protected float fadeLength;
|
||||
|
||||
/**
|
||||
* Used for serialzation use
|
||||
* DirectionalLightShadowRenderer#DirectionalLightShadowRenderer(AssetManager
|
||||
* assetManager, int shadowMapSize, int nbSplits)
|
||||
*/
|
||||
public DirectionalLightShadowRenderer() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DirectionalLightShadowRenderer More info on the technique at <a
|
||||
* href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a>
|
||||
*
|
||||
* @param assetManager the application asset manager
|
||||
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048, etc...)
|
||||
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
|
||||
* etc...)
|
||||
* @param nbSplits the number of shadow maps rendered (the more shadow maps
|
||||
* the more quality, the less fps).
|
||||
*/
|
||||
public DirectionalLightShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbSplits) {
|
||||
super(assetManager, shadowMapSize, nbSplits);
|
||||
init(nbSplits, shadowMapSize);
|
||||
}
|
||||
|
||||
private void init(int nbSplits, int shadowMapSize) {
|
||||
nbShadowMaps = Math.max(Math.min(nbSplits, 4), 1);
|
||||
if (nbShadowMaps != nbSplits) {
|
||||
throw new IllegalArgumentException("Number of splits must be between 1 and 4. Given value : " + nbSplits);
|
||||
}
|
||||
splits = new ColorRGBA();
|
||||
splitsArray = new float[nbSplits + 1];
|
||||
shadowCam = new Camera(shadowMapSize, shadowMapSize);
|
||||
shadowCam.setParallelProjection(true);
|
||||
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
points[i] = new Vector3f();
|
||||
}
|
||||
@ -258,4 +276,27 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = (InputCapsule) im.getCapsule(this);
|
||||
lambda = ic.readFloat("lambda", 0.65f);
|
||||
zFarOverride = ic.readInt("zFarOverride", 0);
|
||||
light = (DirectionalLight) ic.readSavable("light", null);
|
||||
fadeInfo = (Vector2f) ic.readSavable("fadeInfo", null);
|
||||
fadeLength = ic.readFloat("fadeLength", 0f);
|
||||
init(nbShadowMaps, (int) shadowMapSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
|
||||
oc.write(lambda, "lambda", 0.65f);
|
||||
oc.write(zFarOverride, "zFarOverride", 0);
|
||||
oc.write(light, "light", null);
|
||||
oc.write(fadeInfo, "fadeInfo", null);
|
||||
oc.write(fadeLength, "fadeLength", 0f);
|
||||
}
|
||||
}
|
||||
|
@ -37,14 +37,6 @@ import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.light.PointLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector4f;
|
||||
import com.jme3.post.Filter;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -72,7 +64,7 @@ public class PointLightShadowFilter extends AbstractShadowFilter<PointLightShado
|
||||
* etc...)
|
||||
*/
|
||||
public PointLightShadowFilter(AssetManager assetManager, int shadowMapSize) {
|
||||
super(assetManager, shadowMapSize,new PointLightShadowRenderer(assetManager, shadowMapSize));
|
||||
super(assetManager, shadowMapSize, new PointLightShadowRenderer(assetManager, shadowMapSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,6 +89,7 @@ public class PointLightShadowFilter extends AbstractShadowFilter<PointLightShado
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(shadowRenderer, "shadowRenderer", null);
|
||||
|
||||
}
|
||||
|
||||
@ -104,6 +97,6 @@ public class PointLightShadowFilter extends AbstractShadowFilter<PointLightShado
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
|
||||
shadowRenderer = (PointLightShadowRenderer) ic.readSavable("shadowRenderer", null);
|
||||
}
|
||||
}
|
||||
|
@ -32,14 +32,18 @@
|
||||
package com.jme3.shadow;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.light.PointLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.GeometryList;
|
||||
import com.jme3.renderer.queue.OpaqueComparator;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* PointLightShadowRenderer renders shadows for a point light
|
||||
@ -53,6 +57,15 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
|
||||
protected Camera[] shadowCams;
|
||||
private Geometry[] frustums = null;
|
||||
|
||||
/**
|
||||
* Used for serialization use
|
||||
* PointLightShadowRenderer"PointLightShadowRenderer(AssetManager
|
||||
* assetManager, int shadowMapSize)
|
||||
*/
|
||||
public PointLightShadowRenderer() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PointLightShadowRenderer
|
||||
*
|
||||
@ -62,6 +75,10 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
|
||||
*/
|
||||
public PointLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
|
||||
super(assetManager, shadowMapSize, CAM_NUMBER);
|
||||
init(shadowMapSize);
|
||||
}
|
||||
|
||||
private void init(int shadowMapSize) {
|
||||
shadowCams = new Camera[CAM_NUMBER];
|
||||
for (int i = 0; i < CAM_NUMBER; i++) {
|
||||
shadowCams[i] = new Camera(shadowMapSize, shadowMapSize);
|
||||
@ -159,4 +176,19 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
|
||||
public void setLight(PointLight light) {
|
||||
this.light = light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = (InputCapsule) im.getCapsule(this);
|
||||
light = (PointLight) ic.readSavable("light", null);
|
||||
init((int) shadowMapSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
|
||||
oc.write(light, "light", null);
|
||||
}
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* This Filter does basically the same as a SpotLightShadowRenderer
|
||||
* except it renders the post shadow pass as a fulscreen quad pass instead of a
|
||||
* geometry pass. It's mostly faster than PssmShadowRenderer as long as you have
|
||||
* more than a about ten shadow recieving objects. The expense is the draw back
|
||||
* that the shadow Recieve mode set on spatial is ignored. So basically all and
|
||||
* only objects that render depth in the scene receive shadows. See this post
|
||||
* for more details
|
||||
* This Filter does basically the same as a SpotLightShadowRenderer except it
|
||||
* renders the post shadow pass as a fulscreen quad pass instead of a geometry
|
||||
* pass. It's mostly faster than PssmShadowRenderer as long as you have more
|
||||
* than a about ten shadow recieving objects. The expense is the draw back that
|
||||
* the shadow Recieve mode set on spatial is ignored. So basically all and only
|
||||
* objects that render depth in the scene receive shadows. See this post for
|
||||
* more details
|
||||
* http://jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/#post-191599
|
||||
*
|
||||
* API is basically the same as the PssmShadowRenderer;
|
||||
@ -56,13 +56,12 @@ import java.io.IOException;
|
||||
*/
|
||||
public class SpotLightShadowFilter extends AbstractShadowFilter<SpotLightShadowRenderer> {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SpotLight Shadow Filter
|
||||
*
|
||||
* @param assetManager the application asset manager
|
||||
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
|
||||
* etc...)
|
||||
* the more quality, the less fps).
|
||||
* etc...) the more quality, the less fps).
|
||||
*/
|
||||
public SpotLightShadowFilter(AssetManager assetManager, int shadowMapSize) {
|
||||
super(assetManager, shadowMapSize, new SpotLightShadowRenderer(assetManager, shadowMapSize));
|
||||
@ -131,6 +130,7 @@ public class SpotLightShadowFilter extends AbstractShadowFilter<SpotLightShadowR
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(shadowRenderer, "shadowRenderer", null);
|
||||
|
||||
}
|
||||
|
||||
@ -138,6 +138,6 @@ public class SpotLightShadowFilter extends AbstractShadowFilter<SpotLightShadowR
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
|
||||
shadowRenderer = (SpotLightShadowRenderer) ic.readSavable("shadowRenderer", null);
|
||||
}
|
||||
}
|
||||
|
@ -32,18 +32,19 @@
|
||||
package com.jme3.shadow;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.light.DirectionalLight;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.light.SpotLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.math.Vector4f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.GeometryList;
|
||||
import com.jme3.renderer.queue.OpaqueComparator;
|
||||
import com.jme3.scene.Node;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* SpotLightShadowRenderer renderer use Parrallel Split Shadow Mapping technique
|
||||
@ -66,6 +67,14 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
|
||||
protected Vector2f fadeInfo;
|
||||
protected float fadeLength;
|
||||
|
||||
|
||||
/**
|
||||
* Used for serialization use SpotLightShadowRenderer#SpotLightShadowRenderer(AssetManager assetManager, int shadowMapSize)
|
||||
*/
|
||||
public SpotLightShadowRenderer() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SpotLightShadowRenderer This use standard shadow mapping
|
||||
*
|
||||
@ -75,9 +84,12 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
|
||||
*/
|
||||
public SpotLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
|
||||
super(assetManager, shadowMapSize, 1);
|
||||
init(shadowMapSize);
|
||||
}
|
||||
|
||||
|
||||
private void init(int shadowMapSize) {
|
||||
shadowCam = new Camera(shadowMapSize, shadowMapSize);
|
||||
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
points[i] = new Vector3f();
|
||||
}
|
||||
@ -213,4 +225,27 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = (InputCapsule) im.getCapsule(this);
|
||||
zFarOverride = ic.readInt("zFarOverride", 0);
|
||||
light = (SpotLight) ic.readSavable("light", null);
|
||||
fadeInfo = (Vector2f) ic.readSavable("fadeInfo", null);
|
||||
fadeLength = ic.readFloat("fadeLength", 0f);
|
||||
init((int) shadowMapSize);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
|
||||
oc.write(zFarOverride, "zFarOverride", 0);
|
||||
oc.write(light, "light", null);
|
||||
oc.write(fadeInfo, "fadeInfo", null);
|
||||
oc.write(fadeLength, "fadeLength", 0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user