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
5151import 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 */
5860public 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