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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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) { |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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 { |
||||||
|
} |
@ -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(); |
||||||
|
} |
@ -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> { |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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…
Reference in new issue