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

DirectionalLight shadow has a visible line between splits due to linear filtering (GLES3 only) #54074

Open
Calinou opened this issue Oct 21, 2021 · 4 comments

Comments

@Calinou
Copy link
Member

Calinou commented Oct 21, 2021

Godot version

3.3.4.stable, 3.4.beta (69b2f1d)

System information

Fedora 34, GeForce GTX 1080 (NVIDIA 470.74)

Issue description

DirectionalLight shadow has a visible line/seam between splits due to linear filtering.

This has been an issue as far back as Godot 3.0, but only in GLES3. In GLES2, hardware linear filtering isn't used. #46301 performs filtering in the shader, which is slower but sidesteps this issue entirely. However, we should aim to keep hardware linear filtering in GLES3 as it performs significantly better.

Changing the shadow filter mode between Disabled, PCF5 and PCF13 doesn't resolve the issue:

Disabled PCF5 PCF13
2021-10-21_16 55 32 2021-10-21_16 55 14 2021-10-21_16 55 44

Enabling Blend Splits doesn't hide the visible line either:

2021-10-21_17 04 23

Also, if you decrease the DirectionalLight's shadow Normal Bias but increase Bias Split Scale, the split line becomes even more visible. Example with PCF5 filter mode:

2021-10-21_16 56 14

However, if you modify Godot's source code to revert #8009, the black line is gone. This is the case even with the aforementioned bias tweaks:

2021-10-21_17 09 22

Maybe this can be fixed by adding some padding on each shadow map split.

See also #25303. This issue is different though – it's noticeable even on a single continuous mesh, regardless of MSAA, but only in GLES3.

Steps to reproduce

  • Add DirectionalLight node to a scene and rotate it accordingly.
  • Enable shadows for the DirectionalLight node.
  • Move the camera.

Minimal reproduction project

test_directional_shadow_split_line_3.x.zip

@lawnjelly
Copy link
Member

Maybe this can be fixed by adding some padding on each shadow map split.

Another possibility is the wrapping mode used for reading the shadow map? Maybe it is wrapping where it should be clamping, or something like that.

@Calinou
Copy link
Member Author

Calinou commented Oct 22, 2021

Another possibility is the wrapping mode used for reading the shadow map? Maybe it is wrapping where it should be clamping, or something like that.

GL_CLAMP_TO_EDGE is currently used:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

There's even a comment saying so above for cubemap shadows:

// Remove artifact on the edges of the shadowmap
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

@lawnjelly
Copy link
Member

lawnjelly commented Oct 22, 2021

Actually thinking about it if it is combining these shadow maps on an atlas the clamping is only affecting the edges of the atlas and not the in between areas, so you may have to as you say render slightly outside the intended area. So say you were aiming to fill 512 x 512 you might e.g. set the shadow matrices for rendering to 508x508 centrally, then if it reads a bit outside there is no problem.

@Calinou
Copy link
Member Author

Calinou commented Oct 22, 2021

I found a blog post that mentions an issue similar to the one we're facing here:

In fact, with my mind so cleared up I finally resolved two problems that have plagued my shadow mapping code for so long. The first problem I resolved in an hour- it had to do with the shadow maps “tearing” between the cascade splits. Those portions would either be completely dark or filled with parallel lines. In other words, a glitchy mess. Originally, I went with using different near-far distances to generate each map, but they were misaligned if viewed from certain angles. Such was the case for parallel-split maps. So I decided to just go with traditional cascaded shadow mapping by making the near distance the same for all the splits.

This means that while some pixels are wasted for the farther cascades, it guarantees that there will always be overlap between them. The tearing is now gone!

@akien-mga akien-mga modified the milestones: 3.4, 3.5 Nov 8, 2021
@KoBeWi KoBeWi modified the milestones: 3.5, 3.x Apr 23, 2024
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

4 participants