Skip to content

Commit 112ff1f

Browse files
authored
Merge pull request #2514 from capdevon/capdevon-PointLightShadowRenderer
Refactor: PointLightShadowRenderer reduce object allocations
2 parents 1f8b5ed + 85722e8 commit 112ff1f

File tree

1 file changed

+41
-44
lines changed

1 file changed

+41
-44
lines changed

jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2021 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -51,33 +51,39 @@
5151
import java.io.IOException;
5252

5353
/**
54-
* PointLightShadowRenderer renders shadows for a point light
54+
* Renders shadows for a {@link PointLight}. This renderer uses six cameras,
55+
* one for each face of a cube map, to capture shadows from the point light's
56+
* perspective.
5557
*
5658
* @author Rémy Bouquet aka Nehon
5759
*/
5860
public class PointLightShadowRenderer extends AbstractShadowRenderer {
5961

62+
/**
63+
* The fixed number of cameras used for rendering point light shadows (6 for a cube map).
64+
*/
6065
public static final int CAM_NUMBER = 6;
66+
6167
protected PointLight light;
6268
protected Camera[] shadowCams;
63-
private Geometry[] frustums = null;
69+
protected Geometry[] frustums = null;
70+
protected final Vector3f X_NEG = Vector3f.UNIT_X.mult(-1f);
71+
protected final Vector3f Y_NEG = Vector3f.UNIT_Y.mult(-1f);
72+
protected final Vector3f Z_NEG = Vector3f.UNIT_Z.mult(-1f);
6473

6574
/**
66-
* Used for serialization.
67-
* Use PointLightShadowRenderer#PointLightShadowRenderer(AssetManager
68-
* assetManager, int shadowMapSize)
69-
* instead.
75+
* For serialization only. Do not use.
7076
*/
7177
protected PointLightShadowRenderer() {
7278
super();
7379
}
7480

7581
/**
76-
* Creates a PointLightShadowRenderer
82+
* Creates a new {@code PointLightShadowRenderer} instance.
7783
*
78-
* @param assetManager the application asset manager
79-
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
80-
* etc...)
84+
* @param assetManager The application's asset manager.
85+
* @param shadowMapSize The size of the rendered shadow maps (e.g., 512, 1024, 2048).
86+
* Higher values produce better quality shadows but may impact performance.
8187
*/
8288
public PointLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
8389
super(assetManager, shadowMapSize, CAM_NUMBER);
@@ -86,7 +92,7 @@ public PointLightShadowRenderer(AssetManager assetManager, int shadowMapSize) {
8692

8793
private void init(int shadowMapSize) {
8894
shadowCams = new Camera[CAM_NUMBER];
89-
for (int i = 0; i < CAM_NUMBER; i++) {
95+
for (int i = 0; i < shadowCams.length; i++) {
9096
shadowCams[i] = new Camera(shadowMapSize, shadowMapSize);
9197
}
9298
}
@@ -95,9 +101,9 @@ private void init(int shadowMapSize) {
95101
protected void initFrustumCam() {
96102
Camera viewCam = viewPort.getCamera();
97103
frustumCam = viewCam.clone();
98-
frustumCam.setFrustum(viewCam.getFrustumNear(), zFarOverride, viewCam.getFrustumLeft(), viewCam.getFrustumRight(), viewCam.getFrustumTop(), viewCam.getFrustumBottom());
104+
frustumCam.setFrustum(viewCam.getFrustumNear(), zFarOverride,
105+
viewCam.getFrustumLeft(), viewCam.getFrustumRight(), viewCam.getFrustumTop(), viewCam.getFrustumBottom());
99106
}
100-
101107

102108
@Override
103109
protected void updateShadowCams(Camera viewCam) {
@@ -107,31 +113,21 @@ protected void updateShadowCams(Camera viewCam) {
107113
return;
108114
}
109115

110-
//bottom
111-
shadowCams[0].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y.mult(-1f));
112-
113-
//top
114-
shadowCams[1].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z, Vector3f.UNIT_Y);
115-
116-
//forward
117-
shadowCams[2].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_Z.mult(-1f));
118-
119-
//backward
120-
shadowCams[3].setAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z);
121-
122-
//left
123-
shadowCams[4].setAxes(Vector3f.UNIT_Z, Vector3f.UNIT_Y, Vector3f.UNIT_X.mult(-1f));
124-
125-
//right
126-
shadowCams[5].setAxes(Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_X);
127-
128-
for (int i = 0; i < CAM_NUMBER; i++) {
129-
shadowCams[i].setFrustumPerspective(90f, 1f, 0.1f, light.getRadius());
130-
shadowCams[i].setLocation(light.getPosition());
131-
shadowCams[i].update();
132-
shadowCams[i].updateViewProjection();
116+
// Configure axes for each of the six cube map cameras (positive/negative X, Y, Z)
117+
shadowCams[0].setAxes(X_NEG, Z_NEG, Y_NEG); // -Y (bottom)
118+
shadowCams[1].setAxes(X_NEG, Vector3f.UNIT_Z, Vector3f.UNIT_Y); // +Y (top)
119+
shadowCams[2].setAxes(X_NEG, Vector3f.UNIT_Y, Z_NEG); // +Z (forward)
120+
shadowCams[3].setAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z); // -Z (backward)
121+
shadowCams[4].setAxes(Vector3f.UNIT_Z, Vector3f.UNIT_Y, X_NEG); // -X (left)
122+
shadowCams[5].setAxes(Z_NEG, Vector3f.UNIT_Y, Vector3f.UNIT_X); // +X (right)
123+
124+
// Set perspective and location for all shadow cameras
125+
for (Camera shadowCam : shadowCams) {
126+
shadowCam.setFrustumPerspective(90f, 1f, 0.1f, light.getRadius());
127+
shadowCam.setLocation(light.getPosition());
128+
shadowCam.update();
129+
shadowCam.updateViewProjection();
133130
}
134-
135131
}
136132

137133
@Override
@@ -160,16 +156,17 @@ protected void doDisplayFrustumDebug(int shadowMapIndex) {
160156
if (frustums == null) {
161157
frustums = new Geometry[CAM_NUMBER];
162158
Vector3f[] points = new Vector3f[8];
163-
for (int i = 0; i < 8; i++) {
159+
for (int i = 0; i < points.length; i++) {
164160
points[i] = new Vector3f();
165161
}
166162
for (int i = 0; i < CAM_NUMBER; i++) {
167163
ShadowUtil.updateFrustumPoints2(shadowCams[i], points);
168164
frustums[i] = createFrustum(points, i);
169165
}
170166
}
171-
if (frustums[shadowMapIndex].getParent() == null) {
172-
((Node) viewPort.getScenes().get(0)).attachChild(frustums[shadowMapIndex]);
167+
Geometry geo = frustums[shadowMapIndex];
168+
if (geo.getParent() == null) {
169+
((Node) viewPort.getScenes().get(0)).attachChild(geo);
173170
}
174171
}
175172

@@ -237,13 +234,13 @@ protected boolean checkCulling(Camera viewCam) {
237234
}
238235

239236
Camera cam = viewCam;
240-
if(frustumCam != null){
241-
cam = frustumCam;
237+
if (frustumCam != null) {
238+
cam = frustumCam;
242239
cam.setLocation(viewCam.getLocation());
243240
cam.setRotation(viewCam.getRotation());
244241
}
245242
TempVars vars = TempVars.get();
246-
boolean intersects = light.intersectsFrustum(cam,vars);
243+
boolean intersects = light.intersectsFrustum(cam, vars);
247244
vars.release();
248245
return intersects;
249246
}

0 commit comments

Comments
 (0)