From c5363ba46e588e35bb06f38e0763ed9580d08046 Mon Sep 17 00:00:00 2001 From: Wyatt Gillette Date: Mon, 23 Jun 2025 17:23:08 +0200 Subject: [PATCH 1/2] Update AbstractShadowRenderer.java --- .../jme3/shadow/AbstractShadowRenderer.java | 91 +++++++++---------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 50db5a5a64..4db661c28a 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2024 jMonkeyEngine + * Copyright (c) 2009-2025 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -74,9 +74,9 @@ * abstract shadow renderer that holds commons feature to have for a shadow * renderer * - * @author Rémy Bouquet aka Nehon + * @author Nehon */ -public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, JmeCloneable, Cloneable { +public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, JmeCloneable { protected static final Logger logger = Logger.getLogger(AbstractShadowRenderer.class.getName()); private static final LightFilter NULL_LIGHT_FILTER = new NullLightFilter(); @@ -100,6 +100,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, protected RenderState forcedRenderState = new RenderState(); protected boolean renderBackFacesShadows = true; protected AppProfiler prof; + protected boolean debugfrustums = false; /** * true if the fallback material should be used, otherwise false @@ -130,24 +131,23 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, protected boolean skipPostPass; /** - * used for serialization + * For serialization only. Do not use. */ protected AbstractShadowRenderer() { } /** - * Create an abstract shadow renderer. Subclasses invoke this constructor. + * Creates an AbstractShadowRenderer. Subclasses invoke this constructor. * - * @param assetManager the application asset manager - * @param shadowMapSize the size of the rendered shadow maps (512,1024,2048, - * etc...) - * @param nbShadowMaps the number of shadow maps rendered (the more shadow - * maps the more quality, the fewer fps). + * @param assetManager The application's asset manager. + * @param shadowMapSize The size of the rendered shadow maps (e.g., 512, 1024, 2048). + * @param nbShadowMaps The number of shadow maps to render (1 to 4). More maps + * improve quality but can reduce performance. */ protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) { this.assetManager = assetManager; - this.nbShadowMaps = nbShadowMaps; this.shadowMapSize = shadowMapSize; + this.nbShadowMaps = nbShadowMaps; init(assetManager, nbShadowMaps, shadowMapSize); } @@ -301,32 +301,33 @@ public CompareMode getShadowCompareMode() { */ protected Geometry createFrustum(Vector3f[] pts, int i) { WireFrustum frustum = new WireFrustum(pts); - Geometry frustumMdl = new Geometry("f", frustum); - frustumMdl.setCullHint(Spatial.CullHint.Never); - frustumMdl.setShadowMode(ShadowMode.Off); + Geometry geo = new Geometry("WireFrustum" + i, frustum); Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); mat.getAdditionalRenderState().setWireframe(true); - frustumMdl.setMaterial(mat); + geo.setMaterial(mat); + geo.setCullHint(Spatial.CullHint.Never); + geo.setShadowMode(ShadowMode.Off); + switch (i) { case 0: - frustumMdl.getMaterial().setColor("Color", ColorRGBA.Pink); + mat.setColor("Color", ColorRGBA.Pink); break; case 1: - frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red); + mat.setColor("Color", ColorRGBA.Red); break; case 2: - frustumMdl.getMaterial().setColor("Color", ColorRGBA.Green); + mat.setColor("Color", ColorRGBA.Green); break; case 3: - frustumMdl.getMaterial().setColor("Color", ColorRGBA.Blue); + mat.setColor("Color", ColorRGBA.Blue); break; default: - frustumMdl.getMaterial().setColor("Color", ColorRGBA.White); + mat.setColor("Color", ColorRGBA.White); break; } - frustumMdl.updateGeometricState(); - return frustumMdl; + geo.updateGeometricState(); + return geo; } /** @@ -340,7 +341,7 @@ public void initialize(RenderManager rm, ViewPort vp) { renderManager = rm; viewPort = vp; postTechniqueName = "PostShadow"; - if(zFarOverride>0 && frustumCam == null){ + if (zFarOverride > 0 && frustumCam == null) { initFrustumCam(); } } @@ -396,7 +397,6 @@ public boolean isInitialized() { protected void doDisplayFrustumDebug(int shadowMapIndex) { } - @SuppressWarnings("fallthrough") @Override public void postQueue(RenderQueue rq) { lightReceivers.clear(); @@ -413,13 +413,11 @@ public void postQueue(RenderQueue rq) { renderManager.setForcedTechnique("PreShadow"); for (int shadowMapIndex = 0; shadowMapIndex < nbShadowMaps; shadowMapIndex++) { - - if (debugfrustums) { - doDisplayFrustumDebug(shadowMapIndex); - } - renderShadowMap(shadowMapIndex); - + if (debugfrustums) { + doDisplayFrustumDebug(shadowMapIndex); } + renderShadowMap(shadowMapIndex); + } debugfrustums = false; @@ -450,8 +448,6 @@ protected void renderShadowMap(int shadowMapIndex) { renderManager.setForcedRenderState(null); } - boolean debugfrustums = false; - public void displayFrustum() { debugfrustums = true; } @@ -536,11 +532,11 @@ private void clearMatParams(){ //renderers //Note that j start at 1 because other shadow renderers will have //at least 1 shadow map and will set it on each frame anyway. - for (int j = 1; j < nbShadowMaps; j++) { - mat.clearParam(lightViewStringCache[j]); + for (int i = 1; i < nbShadowMaps; i++) { + mat.clearParam(lightViewStringCache[i]); } - for (int j = 1; j < nbShadowMaps; j++) { - mat.clearParam(shadowMapStringCache[j]); + for (int i = 1; i < nbShadowMaps; i++) { + mat.clearParam(shadowMapStringCache[i]); } mat.clearParam("FadeInfo"); clearMaterialParameters(mat); @@ -556,22 +552,20 @@ private void clearMatParams(){ */ protected abstract void setMaterialParameters(Material material); - private void setMatParams(GeometryList l) { + private void setMatParams(GeometryList list) { //iterate through all the geometries of the list to gather the materials - buildMatCache(l); + buildMatCache(list); //iterating through the mat cache and setting the parameters for (Material mat : matCache) { - mat.setFloat("ShadowMapSize", shadowMapSize); - for (int j = 0; j < nbShadowMaps; j++) { - mat.setMatrix4(lightViewStringCache[j], lightViewProjectionsMatrices[j]); + for (int i = 0; i < nbShadowMaps; i++) { + mat.setMatrix4(lightViewStringCache[i], lightViewProjectionsMatrices[i]); } - - for (int j = 0; j < nbShadowMaps; j++) { - mat.setTexture(shadowMapStringCache[j], shadowMaps[j]); + for (int i = 0; i < nbShadowMaps; i++) { + mat.setTexture(shadowMapStringCache[i], shadowMaps[i]); } mat.setBoolean("HardwareShadows", shadowCompareMode == CompareMode.Hardware); @@ -581,7 +575,7 @@ private void setMatParams(GeometryList l) { mat.setBoolean("BackfaceShadows", renderBackFacesShadows); if (fadeInfo != null) { - mat.setVector2("FadeInfo", fadeInfo); + mat.setVector2("FadeInfo", fadeInfo); } setMaterialParameters(mat); @@ -592,13 +586,12 @@ private void setMatParams(GeometryList l) { if (needsfallBackMaterial) { setPostShadowParams(); } - } - private void buildMatCache(GeometryList l) { + private void buildMatCache(GeometryList list) { matCache.clear(); - for (int i = 0; i < l.size(); i++) { - Material mat = l.get(i).getMaterial(); + for (int i = 0; i < list.size(); i++) { + Material mat = list.get(i).getMaterial(); //checking if the material has the post technique and adding it to the material cache if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) { if (!matCache.contains(mat)) { From 15129128a7d4f15b0147ecf30b298c3b31e8d699 Mon Sep 17 00:00:00 2001 From: Wyatt Gillette Date: Wed, 25 Jun 2025 18:06:32 +0200 Subject: [PATCH 2/2] AbstractShadowRenderer: add javadoc --- .../jme3/shadow/AbstractShadowRenderer.java | 294 +++++++++++------- 1 file changed, 188 insertions(+), 106 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 4db661c28a..6d4b6ad470 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -32,7 +32,11 @@ package com.jme3.shadow; import com.jme3.asset.AssetManager; -import com.jme3.export.*; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.export.Savable; import com.jme3.light.LightFilter; import com.jme3.light.NullLightFilter; import com.jme3.material.Material; @@ -55,12 +59,12 @@ import com.jme3.scene.Spatial; import com.jme3.scene.debug.WireFrustum; import com.jme3.texture.FrameBuffer; +import com.jme3.texture.FrameBuffer.FrameBufferTarget; import com.jme3.texture.Image.Format; import com.jme3.texture.Texture.MagFilter; import com.jme3.texture.Texture.MinFilter; import com.jme3.texture.Texture.ShadowCompareMode; import com.jme3.texture.Texture2D; -import com.jme3.texture.FrameBuffer.FrameBufferTarget; import com.jme3.ui.Picture; import com.jme3.util.clone.Cloner; import com.jme3.util.clone.JmeCloneable; @@ -71,8 +75,7 @@ import java.util.logging.Logger; /** - * abstract shadow renderer that holds commons feature to have for a shadow - * renderer + * An abstract shadow renderer that provides common features for shadow rendering. * * @author Nehon */ @@ -80,54 +83,73 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, protected static final Logger logger = Logger.getLogger(AbstractShadowRenderer.class.getName()); private static final LightFilter NULL_LIGHT_FILTER = new NullLightFilter(); + + // The number of shadow maps to render. protected int nbShadowMaps = 1; + // The resolution (width and height) of each shadow map. protected float shadowMapSize; + // The intensity of the shadows, ranging from 0.0 (fully transparent) to 1.0 (fully opaque). protected float shadowIntensity = 0.7f; + // The RenderManager instance used for rendering operations. protected RenderManager renderManager; + // The ViewPort associated with this shadow renderer. protected ViewPort viewPort; + // Array of frame buffers used for rendering shadow maps. protected FrameBuffer[] shadowFB; + // Array of 2D textures representing the generated shadow maps. protected Texture2D[] shadowMaps; + // A dummy texture used to prevent read-buffer crashes on certain platforms (e.g., OSX). protected Texture2D dummyTex; + // Material used for the pre-shadow pass (rendering occluders into the shadow map). protected Material preshadowMat; + // Material used for the post-shadow pass (applying shadows to the scene). protected Material postshadowMat; + // Array of light view projection matrices for each shadow map. protected Matrix4f[] lightViewProjectionsMatrices; + // The AssetManager instance used to load assets. protected AssetManager assetManager; + // Flag indicating whether debug visualizations (e.g., shadow maps) should be displayed. protected boolean debug = false; + // The thickness of shadow edges, influencing PCF (Percentage-Closer Filtering). Value is in tenths of a pixel. protected float edgesThickness = 1.0f; + // The filtering mode applied to shadow edges. protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear; + // The shadow comparison mode (hardware or software). protected CompareMode shadowCompareMode = CompareMode.Hardware; + // Array of Picture objects used for debugging to display shadow maps. protected Picture[] dispPic; + // Forced RenderState used during the pre-shadow pass to render occluders. protected RenderState forcedRenderState = new RenderState(); + // Flag indicating whether back faces should cast shadows. protected boolean renderBackFacesShadows = true; + // The application profiler for performance monitoring. protected AppProfiler prof; + // Flag indicating whether shadow frustums should be displayed for debugging. protected boolean debugfrustums = false; - - /** - * true if the fallback material should be used, otherwise false - */ + // True if a fallback material should be used for post-shadow rendering, otherwise false. + // This occurs if some scene materials do not support the post-shadow technique. protected boolean needsfallBackMaterial = false; - /** - * name of the post material technique - */ + // The name of the technique to use for the post-shadow material. protected String postTechniqueName = "PostShadow"; - /** - * list of materials for post shadow queue geometries - */ + // A cache of materials found on geometries in the post-shadow queue. protected List matCache = new ArrayList<>(); + // List of geometries that receive shadows. protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator()); + // List of geometries that cast shadows (occluders). protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator()); + // Internal cache for shadow map uniform names (e.g., "ShadowMap0", "ShadowMap1"). private String[] shadowMapStringCache; + // nternal cache for light view projection matrix uniform names (e.g., "LightViewProjectionMatrix0"). private String[] lightViewStringCache; - /** - * fade shadows at distance - */ + // The distance at which shadows start to fade out. A value of 0 means no override. protected float zFarOverride = 0; + // Vector containing information about shadow fading (start distance, inverse fade length). protected Vector2f fadeInfo; + // The length over which shadows fade out. protected float fadeLength; + // A camera used to define the frustum for shadow rendering, especially when `zFarOverride` is used. protected Camera frustumCam; - /** - * true to skip the post pass when there are no shadow casters - */ + // True to skip the post pass when there are no shadow casters. protected boolean skipPostPass; /** @@ -200,9 +222,10 @@ protected void initForcedRenderState() { } /** - * set the post shadow material for this renderer + * Sets the post-shadow material for this renderer. This material is used to apply + * the shadows to the main scene. * - * @param postShadowMat the desired Material (alias created) + * @param postShadowMat The desired Material instance to use (alias created). */ protected final void setPostShadowMaterial(Material postShadowMat) { this.postshadowMat = postShadowMat; @@ -216,10 +239,11 @@ protected final void setPostShadowMaterial(Material postShadowMat) { } /** - * Sets the filtering mode for shadow edges. See {@link EdgeFilteringMode} - * for more info. + * Sets the filtering mode for shadow edges. This affects the smoothness of + * shadow boundaries. * - * @param filterMode the desired filtering mode (not null) + * @param filterMode The desired filtering mode (cannot be null). See {@link EdgeFilteringMode} + * for available options. */ final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) { if (filterMode == null) { @@ -243,19 +267,21 @@ final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) { } /** - * returns the edge filtering mode + * Returns the currently edge filtering mode for shadows. * + * @return The current {@link EdgeFilteringMode} enum value. * @see EdgeFilteringMode - * @return the enum value */ public EdgeFilteringMode getEdgeFilteringMode() { return edgeFilteringMode; } /** - * Sets the shadow compare mode. See {@link CompareMode} for more info. + * Sets the shadow comparison mode. This determines how shadow map values are + * compared to generate shadows. * - * @param compareMode the desired compare mode (not null) + * @param compareMode The desired compare mode (cannot be null). See {@link CompareMode} + * for available options. */ final public void setShadowCompareMode(CompareMode compareMode) { if (compareMode == null) { @@ -283,21 +309,22 @@ final public void setShadowCompareMode(CompareMode compareMode) { } /** - * returns the shadow compare mode + * Returns the currently shadow comparison mode. * + * @return The current {@link CompareMode} enum value. * @see CompareMode - * @return the shadowCompareMode */ public CompareMode getShadowCompareMode() { return shadowCompareMode; } /** - * debug function to create a visible frustum + * Debug function to create a visible wireframe frustum. This is useful for + * visualizing the shadow camera's view. * - * @param pts optional storage for vertex positions (may be null) - * @param i the index of the desired wire color (default=White) - * @return a new Geometry + * @param pts Optional storage for vertex positions. If null, a new array will be created. + * @param i The index, used to assign a color to the frustum for differentiation (e.g., for multiple shadow maps). + * @return A new {@link Geometry} representing the wireframe frustum. */ protected Geometry createFrustum(Vector3f[] pts, int i) { WireFrustum frustum = new WireFrustum(pts); @@ -347,7 +374,8 @@ public void initialize(RenderManager rm, ViewPort vp) { } /** - * delegates the initialization of the frustum cam to child renderers + * Delegates the initialization of the frustum camera to child renderers. + * This camera defines the view for calculating shadow frustums. */ protected abstract void initFrustumCam(); @@ -362,39 +390,41 @@ public boolean isInitialized() { } /** - * Invoked once per frame to update the shadow cams according to the light - * view. + * Invoked once per frame to update the shadow cameras according to the light view. + * Subclasses must implement this method to define how shadow cameras are positioned + * and oriented. * - * @param viewCam the scene cam + * @param viewCam The main scene camera. */ protected abstract void updateShadowCams(Camera viewCam); /** - * Returns a subclass-specific geometryList containing the occluders to be - * rendered in the shadow map + * Returns a subclass-specific {@link GeometryList} containing the occluders + * that should be rendered into the shadow map. * - * @param shadowMapIndex the index of the shadow map being rendered - * @param shadowMapOccluders the list of occluders - * @return the geometryList + * @param shadowMapIndex The index of the shadow map being rendered. + * @param shadowMapOccluders An existing {@link GeometryList} that can be reused or populated. + * @return A {@link GeometryList} containing the geometries that cast shadows for the given map. */ protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders); /** - * return the shadow camera to use for rendering the shadow map according - * the given index + * Returns the shadow camera to use for rendering the shadow map according to the given index. + * Subclasses must implement this to provide the correct camera for each shadow map. * - * @param shadowMapIndex the index of the shadow map being rendered - * @return the shadowCam + * @param shadowMapIndex The index of the shadow map being rendered. + * @return The {@link Camera} instance representing the shadow's viewpoint. */ protected abstract Camera getShadowCam(int shadowMapIndex); /** - * responsible for displaying the frustum of the shadow cam for debug - * purpose + * Responsible for displaying the frustum of the shadow camera for debugging purposes. + * Subclasses can override this method to provide specific debug visualizations. * - * @param shadowMapIndex the index of the shadow map + * @param shadowMapIndex The index of the shadow map for which to display the frustum. */ protected void doDisplayFrustumDebug(int shadowMapIndex) { + // Default implementation does nothing. } @Override @@ -440,7 +470,7 @@ protected void renderShadowMap(int shadowMapIndex) { renderManager.getRenderer().clearBuffers(true, true, true); renderManager.setForcedRenderState(forcedRenderState); - // render shadow casters to shadow map and disables the lightfilter + // render shadow casters to shadow map and disables the light filter LightFilter tmpLightFilter = renderManager.getLightFilter(); renderManager.setLightFilter(NULL_LIGHT_FILTER); viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true); @@ -448,14 +478,18 @@ protected void renderShadowMap(int shadowMapIndex) { renderManager.setForcedRenderState(null); } + /** + * Enables debugging of shadow frustums, making them visible in the scene. + * Call this before {@link #postQueue(RenderQueue)} to see the frustums. + */ public void displayFrustum() { debugfrustums = true; } /** - * For debugging purposes, display depth shadow maps. + * For debugging purposes, displays the depth shadow maps on screen as Picture quads. * - * @param r ignored + * @param r The current {@link Renderer} (ignored). */ protected void displayShadowMap(Renderer r) { Camera cam = viewPort.getCamera(); @@ -472,12 +506,19 @@ protected void displayShadowMap(Renderer r) { } /** - * For debugging purposes, "snapshot" the current frustum to the scene. + * For debugging purposes, "snapshots" the current state of the shadow maps + * and displays them on screen. */ public void displayDebug() { debug = true; } + /** + * Populates the provided {@link GeometryList} with geometries that are considered + * shadow receivers. Subclasses must implement this method. + * + * @param lightReceivers The {@link GeometryList} to populate with shadow-receiving geometries. + */ protected abstract void getReceivers(GeometryList lightReceivers); @Override @@ -519,13 +560,19 @@ public void postFrame(FrameBuffer out) { /** * This method is called once per frame and is responsible for clearing any - * material parameters that subclasses may need to clear on the post material. + * material parameters that subclasses may have set on the post-shadow material. + * This ensures that parameters from previous frames or other renderers do not + * interfere. * - * @param material the material that was used for the post shadow pass + * @param material The material that was used for the post-shadow pass. */ protected abstract void clearMaterialParameters(Material material); - private void clearMatParams(){ + /** + * Clears common material parameters set by this renderer on materials in the cache. + * This is done to avoid interference with other shadow renderers or subsequent frames. + */ + private void clearMatParams() { for (Material mat : matCache) { //clearing only necessary params, the others may be set by other @@ -552,6 +599,12 @@ private void clearMatParams(){ */ protected abstract void setMaterialParameters(Material material); + /** + * Iterates through the given {@link GeometryList} to gather unique materials + * and sets common shadow-related parameters on them. + * + * @param list The {@link GeometryList} containing geometries whose materials need parameters set. + */ private void setMatParams(GeometryList list) { //iterate through all the geometries of the list to gather the materials @@ -588,6 +641,13 @@ private void setMatParams(GeometryList list) { } } + /** + * Builds a cache of unique materials from the provided {@link GeometryList} + * that support the post-shadow technique. If any material does not support + * it, the `needsfallBackMaterial` flag is set. + * + * @param list The {@link GeometryList} to extract materials from. + */ private void buildMatCache(GeometryList list) { matCache.clear(); for (int i = 0; i < list.size(); i++) { @@ -604,7 +664,8 @@ private void buildMatCache(GeometryList list) { } /** - * for internal use only + * For internal use only. Sets the common shadow parameters on the internal + * post-shadow material. This is used when a fallback material is needed. */ protected void setPostShadowParams() { setMaterialParameters(postshadowMat); @@ -619,43 +680,45 @@ protected void setPostShadowParams() { } /** - * How far the shadows are rendered in the view + * Returns the maximum distance from the eye where shadows are rendered. + * A value of 0 indicates that the distance is dynamically computed based on scene bounds. * + * @return The shadow Z-extend distance in world units. * @see #setShadowZExtend(float zFar) - * @return shadowZExtend */ public float getShadowZExtend() { return zFarOverride; } /** - * Set the distance from the eye where the shadows will be rendered default - * value is dynamically computed to the shadow casters/receivers union bound - * zFar, capped to view frustum far value. + * Sets the distance from the camera where shadows will be rendered. + * By default (0), this value is dynamically computed based on the union bound + * of shadow casters and receivers, capped by the view frustum's far value. + * Setting a positive value overrides this dynamic computation. * - * @param zFar the zFar values that override the computed one + * @param zFar The zFar value that overrides the computed one. Set to 0 to use dynamic computation. */ public void setShadowZExtend(float zFar) { this.zFarOverride = zFar; - if(zFarOverride == 0){ + if (zFarOverride == 0) { fadeInfo = null; frustumCam = null; - }else{ + } else { if (fadeInfo != null) { fadeInfo.set(zFarOverride - fadeLength, 1f / fadeLength); } - if(frustumCam == null && viewPort != null){ + if (frustumCam == null && viewPort != null) { initFrustumCam(); } } } /** - * Define the length over which the shadow will fade out when using a - * shadowZextend This is useful to make dynamic shadows fade into baked - * shadows in the distance. + * Defines the length over which the shadow will fade out when using a + * custom `shadowZextend`. This is useful for smoothly transitioning + * dynamic shadows into baked shadows or for preventing abrupt shadow cut-offs. * - * @param length the fade length in world units + * @param length The fade length in world units. Set to 0 to disable fading. */ public void setShadowZFadeLength(float length) { if (length == 0) { @@ -674,10 +737,10 @@ public void setShadowZFadeLength(float length) { } /** - * get the length over which the shadow will fade out when using a - * shadowZextend + * Returns the length over which the shadow will fade out when using a + * custom `shadowZextend`. * - * @return the fade length in world units + * @return The fade length in world units. Returns 0 if no fading is applied. */ public float getShadowZFadeLength() { if (fadeInfo != null) { @@ -687,39 +750,45 @@ public float getShadowZFadeLength() { } /** - * @param viewCam a Camera to define the view frustum - * @return true if the light source bounding box is in the view frustum + * Abstract method to check if the light source's bounding box is within the view frustum + * of the given camera. This is used for culling to avoid unnecessary shadow computations. + * + * @param viewCam A {@link Camera} to define the view frustum against which to check. + * @return True if the light source's bounding box is in the view frustum, otherwise false. */ protected abstract boolean checkCulling(Camera viewCam); @Override public void preFrame(float tpf) { + // no-op } @Override public void cleanup() { + // no-op } @Override public void reshape(ViewPort vp, int w, int h) { + // no-op } /** - * Returns the shadow intensity. + * Returns the current shadow intensity. * + * @return The shadow intensity value, ranging from 0.0 to 1.0. * @see #setShadowIntensity(float shadowIntensity) - * @return shadowIntensity */ public float getShadowIntensity() { return shadowIntensity; } /** - * Set the shadowIntensity. The value should be between 0 and 1. A 0 value - * gives a bright and invisible shadow, a 1 value gives a pitch black - * shadow. The default is 0.7 + * Sets the shadow intensity. This value controls the darkness of the shadows. + * A value of 0.0 results in bright, almost invisible shadows, while 1.0 creates + * pitch-black shadows. The default value is 0.7. * - * @param shadowIntensity the darkness of the shadow + * @param shadowIntensity The desired darkness of the shadow, a float between 0.0 and 1.0. */ final public void setShadowIntensity(float shadowIntensity) { this.shadowIntensity = shadowIntensity; @@ -727,38 +796,41 @@ final public void setShadowIntensity(float shadowIntensity) { } /** - * returns the edges thickness + * Returns the configured shadow edges thickness. The value is returned + * as an integer representing tenths of a pixel (e.g., 10 for 1.0 pixel). * + * @return The edges thickness in tenths of a pixel. * @see #setEdgesThickness(int edgesThickness) - * @return edgesThickness */ public int getEdgesThickness() { return (int) (edgesThickness * 10); } /** - * Read the number of shadow maps rendered by this renderer. + * Returns the number of shadow maps currently rendered by this processor. * - * @return count + * @return The count of shadow maps. */ public int getNumShadowMaps() { return nbShadowMaps; } /** - * Read the size of each shadow map rendered by this renderer. + * Returns the size (width and height) of each shadow map rendered by this processor. * - * @return a map's height (which is also its width, in pixels) + * @return The resolution of a single shadow map in pixels. */ public int getShadowMapSize() { return (int) shadowMapSize; } /** - * Sets the shadow edges thickness. Default is 10. Setting it to lower values - * can help reduce the jagged effect of shadow edges. + * Sets the shadow edges thickness. This parameter influences the + * smoothness of shadow edges, particularly with PCF (Percentage-Closer Filtering). + * Setting lower values can help reduce jagged artifacts. * - * @param edgesThickness the desired thickness (in tenths of a pixel, default=10) + * @param edgesThickness The desired thickness in tenths of a pixel (e.g., 10 for 1.0 pixel). + * The value is clamped between 1 and 10. Default is 10. */ public void setEdgesThickness(int edgesThickness) { this.edgesThickness = Math.max(1, Math.min(edgesThickness, 10)); @@ -772,29 +844,39 @@ public void setEdgesThickness(int edgesThickness) { * @return false */ @Deprecated - public boolean isFlushQueues() { return false; } + public boolean isFlushQueues() { + return false; + } /** - * returns the pre shadows pass render state. - * use it to adjust the RenderState parameters of the pre shadow pass. - * Note that this will be overridden if the preShadow technique in the material has a ForcedRenderState - * @return the pre shadow render state. + * Returns the {@link RenderState} that is forced during the pre-shadow pass. + * You can use this to adjust the rendering parameters for geometries that cast shadows. + * Note that this will be overridden if the "PreShadow" technique in the material definition + * has its own `ForcedRenderState`. + * + * @return The {@link RenderState} applied to the pre-shadow pass. */ public RenderState getPreShadowForcedRenderState() { return forcedRenderState; } /** - * Set to true if you want back faces shadows on geometries. - * Note that back faces shadows will be blended over dark lighten areas and may produce overly dark lighting. + * Sets whether back faces of geometries should cast shadows. + * When enabled, shadows cast by the back side of an object can appear. + * Be aware that back face shadows can sometimes lead to overly dark lighting + * when blended with existing dark areas. * - * Also note that setting this parameter will override this parameter for ALL materials in the scene. - * You can alternatively change this parameter on a single material using {@link Material#setBoolean(String, boolean)} + *

Setting this parameter will globally override this setting for ALL materials + * in the scene for the shadow pass. Alternatively, you can control this on + * individual materials using {@link Material#setBoolean(String, boolean)} + * with the "BackfaceShadows" parameter. * - * This also will automatically adjust the faceCullMode and the PolyOffset of the pre shadow pass. - * You can modify them by using {@link #getPreShadowForcedRenderState()} + *

This method also automatically adjusts the {@link RenderState.FaceCullMode} + * and {@link RenderState#setPolyOffset(float, float)} of the pre-shadow pass + * to accommodate back face rendering. You can further modify these + * using {@link #getPreShadowForcedRenderState()}. * - * @param renderBackFacesShadows true or false. + * @param renderBackFacesShadows True to enable back face shadows, false to disable. */ public void setRenderBackFacesShadows(boolean renderBackFacesShadows) { this.renderBackFacesShadows = renderBackFacesShadows; @@ -808,9 +890,9 @@ public void setRenderBackFacesShadows(boolean renderBackFacesShadows) { } /** - * if this processor renders back faces shadows + * Checks if this shadow processor is configured to render shadows from back faces. * - * @return true if this processor renders back faces shadows + * @return True if back face shadows are enabled, false otherwise. */ public boolean isRenderBackFacesShadows() { return renderBackFacesShadows;