godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.64k stars 20.1k forks source link

Visibility range mixes origin and AABB #79471

Open Norodix opened 1 year ago

Norodix commented 1 year ago

Godot version

v4.1.stable.official [970459615]

System information

Godot v4.1.stable - Pop!_OS 22.04 LTS - Vulkan (Forward+) - dedicated AMD Radeon RX 580 Series (RADV POLARIS10) () - AMD Ryzen 5 5600G with Radeon Graphics (12 Threads)

Issue description

When using a multimeshinstance3d with visibility range it seems that the visibility and fading are calculated differently. Visibility is calculated from the camera's distance to the origin, while fading is calculated based on the distance from the AABB. I assume this because the fading depends on the viewing direction.

I assume it happens too when the mesh in a meshinstance is not centered at the origin, but I have not tested this yet.

Steps to reproduce

Create a MeshInstance3D Add a plane to it Offset the MeshInstance3D eg +1m in the x direction Create a MeshInstance3D as target mesh. Add arbitrary mesh, eg small capsule Create a MultiMeshInstance3D Populate it with the small capsule on the plane surface. Set 10m as visibility_range_end set 5m as visibility_range_end_margin set self fade mode

Observe as you pan around the center the mmi sometimes fades nicely and sometimes pops out of existence.

https://github.com/godotengine/godot/assets/36245389/51859cb4-e2ef-45de-b1c3-18767365ac5b

Minimal reproduction project

mmiproblem.zip

Norodix commented 1 year ago

Some additional observations. If fade mode is set to disabled, all is correct. Panning around the aabb center does not change the visibility of the mesh. If fade mode is set to self, the problem occurs even with 0 margin (so basically no fading). If fade mode is set to self with some noticeable margin, the fading is also calculated using the origin instead of the aabb center.

JFonS commented 1 year ago

This is where the visibility distance is computed:

https://github.com/godotengine/godot/blob/a7583881af5477cd73110cc859fecf7ceaf39bd7/servers/rendering/renderer_scene_cull.cpp#L2642

I haven't touched the rendering cull code in a while, but there should be a way to get the AABB center instead of the transform origin here.

Norodix commented 1 year ago

I tried to look around the code a bit. I have not managed to track down the issue but I think it should be somewhere else. I say this because the same code is applied when fading is disabled (at leas this part of the function) and that case works without any issues.

JFonS commented 1 year ago

Actually, the position is cached here:

https://github.com/godotengine/godot/blob/a7583881af5477cd73110cc859fecf7ceaf39bd7/servers/rendering/renderer_scene_cull.cpp#L1384

And it should already be the AABB center, so more investigation is needed.

Norodix commented 1 year ago

I tested it with a mesh that is offset from the origin. As expected, the same thing happens as with the multimesh example above.

image

Koalamana9 commented 11 months ago

This issue is still a thing... And by the way, @JFonS is it possible to make the whole node turn off it's visibility and have same effect on all it's children with visibility range? This would allow the creation of more complex groups of lods

UPD: Oh, it turns out there is visibility parent parameter in Node3D that works exactly like that. Please update manual: https://docs.godotengine.org/en/stable/tutorials/3d/visibility_ranges.html there is no mention of visibility parent parameter and its use with visibility range!