Add PreShadowArrayRenderer
This commit is contained in:
parent
d159e1746c
commit
9c4fcac876
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.material.logic;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
|
import com.jme3.math.Matrix4f;
|
||||||
|
import com.jme3.math.Vector4f;
|
||||||
|
import com.jme3.renderer.Caps;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.shader.DefineList;
|
||||||
|
import com.jme3.shader.Shader;
|
||||||
|
import com.jme3.shader.Uniform;
|
||||||
|
import com.jme3.shader.VarType;
|
||||||
|
import com.jme3.shadow.next.array.ArrayShadowMap;
|
||||||
|
import com.jme3.shadow.next.array.ArrayShadowMapSlice;
|
||||||
|
import com.jme3.shadow.next.array.DirectionalArrayShadowMap;
|
||||||
|
import com.jme3.shadow.next.array.SpotArrayShadowMap;
|
||||||
|
import com.jme3.shadow.next.array.SpotArrayShadowMapSlice;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
|
||||||
|
|
||||||
|
private static final String DEFINE_NUM_PSSM_SPLITS = "NUM_PSSM_SPLITS";
|
||||||
|
private static final String DEFINE_NUM_SHADOW_DIR_LIGHTS = "NUM_SHADOW_DIR_LIGHTS";
|
||||||
|
private static final String DEFINE_NUM_SHADOW_POINT_LIGHTS = "NUM_SHADOW_POINT_LIGHTS";
|
||||||
|
private static final String DEFINE_NUM_SHADOW_SPOT_LIGHTS = "NUM_SHADOW_SPOT_LIGHTS";
|
||||||
|
|
||||||
|
private final int numPssmSplitsDefineId;
|
||||||
|
private final int numShadowDirLightsDefineId;
|
||||||
|
private final int numShadowPointLightsDefineId;
|
||||||
|
private final int numShadowSpotLightsDefineId;
|
||||||
|
private int numShadowDirLights = 0;
|
||||||
|
private int numShadowPointLights = 0;
|
||||||
|
private int numShadowSpotLights = 0;
|
||||||
|
private final Matrix4f[] shadowMatrices = new Matrix4f[5];
|
||||||
|
|
||||||
|
public ShadowStaticPassLightingLogic(TechniqueDef techniqueDef) {
|
||||||
|
super(techniqueDef);
|
||||||
|
numPssmSplitsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_PSSM_SPLITS, VarType.Int);
|
||||||
|
numShadowDirLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_DIR_LIGHTS, VarType.Int);
|
||||||
|
numShadowPointLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_POINT_LIGHTS, VarType.Int);
|
||||||
|
numShadowSpotLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_SPOT_LIGHTS, VarType.Int);
|
||||||
|
|
||||||
|
for (int i = 0; i < shadowMatrices.length; i++) {
|
||||||
|
shadowMatrices[i] = new Matrix4f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void makeCurrentBase(AssetManager assetManager, RenderManager renderManager,
|
||||||
|
EnumSet<Caps> rendererCaps, LightList lights, DefineList defines) {
|
||||||
|
|
||||||
|
tempDirLights.clear();
|
||||||
|
tempPointLights.clear();
|
||||||
|
tempSpotLights.clear();
|
||||||
|
ambientLightColor.set(0, 0, 0, 1);
|
||||||
|
numShadowDirLights = 0;
|
||||||
|
numShadowPointLights = 0;
|
||||||
|
numShadowSpotLights = 0;
|
||||||
|
|
||||||
|
int pssmSplits = 0;
|
||||||
|
|
||||||
|
for (Light light : lights) {
|
||||||
|
switch (light.getType()) {
|
||||||
|
case Directional:
|
||||||
|
if (light.getShadowMap() != null) {
|
||||||
|
pssmSplits = light.getShadowMap().getNumSlices();
|
||||||
|
tempDirLights.add(numShadowDirLights, (DirectionalLight) light);
|
||||||
|
numShadowDirLights++;
|
||||||
|
} else {
|
||||||
|
tempDirLights.add((DirectionalLight) light);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Point:
|
||||||
|
if (light.getShadowMap() != null) {
|
||||||
|
tempPointLights.add(numShadowPointLights, (PointLight) light);
|
||||||
|
numShadowPointLights++;
|
||||||
|
} else {
|
||||||
|
tempPointLights.add((PointLight) light);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Spot:
|
||||||
|
if (light.getShadowMap() != null) {
|
||||||
|
tempSpotLights.add(numShadowSpotLights, (SpotLight) light);
|
||||||
|
numShadowSpotLights++;
|
||||||
|
} else {
|
||||||
|
tempSpotLights.add((SpotLight) light);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Ambient:
|
||||||
|
ambientLightColor.addLocal(light.getColor());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ambientLightColor.a = 1.0f;
|
||||||
|
|
||||||
|
defines.set(numDirLightsDefineId, tempDirLights.size());
|
||||||
|
defines.set(numPointLightsDefineId, tempPointLights.size());
|
||||||
|
defines.set(numSpotLightsDefineId, tempSpotLights.size());
|
||||||
|
|
||||||
|
defines.set(numShadowDirLightsDefineId, numShadowDirLights);
|
||||||
|
defines.set(numShadowPointLightsDefineId, numShadowPointLights);
|
||||||
|
defines.set(numShadowSpotLightsDefineId, numShadowSpotLights);
|
||||||
|
|
||||||
|
defines.set(numPssmSplitsDefineId, pssmSplits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getShadowMapIndex(Light light) {
|
||||||
|
if (light.getShadowMap() == null) {
|
||||||
|
return -1.0f;
|
||||||
|
}
|
||||||
|
ArrayShadowMap map = (ArrayShadowMap) light.getShadowMap();
|
||||||
|
return (float) map.getFirstArraySlice();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateShadowUniforms(Renderer renderer, Shader shader, int nextTextureUnit) {
|
||||||
|
TextureArray array = null;
|
||||||
|
Vector4f pssmSplits = null;
|
||||||
|
|
||||||
|
Uniform shadowMatricesUniform = shader.getUniform("g_ShadowMatrices");
|
||||||
|
int shadowMatrixIndex = 0;
|
||||||
|
for (int i = 0; i < numShadowDirLights; i++) {
|
||||||
|
DirectionalArrayShadowMap map = (DirectionalArrayShadowMap) tempDirLights.get(i).getShadowMap();
|
||||||
|
array = map.getArray();
|
||||||
|
pssmSplits = map.getProjectionSplitPositions();
|
||||||
|
for (int j = 0; j < map.getNumSlices(); j++) {
|
||||||
|
ArrayShadowMapSlice slice = (ArrayShadowMapSlice) map.getSlice(j);
|
||||||
|
BIAS_MATRIX.mult(slice.getViewProjectionMatrix(), shadowMatrices[shadowMatrixIndex]);
|
||||||
|
shadowMatrixIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < numShadowSpotLights; i++) {
|
||||||
|
SpotArrayShadowMap map = (SpotArrayShadowMap) tempSpotLights.get(i).getShadowMap();
|
||||||
|
array = map.getArray();
|
||||||
|
SpotArrayShadowMapSlice slice = map.getSlice(0);
|
||||||
|
BIAS_MATRIX.mult(slice.getViewProjectionMatrix(), shadowMatrices[shadowMatrixIndex]);
|
||||||
|
shadowMatrixIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowMatricesUniform.setValue(VarType.Matrix4Array, shadowMatrices);
|
||||||
|
if (array != null) {
|
||||||
|
renderer.setTexture(nextTextureUnit, array);
|
||||||
|
Uniform shadowMapArrayUniform = shader.getUniform("g_ShadowMapArray");
|
||||||
|
shadowMapArrayUniform.setValue(VarType.Int, nextTextureUnit);
|
||||||
|
}
|
||||||
|
if (pssmSplits != null) {
|
||||||
|
Uniform pssmSplitsUniform = shader.getUniform("g_PssmSplits");
|
||||||
|
pssmSplitsUniform.setValue(VarType.Vector4, pssmSplits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
248
jme3-core/src/main/java/com/jme3/shadow/next/PreShadowArrayRenderer.java
Executable file
248
jme3-core/src/main/java/com/jme3/shadow/next/PreShadowArrayRenderer.java
Executable file
@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next;
|
||||||
|
|
||||||
|
import com.jme3.shadow.next.pssm.DirectionalShadowParameters;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.post.SceneProcessor;
|
||||||
|
import com.jme3.profile.AppProfiler;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.renderer.queue.OpaqueComparator;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.shadow.next.array.DirectionalArrayShadowMap;
|
||||||
|
import com.jme3.shadow.next.array.SpotArrayShadowMap;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.texture.Texture.MagFilter;
|
||||||
|
import com.jme3.texture.Texture.MinFilter;
|
||||||
|
import com.jme3.texture.Texture.ShadowCompareMode;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
import com.jme3.texture.image.ColorSpace;
|
||||||
|
import com.jme3.util.ListMap;
|
||||||
|
import com.jme3.util.TempVars;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 4th generation of shadow mapping in jME3.
|
||||||
|
* <p>
|
||||||
|
* This version is primarily focused on rendering in-pass shadows, so pre-pass
|
||||||
|
* and subsequent stages are separated.
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class PreShadowArrayRenderer implements SceneProcessor {
|
||||||
|
|
||||||
|
private static final String PRE_SHADOW_TECHNIQUE_NAME = "PreShadow";
|
||||||
|
|
||||||
|
private RenderManager renderManager;
|
||||||
|
private ViewPort viewPort;
|
||||||
|
private final Vector3f[] points = new Vector3f[8];
|
||||||
|
private final GeometryList shadowCasters = new GeometryList(new OpaqueComparator());
|
||||||
|
private final ListMap<Light, ShadowMap> shadowedLights = new ListMap<>();
|
||||||
|
private final RenderState prePassRenderState = RenderState.ADDITIONAL.clone();
|
||||||
|
private final TextureArray array = new TextureArray();
|
||||||
|
|
||||||
|
private int textureSize = 1024;
|
||||||
|
private int nextArraySlice = 0;
|
||||||
|
|
||||||
|
// parameters for directional lights
|
||||||
|
private final DirectionalShadowParameters directionalParams = new DirectionalShadowParameters();
|
||||||
|
|
||||||
|
public PreShadowArrayRenderer() {
|
||||||
|
for (int i = 0; i < points.length; i++) {
|
||||||
|
points[i] = new Vector3f();
|
||||||
|
}
|
||||||
|
|
||||||
|
prePassRenderState.setFaceCullMode(RenderState.FaceCullMode.Front);
|
||||||
|
prePassRenderState.setColorWrite(false);
|
||||||
|
prePassRenderState.setDepthWrite(true);
|
||||||
|
prePassRenderState.setDepthTest(true);
|
||||||
|
prePassRenderState.setPolyOffset(0, 0);
|
||||||
|
|
||||||
|
array.setAnisotropicFilter(1);
|
||||||
|
array.setShadowCompareMode(ShadowCompareMode.LessOrEqual);
|
||||||
|
array.setMagFilter(MagFilter.Nearest);
|
||||||
|
array.setMinFilter(MinFilter.NearestNoMipMaps);
|
||||||
|
|
||||||
|
array.setMagFilter(MagFilter.Bilinear);
|
||||||
|
array.setMinFilter(MinFilter.BilinearNoMipMaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(RenderManager rm, ViewPort vp) {
|
||||||
|
this.renderManager = rm;
|
||||||
|
this.viewPort = vp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectionalShadowParameters directional() {
|
||||||
|
return directionalParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolyOffset(float factor, float units) {
|
||||||
|
prePassRenderState.setPolyOffset(factor, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTextureSize() {
|
||||||
|
return textureSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextureSize(int textureSize) {
|
||||||
|
// TODO: support changing texture size after shadow maps are created
|
||||||
|
this.textureSize = textureSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLight(Light light) {
|
||||||
|
if (array.getImage() == null) {
|
||||||
|
array.setImage(new Image(
|
||||||
|
Format.Depth32F,
|
||||||
|
textureSize,
|
||||||
|
textureSize,
|
||||||
|
0,
|
||||||
|
new ArrayList<ByteBuffer>(),
|
||||||
|
ColorSpace.Linear));
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowMap shadowMap;
|
||||||
|
switch (light.getType()) {
|
||||||
|
case Directional:
|
||||||
|
shadowMap = new DirectionalArrayShadowMap(
|
||||||
|
(DirectionalLight) light,
|
||||||
|
array,
|
||||||
|
nextArraySlice,
|
||||||
|
textureSize,
|
||||||
|
directionalParams.getNumSplits(),
|
||||||
|
points);
|
||||||
|
break;
|
||||||
|
case Spot:
|
||||||
|
shadowMap = new SpotArrayShadowMap(
|
||||||
|
(SpotLight) light,
|
||||||
|
array,
|
||||||
|
nextArraySlice,
|
||||||
|
textureSize,
|
||||||
|
points);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowedLights.put(light, shadowMap);
|
||||||
|
nextArraySlice += shadowMap.getNumSlices();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reshape(ViewPort vp, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return this.viewPort != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preFrame(float tpf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderShadowMaps(ViewPort viewPort) {
|
||||||
|
renderManager.setForcedRenderState(prePassRenderState);
|
||||||
|
renderManager.setForcedTechnique(PRE_SHADOW_TECHNIQUE_NAME);
|
||||||
|
|
||||||
|
for (int i = 0; i < shadowedLights.size(); i++) {
|
||||||
|
Light light = shadowedLights.getKey(i);
|
||||||
|
ShadowMap shadowMap = shadowedLights.getValue(i);
|
||||||
|
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
try {
|
||||||
|
light.setFrustumCheckNeeded(false);
|
||||||
|
light.setIntersectsFrustum(light.intersectsFrustum(viewPort.getCamera(), vars));
|
||||||
|
if (!light.isIntersectsFrustum()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
vars.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (shadowMap.getLightType()) {
|
||||||
|
case Directional:
|
||||||
|
DirectionalArrayShadowMap directionalShadow = (DirectionalArrayShadowMap) shadowMap;
|
||||||
|
directionalShadow.renderShadowMap(renderManager, viewPort, directionalParams, shadowCasters);
|
||||||
|
break;
|
||||||
|
case Spot:
|
||||||
|
SpotArrayShadowMap spotShadow = (SpotArrayShadowMap) shadowMap;
|
||||||
|
spotShadow.renderShadowMap(renderManager, viewPort, shadowCasters);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
light.setShadowMap(shadowMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer renderer = renderManager.getRenderer();
|
||||||
|
renderer.setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
|
renderManager.setForcedRenderState(null);
|
||||||
|
renderManager.setForcedTechnique(null);
|
||||||
|
renderManager.setCamera(viewPort.getCamera(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postQueue(RenderQueue rq) {
|
||||||
|
directionalParams.updateSplitPositions(viewPort.getCamera());
|
||||||
|
renderShadowMaps(viewPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postFrame(FrameBuffer out) {
|
||||||
|
// TODO: call discard contents on all the framebuffers.
|
||||||
|
for (int i = 0; i < shadowedLights.size(); i++) {
|
||||||
|
Light light = shadowedLights.getKey(i);
|
||||||
|
light.setShadowMap(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProfiler(AppProfiler profiler) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
jme3-core/src/main/java/com/jme3/shadow/next/ShadowParameters.java
Executable file
38
jme3-core/src/main/java/com/jme3/shadow/next/ShadowParameters.java
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public interface ShadowParameters {
|
||||||
|
}
|
47
jme3-core/src/main/java/com/jme3/shadow/next/array/ArrayShadowMap.java
Executable file
47
jme3-core/src/main/java/com/jme3/shadow/next/array/ArrayShadowMap.java
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.shadow.next.ShadowMap;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents shadow information for a light, uses texture arrays.
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public interface ArrayShadowMap extends ShadowMap {
|
||||||
|
|
||||||
|
public TextureArray getArray();
|
||||||
|
|
||||||
|
public int getFirstArraySlice();
|
||||||
|
}
|
41
jme3-core/src/main/java/com/jme3/shadow/next/array/ArrayShadowMapSlice.java
Executable file
41
jme3-core/src/main/java/com/jme3/shadow/next/array/ArrayShadowMapSlice.java
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.shadow.next.ShadowMapSlice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public interface ArrayShadowMapSlice<T extends Light> extends ShadowMapSlice<T> {
|
||||||
|
}
|
75
jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMap.java
Executable file
75
jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMap.java
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public abstract class BaseArrayShadowMap<T extends ArrayShadowMapSlice> implements ArrayShadowMap {
|
||||||
|
|
||||||
|
protected final TextureArray array;
|
||||||
|
protected final int firstArraySlice;
|
||||||
|
protected T[] slices;
|
||||||
|
|
||||||
|
public BaseArrayShadowMap(TextureArray array, int firstArraySlice) {
|
||||||
|
this.array = array;
|
||||||
|
this.firstArraySlice = firstArraySlice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextureArray getArray() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstArraySlice() {
|
||||||
|
return firstArraySlice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract Light.Type getLightType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumSlices() {
|
||||||
|
return slices.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getSlice(int index) {
|
||||||
|
return slices[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.math.Matrix4f;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param <T>
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapSlice<T> {
|
||||||
|
|
||||||
|
protected final FrameBuffer frameBuffer;
|
||||||
|
protected final Camera shadowCamera;
|
||||||
|
protected final Vector3f[] points;
|
||||||
|
|
||||||
|
public BaseArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
|
||||||
|
this.shadowCamera = new Camera(textureSize, textureSize);
|
||||||
|
this.shadowCamera.setParallelProjection(true);
|
||||||
|
this.frameBuffer = new FrameBuffer(textureSize, textureSize, 1);
|
||||||
|
|
||||||
|
Image image = array.getImage();
|
||||||
|
image.setDepth(image.getDepth() + 1);
|
||||||
|
image.addData(null);
|
||||||
|
|
||||||
|
this.frameBuffer.setDepthTexture(array, layer);
|
||||||
|
this.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Matrix4f getViewProjectionMatrix() {
|
||||||
|
return shadowCamera.getViewProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderShadowMap(RenderManager renderManager, Light light, ViewPort viewPort, GeometryList shadowCasters) {
|
||||||
|
Renderer renderer = renderManager.getRenderer();
|
||||||
|
|
||||||
|
renderer.setFrameBuffer(frameBuffer);
|
||||||
|
renderManager.setCamera(shadowCamera, false);
|
||||||
|
renderer.clearBuffers(false, true, false);
|
||||||
|
|
||||||
|
viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.math.Vector4f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.shadow.next.pssm.DirectionalShadowParameters;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class DirectionalArrayShadowMap extends BaseArrayShadowMap<DirectionalArrayShadowMapSlice> {
|
||||||
|
|
||||||
|
private final DirectionalLight light;
|
||||||
|
private final Vector4f projectionSplitPositions = new Vector4f();
|
||||||
|
|
||||||
|
public DirectionalArrayShadowMap(DirectionalLight light, TextureArray array, int firstArraySlice, int textureSize, int numSplits, Vector3f[] points) {
|
||||||
|
super(array, firstArraySlice);
|
||||||
|
this.light = light;
|
||||||
|
this.slices = new DirectionalArrayShadowMapSlice[numSplits];
|
||||||
|
for (int i = 0; i < numSplits; i++) {
|
||||||
|
this.slices[i] = new DirectionalArrayShadowMapSlice(array, firstArraySlice + i, textureSize, points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, DirectionalShadowParameters params, GeometryList shadowCasters) {
|
||||||
|
projectionSplitPositions.set(params.getProjectionSplitPositions());
|
||||||
|
float[] splitPositionsViewSpace = params.getSplitPositions();
|
||||||
|
for (int i = 0; i < slices.length; i++) {
|
||||||
|
float near = splitPositionsViewSpace[i];
|
||||||
|
float far = splitPositionsViewSpace[i + 1];
|
||||||
|
shadowCasters.clear();
|
||||||
|
slices[i].updateShadowCamera(viewPort, light, shadowCasters, near, far);
|
||||||
|
slices[i].renderShadowMap(renderManager, light, viewPort, shadowCasters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4f getProjectionSplitPositions() {
|
||||||
|
return projectionSplitPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Light.Type getLightType() {
|
||||||
|
return Light.Type.Directional;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.shadow.ShadowUtil;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<DirectionalLight> {
|
||||||
|
|
||||||
|
public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
|
||||||
|
super(array, layer, textureSize, points);
|
||||||
|
this.shadowCamera.setParallelProjection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateShadowCamera(
|
||||||
|
ViewPort viewPort,
|
||||||
|
DirectionalLight light,
|
||||||
|
GeometryList shadowCasters,
|
||||||
|
float near,
|
||||||
|
float far) {
|
||||||
|
|
||||||
|
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
|
||||||
|
shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
|
||||||
|
|
||||||
|
int textureSize = frameBuffer.getWidth();
|
||||||
|
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java
Executable file
68
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java
Executable file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class SpotArrayShadowMap extends BaseArrayShadowMap<SpotArrayShadowMapSlice> {
|
||||||
|
|
||||||
|
private final SpotLight light;
|
||||||
|
|
||||||
|
public SpotArrayShadowMap(SpotLight light, TextureArray array, int firstArraySlice, int textureSize, Vector3f[] points) {
|
||||||
|
super(array, firstArraySlice);
|
||||||
|
this.light = light;
|
||||||
|
slices = new SpotArrayShadowMapSlice[]{
|
||||||
|
new SpotArrayShadowMapSlice(array, firstArraySlice, textureSize, points)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, GeometryList shadowCasters) {
|
||||||
|
shadowCasters.clear();
|
||||||
|
slices[0].updateShadowCamera(viewPort, light, shadowCasters);
|
||||||
|
slices[0].renderShadowMap(renderManager, light, viewPort, shadowCasters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Light.Type getLightType() {
|
||||||
|
return Light.Type.Spot;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.array;
|
||||||
|
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Matrix4f;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
|
import com.jme3.shadow.ShadowUtil;
|
||||||
|
import com.jme3.texture.TextureArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> {
|
||||||
|
|
||||||
|
public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
|
||||||
|
super(array, layer, textureSize, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateShadowCamera(
|
||||||
|
ViewPort viewPort,
|
||||||
|
SpotLight light,
|
||||||
|
GeometryList shadowCasters) {
|
||||||
|
|
||||||
|
Camera viewCamera = viewPort.getCamera();
|
||||||
|
float near = viewCamera.getFrustumNear();
|
||||||
|
float far = viewCamera.getFrustumFar();
|
||||||
|
|
||||||
|
ShadowUtil.updateFrustumPoints(viewCamera, near, far, points);
|
||||||
|
|
||||||
|
shadowCamera.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1, light.getSpotRange());
|
||||||
|
shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
|
||||||
|
shadowCamera.setLocation(light.getPosition());
|
||||||
|
|
||||||
|
int textureSize = frameBuffer.getWidth();
|
||||||
|
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.shadow.next.pssm;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector4f;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.shadow.PssmShadowUtil;
|
||||||
|
import com.jme3.shadow.next.ShadowParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public final class DirectionalShadowParameters implements ShadowParameters {
|
||||||
|
|
||||||
|
private float lambda = 0.65f;
|
||||||
|
private int numSplits = 4;
|
||||||
|
protected float zFarOverride = 0;
|
||||||
|
private float[] splitPositions = new float[numSplits + 1];
|
||||||
|
private final Vector4f projectionSplitPositions = new Vector4f();
|
||||||
|
|
||||||
|
public float getLambda() {
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLambda(float lambda) {
|
||||||
|
this.lambda = lambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumSplits() {
|
||||||
|
return numSplits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumSplits(int numSplits) {
|
||||||
|
// TODO: ensure it is 1 to 4
|
||||||
|
this.numSplits = numSplits;
|
||||||
|
this.splitPositions = new float[numSplits + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getSplitPositions() {
|
||||||
|
return splitPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4f getProjectionSplitPositions() {
|
||||||
|
return projectionSplitPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How far the shadows are rendered in the view
|
||||||
|
*
|
||||||
|
* @see #setShadowZExtend(float zFar)
|
||||||
|
* @return shadowZExtend
|
||||||
|
*/
|
||||||
|
public float getShadowZExtend() {
|
||||||
|
return zFarOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the distance from the eye where the shadows will be rendered.
|
||||||
|
*
|
||||||
|
* The default value is dynamically computed based on the shadow
|
||||||
|
* casters/receivers union bound zFar, capped to view frustum far value.
|
||||||
|
*
|
||||||
|
* @param zFar the zFar values that override the computed one
|
||||||
|
*/
|
||||||
|
public void setShadowZExtend(float zFar) {
|
||||||
|
this.zFarOverride = zFar;
|
||||||
|
|
||||||
|
// TODO: Fade length not supported yet
|
||||||
|
// if (zFarOverride == 0) {
|
||||||
|
// fadeInfo = null;
|
||||||
|
// frustumCam = null;
|
||||||
|
// } else {
|
||||||
|
// if (fadeInfo != null) {
|
||||||
|
// fadeInfo.set(zFarOverride - fadeLength, 1f / fadeLength);
|
||||||
|
// }
|
||||||
|
// if (frustumCam == null && viewPort != null) {
|
||||||
|
// initFrustumCam();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateSplitPositions(Camera viewCamera) {
|
||||||
|
float near = viewCamera.getFrustumNear();
|
||||||
|
float far = zFarOverride == 0f ? viewCamera.getFrustumFar() : zFarOverride;
|
||||||
|
|
||||||
|
PssmShadowUtil.updateFrustumSplits(splitPositions, near, far, lambda);
|
||||||
|
|
||||||
|
// TODO: Parallel projection can have negative near value, so split
|
||||||
|
// positions must be adjusted.
|
||||||
|
// if (viewCamera.isParallelProjection()) {
|
||||||
|
// for (int i = 0; i < splitPositions.length; i++) {
|
||||||
|
// splitPositions[i] = splitPositions[i] / (far - near);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
switch (splitPositions.length) {
|
||||||
|
case 5:
|
||||||
|
projectionSplitPositions.w = 1.0f; // = viewCamera.getViewToProjectionZ(splitPositions[4]);
|
||||||
|
case 4:
|
||||||
|
projectionSplitPositions.z = viewCamera.getViewToProjectionZ(splitPositions[3]);
|
||||||
|
case 3:
|
||||||
|
projectionSplitPositions.y = viewCamera.getViewToProjectionZ(splitPositions[2]);
|
||||||
|
case 2:
|
||||||
|
case 1:
|
||||||
|
projectionSplitPositions.x = viewCamera.getViewToProjectionZ(splitPositions[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user