You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the problem or limitation you are having in your project
In Godot, all shadow splits follow the camera. This is a good approach for open world games, but it can fall short in games with closed level designs, especially when you can see far away in the distance. Shadow splits cover a limited distance from the camera's position, so you may not see any shadows when looking far away:
This tends to incentivize users to greatly increase Shadow Max Distance to cover the entire level (while also setting Fade Start to 1.0 to maximize its potential), but this comes at a quality and performance cost as all shadow splits need to be stretched out accordingly. Manual shadow split tuning can help somewhat, but this isn't something most users perform as it's relatively complicated to get right.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Add a fixed-size last shadow split option in DirectionalLight3D.
Example in Trackmania 20201, with a free camera that has a very low FOV to make it easier to notice:
tm.mp4
This is technically feasible because the level has a fixed size, with the last shadow split being at a fixed position and covering the stadium:
Therefore, no matter how far away the camera is, the last split's shadows will always be visible on the stadium. This comes at no performance or quality cost, just the shadow frustum being optimally located.
Some benefits of using a fixed frustum for the shadow split:
This reduces the incentive of setting Shadow Max Distance to a very high value to cover the entire world, which is often counterproductive from a performance and quality standpoint.
Maybe culling cost can be reduced on the last split if its position is fixed (it would only need to be updated when the property is modified). I'm not sure how much of a CPU impact this has though.
There are some downsides though:
This is most suited to closed level designs of a small or medium size, not open world games.
The last fixed split's size must be configured manually by the user (or generated using an editor tool, as described below).
The last split has to cover the entire level, including what's behind the camera. This means shadow texel density will be lower than with a dynamic split approach that may not cover the entire level. That said, since this is intended to be used for static objects, the increased pixelation artifacts won't be too noticeable. Also consider that with a fixed split, you can often decrease Shadow Max Distance to a lower value without affecting quality much.
If objects can draw shadows outside this fixed split, the last split will not contain any shadows for them. Dynamic objects should still be able to cast shadows up close though, as the first split(s) continue to follow the camera with this option enabled.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This would likely be exposed as a boolean in DirectionalLight3D to enable fixed-size last shadow split (only when shadows are enabled). When enabled, you can see another Last Split AABB property, or a Last Split Size Vector3 property centered around the DirectionalLight3D's origin. We can provide an editor helper to automatically fit its extents to the world geometry (VoxelGI could benefit from that too).
The option should work with all shadow split modes (orthogonal, PSSM 2 Splits, PSSM 4 Splits). The last split is the only split affected by the option. When using orthogonal, it'll effectively affect the entire shadow rendering. Fade Start is ignored and hidden in the inspector when the option is enabled.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No.
Is there a reason why this should be core and not an add-on in the asset library?
This is about improving built-in shadow rendering, which is a core feature.
Footnotes
Every Trackmania game since Sunrise has used this approach, so it's not exactly a new thing to do 🙂 ↩
The text was updated successfully, but these errors were encountered:
Calinou
changed the title
Add a fixed-size last shadow split option in DirectionalLight3D
Add a fixed-position, fixed-size last shadow split option in DirectionalLight3D
Aug 31, 2023
Calinou
changed the title
Add a fixed-position, fixed-size last shadow split option in DirectionalLight3D
Add a fixed-position, fixed-size last shadow split option in DirectionalLight3D to improve quality in small/medium-sized levels
Aug 31, 2023
Yes! This is a very good approach. Had the same problem recently and tried to figure out solutions for faraway background objects to still get shadowed. yes please :D
Describe the project you are working on
The Godot editor 🙂
Describe the problem or limitation you are having in your project
In Godot, all shadow splits follow the camera. This is a good approach for open world games, but it can fall short in games with closed level designs, especially when you can see far away in the distance. Shadow splits cover a limited distance from the camera's position, so you may not see any shadows when looking far away:
This tends to incentivize users to greatly increase Shadow Max Distance to cover the entire level (while also setting Fade Start to
1.0
to maximize its potential), but this comes at a quality and performance cost as all shadow splits need to be stretched out accordingly. Manual shadow split tuning can help somewhat, but this isn't something most users perform as it's relatively complicated to get right.Describe the feature / enhancement and how it helps to overcome the problem or limitation
Add a fixed-size last shadow split option in DirectionalLight3D.
Example in Trackmania 20201, with a free camera that has a very low FOV to make it easier to notice:
tm.mp4
This is technically feasible because the level has a fixed size, with the last shadow split being at a fixed position and covering the stadium:
Therefore, no matter how far away the camera is, the last split's shadows will always be visible on the stadium. This comes at no performance or quality cost, just the shadow frustum being optimally located.
Some benefits of using a fixed frustum for the shadow split:
There are some downsides though:
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This would likely be exposed as a boolean in DirectionalLight3D to enable fixed-size last shadow split (only when shadows are enabled). When enabled, you can see another Last Split AABB property, or a Last Split Size Vector3 property centered around the DirectionalLight3D's origin. We can provide an editor helper to automatically fit its extents to the world geometry (VoxelGI could benefit from that too).
The option should work with all shadow split modes (orthogonal, PSSM 2 Splits, PSSM 4 Splits). The last split is the only split affected by the option. When using orthogonal, it'll effectively affect the entire shadow rendering. Fade Start is ignored and hidden in the inspector when the option is enabled.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No.
Is there a reason why this should be core and not an add-on in the asset library?
This is about improving built-in shadow rendering, which is a core feature.
Footnotes
Every Trackmania game since Sunrise has used this approach, so it's not exactly a new thing to do 🙂 ↩
The text was updated successfully, but these errors were encountered: