optimize clearing shadow maps
This commit is contained in:
parent
1e861fd2fa
commit
47b34c6de5
@ -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…
x
Reference in New Issue
Block a user