Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moveable DirectionalLights #5789

Closed
hankjordan opened this issue Aug 24, 2022 · 3 comments
Closed

Moveable DirectionalLights #5789

hankjordan opened this issue Aug 24, 2022 · 3 comments
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible

Comments

@hankjordan
Copy link
Contributor

What problem does this solve or what need does it fill?

DirectionalLight shadow casting is tied to the world origin.
If you move a camera too far away from the origin, shadows disappear.

What solution would you like?

Allow the Transform component of any entity with a DirectionalLight to apply to its shadow casting.
Then, users could update the transform as the camera moves around the world.

What alternative(s) have you considered?

You might be able to update the frustrum of the DirectionalLight manually, but I was unable to get this to work.

@hankjordan hankjordan added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Aug 24, 2022
@rparrett
Copy link
Contributor

An alternative solution is proposed in #3629

@superdump
Copy link
Contributor

superdump commented Aug 25, 2022

I implemented updating the projection based on the camera position here: superdump@688b265 it basically ensures the view frustum is covered but quality is poor because there’s too little shadow map resolution close to the camera and too much far away. So I wanted to instead get cascaded shadow maps working.

@superdump superdump added A-Rendering Drawing game state to the screen and removed S-Needs-Triage This issue needs to be labelled labels Aug 25, 2022
@ramirezmike
Copy link
Contributor

You might be able to update the frustrum of the DirectionalLight manually, but I was unable to get this to work.

In case anyone wanted to try this approach, I experimented with this a bit. The DirectionalLight transform's translation seems to have no effect, but the rotation does. Once you have your rotation set for the angle of shadows, you just need to update the "box" in DirectionalLight's shadow_projection to cover where you're looking.

This might be tricky depending on what you're trying to do, but in my game I have a car heading in the positive x-axis direction, so I added a system that updates the directional light so that its shadow_projection.left is the car's X coordinate + 100.0 and the shadow_projection.right is the car's X coordinate - 100.0.

Here's a picture of it at the origin and then after driving to 2,544 X

shadow

@bors bors bot closed this as completed in 1bd3d85 Nov 4, 2022
ItsDoot pushed a commit to ItsDoot/bevy that referenced this issue Feb 1, 2023
… shadow map volume (not just direction) (bevyengine#6384)

# Objective

This PR fixes bevyengine#5789, by enabling movable (and scalable) directional light shadow volumes.

## Solution

This PR changes `ExtractedDirectionalLight` to hold a copy of the `DirectionalLight` entity's `GlobalTransform`, instead of just a `direction` vector. This allows the shadow map volume (as defined by the light's `shadow_projection` field) to be transformed honoring translation _and_ scale transforms, and not just rotation.

It also augments the texel size calculation (used to determine the `shadow_normal_bias`) so that it now takes into account the upper bound of the x/y/z scale of the `GlobalTransform`.

This change makes the directional light extraction code more consistent with point and spot lights (that already use `transform`), and allows easily moving and scaling the shadow volume along with a player entity based on camera distance/angle, immediately enabling more real world use cases until we have a more sophisticated adaptive implementation, such as the one described in bevyengine#3629.

**Note:** While it was previously possible to update the projection achieving a similar effect, depending on the light direction and distance to the origin, the fact that the shadow map camera was always positioned at the origin with a hardcoded `Vec3::Y` up value meant you would get sub-optimal or inconsistent/incorrect results.

---

## Changelog

### Changed

- `DirectionalLight` shadow volumes now honor translation and scale transforms

## Migration Guide

- If your directional lights were positioned at the origin and not scaled (the default, most common scenario) no changes are needed on your part; it just works as before;
- If you previously had a system for dynamically updating directional light shadow projections, you might now be able to simplify your code by updating the directional light entity's transform instead;
- In the unlikely scenario that a scene with directional lights that previously rendered shadows correctly has missing shadows, make sure your directional lights are positioned at (0, 0, 0) and are not scaled to a size that's too large or too small.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible
Projects
None yet
4 participants