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