All shadow renderers/filters are now properly savables

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10005 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent dd2b82c881
commit b88350a069
  1. 103
      engine/src/core/com/jme3/shadow/AbstractShadowRenderer.java
  2. 5
      engine/src/core/com/jme3/shadow/DirectionalLightShadowFilter.java
  3. 47
      engine/src/core/com/jme3/shadow/DirectionalLightShadowRenderer.java
  4. 11
      engine/src/core/com/jme3/shadow/PointLightShadowFilter.java
  5. 34
      engine/src/core/com/jme3/shadow/PointLightShadowRenderer.java
  6. 22
      engine/src/core/com/jme3/shadow/SpotLightShadowFilter.java
  7. 45
      engine/src/core/com/jme3/shadow/SpotLightShadowRenderer.java

@ -32,6 +32,11 @@
package com.jme3.shadow; package com.jme3.shadow;
import com.jme3.asset.AssetManager; 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.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix4f; 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.Geometry;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.debug.WireFrustum; import com.jme3.scene.debug.WireFrustum;
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
import com.jme3.texture.FrameBuffer; import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture.MagFilter; import com.jme3.texture.Texture.MagFilter;
@ -57,14 +61,17 @@ import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.ShadowCompareMode; 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.ArrayList;
import java.util.List; 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 * @author Rémy Bouquet aka Nehon
*/ */
public abstract class AbstractShadowRenderer implements SceneProcessor { public abstract class AbstractShadowRenderer implements SceneProcessor, Savable {
protected int nbShadowMaps = 1; protected int nbShadowMaps = 1;
protected float shadowMapSize; protected float shadowMapSize;
@ -80,8 +87,8 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
protected AssetManager assetManager; protected AssetManager assetManager;
protected boolean debug = false; protected boolean debug = false;
protected float edgesThickness = 1.0f; protected float edgesThickness = 1.0f;
protected EdgeFilteringMode edgeFilteringMode; protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
protected CompareMode shadowCompareMode; protected CompareMode shadowCompareMode = CompareMode.Hardware;
protected Picture[] dispPic; protected Picture[] dispPic;
protected boolean flushQueues = true; protected boolean flushQueues = true;
// define if the fallback material should be used. // 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 lightReceivers = new GeometryList(new OpaqueComparator());
protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator()); protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator());
/**
* used for serialization
*/
protected AbstractShadowRenderer(){
}
/** /**
* Create an abstract shadow renderer, this is to be called in extending classes * Create an abstract shadow renderer, this is to be called in extending
* classes
*
* @param assetManager the application asset manager * @param assetManager the application asset manager
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048, * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
* etc...) * etc...)
@ -106,9 +122,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) { protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) {
this.assetManager = assetManager; this.assetManager = assetManager;
this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
this.nbShadowMaps = nbShadowMaps; this.nbShadowMaps = nbShadowMaps;
this.shadowMapSize = shadowMapSize; 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]; shadowFB = new FrameBuffer[nbShadowMaps];
shadowMaps = new Texture2D[nbShadowMaps]; shadowMaps = new Texture2D[nbShadowMaps];
dispPic = new Picture[nbShadowMaps]; dispPic = new Picture[nbShadowMaps];
@ -137,14 +158,14 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
dispPic[i].setTexture(assetManager, shadowMaps[i], false); dispPic[i].setTexture(assetManager, shadowMaps[i], false);
} }
setShadowCompareMode(CompareMode.Hardware); setShadowCompareMode(shadowCompareMode);
setEdgeFilteringMode(EdgeFilteringMode.Bilinear); setEdgeFilteringMode(edgeFilteringMode);
setShadowIntensity(0.7f); setShadowIntensity(shadowIntensity);
} }
/** /**
* set the post shadow material for this renderer * set the post shadow material for this renderer
*
* @param postShadowMat * @param postShadowMat
*/ */
protected final void setPostShadowMaterial(Material 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 * Sets the filtering mode for shadow edges see {@link EdgeFilteringMode}
* info * for more info
* *
* @param filterMode * @param EdgeFilteringMode
*/ */
final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) { final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
if (filterMode == null) { if (filterMode == null) {
@ -206,11 +227,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
*/ */
final public void setShadowCompareMode(CompareMode compareMode) { final public void setShadowCompareMode(CompareMode compareMode) {
if (compareMode == null) { if (compareMode == null) {
throw new NullPointerException(); throw new IllegalArgumentException("Shadow compare mode cannot be null");
}
if (this.shadowCompareMode == compareMode) {
return;
} }
this.shadowCompareMode = compareMode; this.shadowCompareMode = compareMode;
@ -290,14 +307,17 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
} }
/** /**
* This mehtod is called once per frame. * This mehtod is called once per frame. it is responsible for updating the
* it is responsible for updating the shadow cams according to the light view. * shadow cams according to the light view.
*
* @param viewCam the scene cam * @param viewCam the scene cam
*/ */
protected abstract void updateShadowCams(Camera viewCam); 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 shadowMapIndex the index of the shadow map being rendered
* @param sceneOccluders the occluders of the whole scene * @param sceneOccluders the occluders of the whole scene
* @param sceneReceivers the recievers of the whole scene * @param sceneReceivers the recievers of the whole scene
@ -306,14 +326,18 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
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 * @param shadowMapIndex the index of the shadow map being rendered
* @return the shadowCam * @return the shadowCam
*/ */
protected abstract Camera getShadowCam(int shadowMapIndex); 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 * @param shadowMapIndex
*/ */
protected void doDisplayFrustumDebug(int shadowMapIndex) { protected void doDisplayFrustumDebug(int shadowMapIndex) {
@ -436,8 +460,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
} }
/** /**
* This method is called once per frame and is responsible of setting the material * This method is called once per frame and is responsible of setting the
* parameters than sub class may need to set on the post material * material parameters than sub class may need to set on the post material
*
* @param material the materail to use for the post shadow pass * @param material the materail to use for the post shadow pass
*/ */
protected abstract void setMaterialParameters(Material material); protected abstract void setMaterialParameters(Material material);
@ -571,4 +596,30 @@ public abstract class AbstractShadowRenderer implements SceneProcessor {
public void setFlushQueues(boolean flushQueues) { public void setFlushQueues(boolean flushQueues) {
this.flushQueues = 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> { public class DirectionalLightShadowFilter extends AbstractShadowFilter<DirectionalLightShadowRenderer> {
/** /**
* Creates a DirectionalLightShadowFilter Shadow Filter More info on the * Creates a DirectionalLightShadowFilter Shadow Filter More info on the
* technique at <a * technique at <a
@ -162,6 +160,7 @@ public class DirectionalLightShadowFilter extends AbstractShadowFilter<Direction
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
super.write(ex); super.write(ex);
OutputCapsule oc = ex.getCapsule(this); 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 { public void read(JmeImporter im) throws IOException {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
shadowRenderer = (DirectionalLightShadowRenderer) ic.readSavable("shadowRenderer", null);
} }
} }

@ -32,6 +32,10 @@
package com.jme3.shadow; package com.jme3.shadow;
import com.jme3.asset.AssetManager; 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.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
@ -39,8 +43,8 @@ import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.GeometryList;
import com.jme3.renderer.queue.OpaqueComparator;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import java.io.IOException;
/** /**
* DirectionalLightShadowRenderer renderer use Parrallel Split Shadow Mapping * DirectionalLightShadowRenderer renderer use Parrallel Split Shadow Mapping
@ -66,25 +70,39 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
protected Vector2f fadeInfo; protected Vector2f fadeInfo;
protected float fadeLength; 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 * 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> * 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 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 * @param nbSplits the number of shadow maps rendered (the more shadow maps
* the more quality, the less fps). * the more quality, the less fps).
*/ */
public DirectionalLightShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbSplits) { public DirectionalLightShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbSplits) {
super(assetManager, shadowMapSize, nbSplits); super(assetManager, shadowMapSize, nbSplits);
init(nbSplits, shadowMapSize);
}
private void init(int nbSplits, int shadowMapSize) {
nbShadowMaps = Math.max(Math.min(nbSplits, 4), 1); 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(); splits = new ColorRGBA();
splitsArray = new float[nbSplits + 1]; splitsArray = new float[nbSplits + 1];
shadowCam = new Camera(shadowMapSize, shadowMapSize); shadowCam = new Camera(shadowMapSize, shadowMapSize);
shadowCam.setParallelProjection(true); shadowCam.setParallelProjection(true);
for (int i = 0; i < points.length; i++) { for (int i = 0; i < points.length; i++) {
points[i] = new Vector3f(); points[i] = new Vector3f();
} }
@ -258,4 +276,27 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
} }
return 0f; 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.JmeImporter;
import com.jme3.export.OutputCapsule; import com.jme3.export.OutputCapsule;
import com.jme3.light.PointLight; 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; import java.io.IOException;
/** /**
@ -97,6 +89,7 @@ public class PointLightShadowFilter extends AbstractShadowFilter<PointLightShado
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
super.write(ex); super.write(ex);
OutputCapsule oc = ex.getCapsule(this); 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 { public void read(JmeImporter im) throws IOException {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
shadowRenderer = (PointLightShadowRenderer) ic.readSavable("shadowRenderer", null);
} }
} }

@ -32,14 +32,18 @@
package com.jme3.shadow; package com.jme3.shadow;
import com.jme3.asset.AssetManager; 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.light.PointLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.GeometryList;
import com.jme3.renderer.queue.OpaqueComparator;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import java.io.IOException;
/** /**
* PointLightShadowRenderer renders shadows for a point light * PointLightShadowRenderer renders shadows for a point light
@ -53,6 +57,15 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
protected Camera[] shadowCams; protected Camera[] shadowCams;
private Geometry[] frustums = null; private Geometry[] frustums = null;
/**
* Used for serialization use
* PointLightShadowRenderer"PointLightShadowRenderer(AssetManager
* assetManager, int shadowMapSize)
*/
public PointLightShadowRenderer() {
super();
}
/** /**
* Creates a PointLightShadowRenderer * Creates a PointLightShadowRenderer
* *
@ -62,6 +75,10 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
*/ */
public PointLightShadowRenderer(AssetManager assetManager, int shadowMapSize) { public PointLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
super(assetManager, shadowMapSize, CAM_NUMBER); super(assetManager, shadowMapSize, CAM_NUMBER);
init(shadowMapSize);
}
private void init(int shadowMapSize) {
shadowCams = new Camera[CAM_NUMBER]; shadowCams = new Camera[CAM_NUMBER];
for (int i = 0; i < CAM_NUMBER; i++) { for (int i = 0; i < CAM_NUMBER; i++) {
shadowCams[i] = new Camera(shadowMapSize, shadowMapSize); shadowCams[i] = new Camera(shadowMapSize, shadowMapSize);
@ -159,4 +176,19 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
public void setLight(PointLight light) { public void setLight(PointLight light) {
this.light = 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 * This Filter does basically the same as a SpotLightShadowRenderer except it
* except it renders the post shadow pass as a fulscreen quad pass instead of a * renders the post shadow pass as a fulscreen quad pass instead of a geometry
* geometry pass. It's mostly faster than PssmShadowRenderer as long as you have * pass. It's mostly faster than PssmShadowRenderer as long as you have more
* more than a about ten shadow recieving objects. The expense is the draw back * than a about ten shadow recieving objects. The expense is the draw back that
* that the shadow Recieve mode set on spatial is ignored. So basically all and * the shadow Recieve mode set on spatial is ignored. So basically all and only
* only objects that render depth in the scene receive shadows. See this post * objects that render depth in the scene receive shadows. See this post for
* for more details * more details
* http://jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/#post-191599 * http://jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/#post-191599
* *
* API is basically the same as the PssmShadowRenderer; * API is basically the same as the PssmShadowRenderer;
@ -56,13 +56,12 @@ import java.io.IOException;
*/ */
public class SpotLightShadowFilter extends AbstractShadowFilter<SpotLightShadowRenderer> { public class SpotLightShadowFilter extends AbstractShadowFilter<SpotLightShadowRenderer> {
/** /**
* Creates a SpotLight Shadow Filter * Creates a SpotLight Shadow Filter
*
* @param assetManager the application asset manager * @param assetManager the application asset manager
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048, * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
* etc...) * etc...) the more quality, the less fps).
* the more quality, the less fps).
*/ */
public SpotLightShadowFilter(AssetManager assetManager, int shadowMapSize) { public SpotLightShadowFilter(AssetManager assetManager, int shadowMapSize) {
super(assetManager, shadowMapSize, new SpotLightShadowRenderer(assetManager, 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 { public void write(JmeExporter ex) throws IOException {
super.write(ex); super.write(ex);
OutputCapsule oc = ex.getCapsule(this); 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 { public void read(JmeImporter im) throws IOException {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
shadowRenderer = (SpotLightShadowRenderer) ic.readSavable("shadowRenderer", null);
} }
} }

@ -32,18 +32,19 @@
package com.jme3.shadow; package com.jme3.shadow;
import com.jme3.asset.AssetManager; 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.light.SpotLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.GeometryList;
import com.jme3.renderer.queue.OpaqueComparator;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import java.io.IOException;
/** /**
* SpotLightShadowRenderer renderer use Parrallel Split Shadow Mapping technique * SpotLightShadowRenderer renderer use Parrallel Split Shadow Mapping technique
@ -66,6 +67,14 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
protected Vector2f fadeInfo; protected Vector2f fadeInfo;
protected float fadeLength; protected float fadeLength;
/**
* Used for serialization use SpotLightShadowRenderer#SpotLightShadowRenderer(AssetManager assetManager, int shadowMapSize)
*/
public SpotLightShadowRenderer() {
super();
}
/** /**
* Create a SpotLightShadowRenderer This use standard shadow mapping * Create a SpotLightShadowRenderer This use standard shadow mapping
* *
@ -75,9 +84,12 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
*/ */
public SpotLightShadowRenderer(AssetManager assetManager, int shadowMapSize) { public SpotLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
super(assetManager, shadowMapSize, 1); super(assetManager, shadowMapSize, 1);
init(shadowMapSize);
}
shadowCam = new Camera(shadowMapSize, shadowMapSize);
private void init(int shadowMapSize) {
shadowCam = new Camera(shadowMapSize, shadowMapSize);
for (int i = 0; i < points.length; i++) { for (int i = 0; i < points.length; i++) {
points[i] = new Vector3f(); points[i] = new Vector3f();
} }
@ -213,4 +225,27 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
} }
return 0f; 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…
Cancel
Save