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

@ -33,7 +33,6 @@ package com.jme3.shadow.next.array;
import com.jme3.light.Light; import com.jme3.light.Light;
import com.jme3.math.Matrix4f; import com.jme3.math.Matrix4f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager; import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer; import com.jme3.renderer.Renderer;
@ -51,12 +50,18 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
protected final FrameBuffer frameBuffer; protected final FrameBuffer frameBuffer;
protected final Camera shadowCamera; protected final Camera shadowCamera;
protected final Vector3f[] points;
protected final Matrix4f biasedViewProjectionMatrix = new Matrix4f(); 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 = 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); this.frameBuffer = new FrameBuffer(textureSize, textureSize, 1);
Image image = array.getImage(); Image image = array.getImage();
@ -64,7 +69,6 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
image.addData(null); image.addData(null);
this.frameBuffer.setDepthTexture(array, layer); this.frameBuffer.setDepthTexture(array, layer);
this.points = points;
} }
@Override @Override
@ -76,11 +80,17 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
public void renderShadowMap(RenderManager renderManager, Light light, ViewPort viewPort, GeometryList shadowCasters) { public void renderShadowMap(RenderManager renderManager, Light light, ViewPort viewPort, GeometryList shadowCasters) {
Renderer renderer = renderManager.getRenderer(); Renderer renderer = renderManager.getRenderer();
if (fbNeedClear) {
renderer.setFrameBuffer(frameBuffer); renderer.setFrameBuffer(frameBuffer);
renderManager.setCamera(shadowCamera, false);
renderer.clearBuffers(false, true, false); renderer.clearBuffers(false, true, false);
fbNeedClear = false;
}
if (shadowCasters.size() > 0) {
renderManager.setCamera(shadowCamera, false);
viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true); viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
fbNeedClear = true;
}
BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix); BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix);
} }

@ -48,23 +48,23 @@ public class DirectionalArrayShadowMap extends BaseArrayShadowMap<DirectionalArr
private final DirectionalLight light; private final DirectionalLight light;
private final Vector3f projectionSplitPositions = new Vector3f(); 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); super(array, firstArraySlice);
this.light = light; this.light = light;
this.slices = new DirectionalArrayShadowMapSlice[numSplits]; this.slices = new DirectionalArrayShadowMapSlice[numSplits];
for (int i = 0; i < numSplits; i++) { 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()); projectionSplitPositions.set(params.getProjectionSplitPositions());
float[] splitPositionsViewSpace = params.getSplitPositions(); float[] splitPositionsViewSpace = params.getSplitPositions();
for (int i = 0; i < slices.length; i++) { for (int i = 0; i < slices.length; i++) {
float near = splitPositionsViewSpace[i]; float near = splitPositionsViewSpace[i];
float far = splitPositionsViewSpace[i + 1]; float far = splitPositionsViewSpace[i + 1];
shadowCasters.clear(); 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); slices[i].renderShadowMap(renderManager, light, viewPort, shadowCasters);
} }
} }

@ -39,13 +39,12 @@ import com.jme3.shadow.ShadowUtil;
import com.jme3.texture.TextureArray; import com.jme3.texture.TextureArray;
/** /**
*
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<DirectionalLight> { public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<DirectionalLight> {
public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) { public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
super(array, layer, textureSize, points); super(array, layer, textureSize, true);
this.shadowCamera.setParallelProjection(true); this.shadowCamera.setParallelProjection(true);
} }
@ -54,12 +53,12 @@ public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<Dire
DirectionalLight light, DirectionalLight light,
GeometryList shadowCasters, GeometryList shadowCasters,
float near, float near,
float far) { float far,
Vector3f[] points) {
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp()); shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
int textureSize = frameBuffer.getWidth(); int textureSize = frameBuffer.getWidth();
ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize); 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.Light;
import com.jme3.light.SpotLight; import com.jme3.light.SpotLight;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager; import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.GeometryList;
@ -46,11 +45,11 @@ public class SpotArrayShadowMap extends BaseArrayShadowMap<SpotArrayShadowMapSli
private final SpotLight light; 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); super(array, firstArraySlice);
this.light = light; this.light = light;
slices = new SpotArrayShadowMapSlice[]{ 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.light.SpotLight;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.GeometryList; 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.shadow.ShadowUtil;
import com.jme3.texture.TextureArray; import com.jme3.texture.TextureArray;
@ -45,26 +46,16 @@ import com.jme3.texture.TextureArray;
*/ */
public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> { public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> {
public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) { public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
super(array, layer, textureSize, points); super(array, layer, textureSize, true);
} }
public void updateShadowCamera( public void updateShadowCamera(ViewPort viewPort, SpotLight light, GeometryList shadowCasters) {
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()); shadowCamera.setLocation(light.getPosition());
shadowCamera.lookAtDirection(light.getDirection(), Vector3f.UNIT_Y);
int textureSize = frameBuffer.getWidth(); shadowCamera.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1, light.getSpotRange());
ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize); for (Spatial scene : viewPort.getScenes()) {
ShadowUtil.getGeometriesInCamFrustum(scene, shadowCamera, RenderQueue.ShadowMode.Cast, shadowCasters);
}
} }
} }

Loading…
Cancel
Save