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

PCSS not working for SpotLight3D: Vulkan (Forward+) #80137

Open
kevancress opened this issue Aug 1, 2023 · 4 comments
Open

PCSS not working for SpotLight3D: Vulkan (Forward+) #80137

kevancress opened this issue Aug 1, 2023 · 4 comments

Comments

@kevancress
Copy link

Godot version

Godot v4.1.stable

System information

Godot v4.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 31.0.15.2824) - 11th Gen Intel(R) Core(TM) i5-11600K @ 3.90GHz (12 Threads)

Issue description

Percentage-closer soft shadows (PCSS) don't seem to be working correctly with SpotLight3d's.

Image below shows an Omni Light and Spot Light with the same light_size value. The Omni Light shows correct PCSS with the shadow getting softer the furth the object (caster) is from the surface (reciever). The Spot Light shows uniform shadow hardness.

image

Increasing the light_size Value for a Spot Light uniformly blurs the shadow, but the blur doesn't seem impacted by the casters distance from the receiver.

image

Steps to reproduce

  1. Create a 3D Scene
  2. Add a SpotLight3D
  3. Add a plane mesh instance, and a shadow caster mesh instance
  4. Enable shadows on the SpotLight3D
  5. Change the light_size to 0.1
  6. Observe
  7. Change SpotLight3D to OmniLight3D with the same light_size
  8. Observe

Minimal reproduction project

PCSS_Shadow_Issue.zip

@Calinou
Copy link
Member

Calinou commented Aug 2, 2023

I can confirm this on 4.2.dev 41a7f6b (Linux, GeForce RTX 4090 with NVIDIA 535.54.03).

@jsjtxietian
Copy link
Contributor

jsjtxietian commented Aug 24, 2023

I can help with this issue if no one started working on it.

Shadow atlas looks like this:

image

@Calinou
Copy link
Member

Calinou commented Aug 24, 2023

I can help with this issue if no one started working on it.

I don't think anyone has started working on this, so feel free to open a PR 🙂

@jsjtxietian
Copy link
Contributor

jsjtxietian commented Aug 25, 2023

Maybe the problem lies in the different data and shader used to render shadow between omni light and spot light.

CPU side calculation:

light_data.soft_shadow_size is calculated differently between mni light and spot light.

For omni light, the calculation is light_data.soft_shadow_size = size, very simple.

But for spot light,

float half_np = cm.get_z_near() * Math::tan(Math::deg_to_rad(spot_angle));
light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; 

the calculation essentially equals to ( size * 0.5 * rect.size.width ) / ( radius * Math::tan(Math::deg_to_rad(spot_angle) ))

In the example provided, let's say origin soft_shadow_size is 0.5 , rect.size.width is 0.25, radius is 5, and so the final result is 0.0125 ( (the value of soft_shadow_sizein this case is 0.5 in omni light).

But I'm a little confused about the formula above, and git blame doesn't tell me about why we use the formula above for spot light's light_size. I can understand why multiply by rect.size.width as we need it in uv space.

GPU side

Check light_data_inc.glsl, it says 'for spot, soft_shadow_size is the size in uv coordinates of the light, for omni it's the span angle'.

to be continued...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants