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

Object with "Distance Fade" enabled does not cast shadows. #97537

Open
RonYanDaik opened this issue Sep 27, 2024 · 3 comments
Open

Object with "Distance Fade" enabled does not cast shadows. #97537

RonYanDaik opened this issue Sep 27, 2024 · 3 comments

Comments

@RonYanDaik
Copy link

RonYanDaik commented Sep 27, 2024

Tested versions

  • 4.3

System information

Win 10

Issue description

The wall has Distance Fade enabled. It stops to casting shadows.
image

#69329 (comment)

To resolve this, use the Pixel Dither or Object Dither transparency mode for Distance Fade.

Pixel Dither does not resolve this.

Also if this is intended then the tooltip should say that the object will stop casting shadows.
image

But object still do cast shadows from direct light:
image

Which makes me think that light camera is affected by same shader and are just to close to object. Which means light camera pass should use different settings/different shader.

Changing distance to very small number solves the shadows but looses its usability meaning ofc:
image

Another detail:
This is GridMap. Which means that material was assigned to mesh material slot and not to OverrideMaterial Slot of MeshInstance (because GridMap has no Override Material slot, but it should!)
image

Steps to reproduce

Enable Distance Fade on material and put light close to object.

Minimal reproduction project (MRP)

N/A

@RonYanDaik
Copy link
Author

Probably could be solved by this:
godotengine/godot-proposals#4443

@clayjohn
Copy link
Member

I think you are on the right track and the problem is that the shader considers the distance to the light instead of the distance to the camera.

See here:

float fade_distance = length((VIEW_MATRIX * MODEL_MATRIX[3]));

here:
float fade_distance = length(VERTEX);

and here:
ALPHA *= clamp(smoothstep(distance_fade_min, distance_fade_max, length(VERTEX)), 0.0, 1.0);

We solved a similar problem with billboards in #72638. A similar solution should be applied here

@RonYanDaik
Copy link
Author

RonYanDaik commented Sep 27, 2024

I've solved it with this custom shader for now. But works only for DualParaboloid shadow mapping.

bool is_shadow_pass = (PROJECTION_MATRIX[2][3] == 0.0);
if(!is_shadow_pass)
	{
		
		// Distance Fade: Pixel Dither
		float fade_distance = length(VERTEX);

		// Use interleaved gradient noise, which is fast but still looks good.
		const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);
		
		float dfmn = distance_fade_min;
		float dfmx = distance_fade_max;
		if(is_shadow_pass){
			 dfmn= 0.0;
			 dfmx= 0.1;
		}
			
		float fade = clamp(smoothstep(dfmn, dfmx, fade_distance), 0.0, 1.0);
		// Use a hard cap to prevent a few stray pixels from remaining when past the fade-out distance.
		if (fade < 0.001 || fade < fract(magic.z * fract(dot(FRAGCOORD.xy, magic.xy)))) {
			discard;
		}
	}

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