optimize clearing shadow maps

in-pass-shadows
Kirill Vainer 7 years ago
parent 1e861fd2fa
commit 47b34c6de5
  1. 8
      jme3-core/src/main/java/com/jme3/shadow/next/PreShadowArrayRenderer.java
  2. 30
      jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java
  3. 8
      jme3-core/src/main/java/com/jme3/shadow/next/array/DirectionalArrayShadowMap.java
  4. 13
      jme3-core/src/main/java/com/jme3/shadow/next/array/DirectionalArrayShadowMapSlice.java
  5. 5
      jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java
  6. 29
      jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMapSlice.java

@ -148,16 +148,14 @@ public class PreShadowArrayRenderer implements SceneProcessor {
array,
nextArraySlice,
textureSize,
directionalParams.getNumSplits(),
points);
directionalParams.getNumSplits());
break;
case Spot:
shadowMap = new SpotArrayShadowMap(
(SpotLight) light,
array,
nextArraySlice,
textureSize,
points);
textureSize);
break;
default:
throw new UnsupportedOperationException();
@ -202,7 +200,7 @@ public class PreShadowArrayRenderer implements SceneProcessor {
switch (shadowMap.getLightType()) {
case Directional:
DirectionalArrayShadowMap directionalShadow = (DirectionalArrayShadowMap) shadowMap;
directionalShadow.renderShadowMap(renderManager, viewPort, directionalParams, shadowCasters);
directionalShadow.renderShadowMap(renderManager, viewPort, directionalParams, shadowCasters, points);
break;
case Spot:
SpotArrayShadowMap spotShadow = (SpotArrayShadowMap) shadowMap;

@ -33,7 +33,6 @@ 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;
@ -51,12 +50,18 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
protected final FrameBuffer frameBuffer;
protected final Camera shadowCamera;
protected final Vector3f[] points;
protected final Matrix4f biasedViewProjectionMatrix = new Matrix4f();
public BaseArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
protected boolean fbNeedClear = true;
public BaseArrayShadowMapSlice(TextureArray array, int layer, int textureSize, boolean useBorder) {
this.shadowCamera = new Camera(textureSize, textureSize);
this.shadowCamera.setParallelProjection(true);
if (useBorder) {
float onePx = 1f / textureSize;
this.shadowCamera.setViewPort(onePx, 1f - onePx, onePx, 1f - onePx);
}
this.frameBuffer = new FrameBuffer(textureSize, textureSize, 1);
Image image = array.getImage();
@ -64,7 +69,6 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
image.addData(null);
this.frameBuffer.setDepthTexture(array, layer);
this.points = points;
}
@Override
@ -76,12 +80,18 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
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);
if (fbNeedClear) {
renderer.setFrameBuffer(frameBuffer);
renderer.clearBuffers(false, true, false);
fbNeedClear = false;
}
if (shadowCasters.size() > 0) {
renderManager.setCamera(shadowCamera, false);
viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
fbNeedClear = true;
}
viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix);
}
}

@ -48,23 +48,23 @@ public class DirectionalArrayShadowMap extends BaseArrayShadowMap<DirectionalArr
private final DirectionalLight light;
private final Vector3f projectionSplitPositions = new Vector3f();
public DirectionalArrayShadowMap(DirectionalLight light, TextureArray array, int firstArraySlice, int textureSize, int numSplits, Vector3f[] points) {
public DirectionalArrayShadowMap(DirectionalLight light, TextureArray array, int firstArraySlice, int textureSize, int numSplits) {
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);
this.slices[i] = new DirectionalArrayShadowMapSlice(array, firstArraySlice + i, textureSize);
}
}
public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, DirectionalShadowParameters params, GeometryList shadowCasters) {
public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, DirectionalShadowParameters params, GeometryList shadowCasters, Vector3f[] points) {
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].updateShadowCamera(viewPort, light, shadowCasters, near, far, points);
slices[i].renderShadowMap(renderManager, light, viewPort, shadowCasters);
}
}

@ -39,13 +39,12 @@ 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);
public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
super(array, layer, textureSize, true);
this.shadowCamera.setParallelProjection(true);
}
@ -54,12 +53,12 @@ public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<Dire
DirectionalLight light,
GeometryList shadowCasters,
float near,
float far) {
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
float far,
Vector3f[] points) {
shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
int textureSize = frameBuffer.getWidth();
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
}

@ -33,7 +33,6 @@ 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;
@ -46,11 +45,11 @@ public class SpotArrayShadowMap extends BaseArrayShadowMap<SpotArrayShadowMapSli
private final SpotLight light;
public SpotArrayShadowMap(SpotLight light, TextureArray array, int firstArraySlice, int textureSize, Vector3f[] points) {
public SpotArrayShadowMap(SpotLight light, TextureArray array, int firstArraySlice, int textureSize) {
super(array, firstArraySlice);
this.light = light;
slices = new SpotArrayShadowMapSlice[]{
new SpotArrayShadowMapSlice(array, firstArraySlice, textureSize, points)
new SpotArrayShadowMapSlice(array, firstArraySlice, textureSize)
};
}

@ -34,9 +34,10 @@ package com.jme3.shadow.next.array;
import com.jme3.light.SpotLight;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.GeometryList;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Spatial;
import com.jme3.shadow.ShadowUtil;
import com.jme3.texture.TextureArray;
@ -45,26 +46,16 @@ import com.jme3.texture.TextureArray;
*/
public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> {
public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
super(array, layer, textureSize, points);
public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
super(array, layer, textureSize, true);
}
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());
public void updateShadowCamera(ViewPort viewPort, SpotLight light, GeometryList shadowCasters) {
shadowCamera.setLocation(light.getPosition());
int textureSize = frameBuffer.getWidth();
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
shadowCamera.lookAtDirection(light.getDirection(), Vector3f.UNIT_Y);
shadowCamera.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1, light.getSpotRange());
for (Spatial scene : viewPort.getScenes()) {
ShadowUtil.getGeometriesInCamFrustum(scene, shadowCamera, RenderQueue.ShadowMode.Cast, shadowCasters);
}
}
}

Loading…
Cancel
Save