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