godot icon indicating copy to clipboard operation
godot copied to clipboard

Vulkan: Spotlights parented to XRControllers have a blocky look

Open coobenguy opened this issue 3 years ago • 12 comments

Godot version

4.0 Alpha 7

System information

Windows 10, gtx 1080, driver 512.59, Vulkan Clustered + Mobile. also tested on Windows 11, rtx 2070 super, driver 512.59

Issue description

while using a spotlight parented to an XRController, the light will have large(depending on the angle of the spotlight) blocky edges.

Steps to reproduce

Parent A spotlight to an XRController

Minimal reproduction project

SpotlightXR.zip

coobenguy avatar May 01 '22 05:05 coobenguy

4.0

4.0 stable isn't released yet. Which alpha are you using (or in the case of a custom build, which commit)?

Also, the minimal reproduction project is using the Vulkan Clustered backend. Can you reproduce this after switching to the Vulkan Mobile backend in the Project Settings?

Calinou avatar May 01 '22 17:05 Calinou

4.0 alpha 7. and yes it happens in both Clustered and Mobile.

coobenguy avatar May 01 '22 20:05 coobenguy

There is nothing XR does different when it comes to lights. The only thing I can think off is that seeing the light is moving, it may have to do with the spotlights shadow buffer not getting updated because its flagged as static?

BastiaanOlij avatar May 02 '22 04:05 BastiaanOlij

Im not sure. After more testing it seems that the issue is even more general than I thought before. The spotlight doesnt even need to be parented to anything for this to occur. I also dont think it has to do with a shadow buffer since it happens even with shadow turned off on the light (although I dont know the inner workings of these things so the shadow buffer could still be being used)

coobenguy avatar May 02 '22 08:05 coobenguy

@coobenguy Can you record a video of the problem occurring and link it here?

Calinou avatar May 02 '22 12:05 Calinou

https://streamable.com/9yshra

the left half of the light shows in the left eye and the right half shows in the right eye and the 2 halves overlap

coobenguy avatar May 02 '22 17:05 coobenguy

It's strange that you can reproduce this when using the Vulkan Mobile backend, as this looks a lot like a clustering artifact.

Calinou avatar May 02 '22 18:05 Calinou

https://streamable.com/9yshra

the left half of the light shows in the left eye and the right half shows in the right eye and the 2 halves overlap

I had this exact issue the other day while messing with different environment configurations in alpha 7, however my light was an OmniLight3D that was parented to the root scene.

It stopped at some point though and I haven't been able to recreate it.

TOMDM avatar May 03 '22 01:05 TOMDM

huh I was never able to do it with an omniLight but it happens no matter what I do with the spotlight

coobenguy avatar May 03 '22 06:05 coobenguy

having the same problem with not moving decals/lights. I couldn't reproduce it on mobile vulkan, but it has other bugs. Here is discord discussion: https://discord.com/channels/212250894228652034/418572953912082432/993165136107941969

python273 avatar Jul 04 '22 05:07 python273

I'm seeing this on any spotlight if XR is enabled and for most sane values of Angle Attenuation.

  • The artifact is on the left side in the right eye and right side in the left eye.
  • The visibility of the artifact is far worse if Angle Attenuation the effect is low, e.g. 0.01 or less.
  • The artifact is invisible if the Angle Attenuation is very high, e.g. 19. The super soft edges likely fade to 0 before this whatever this is blocky edge is hit.

Screenshot_Sat_Aug_13_14-54-11_2022_VR

OpenXR: Running on OpenXR runtime: SteamVR/OpenXR 0.1.0 Godot Engine v4.0.alpha14.official.106b68050 - https://godotengine.org OpenXR: XrGraphicsRequirementsVulkan2KHR:

  • minApiVersionSupported: 1.0.0
  • maxApiVersionSupported: 1.2.0 Vulkan API 1.2.0 - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce RTX 3080

And actually it is possible to see a similar effect even without XR enabled, but only if the Angle Attenuation is set to an absurdly low value, such as 0.0001: Screenshot 2022-08-13 152028

luzader avatar Aug 13 '22 21:08 luzader

I was hoping this had been indirectly fixed by https://github.com/godotengine/godot/pull/71832 (since the symptoms seemed very similar) but unfortunately, the problem in the first screenshot https://github.com/godotengine/godot/issues/60680#issuecomment-1214224333 is still present in beta 15 and beta 16.

luzader avatar Jan 28 '23 19:01 luzader

Still happening with Godot 4.0.2

https://user-images.githubusercontent.com/26260718/233758197-e44c57af-ad04-4f89-91b7-62ed34458d9c.mp4

leandrodreamer avatar Apr 22 '23 02:04 leandrodreamer

I'm also seeing this. It looks almost like the direct light from spot and omni lights is not being rendered in the area where the views for the left and right eye overlap. If the radius/angle is set low enough it actually becomes impossible to see the lights when they're being looked at straight on.

It becomes more obvious what's going on if you take a shot from the VR View window set to show both eyes than the Godot screen mirror.

image

(You can also see in this screenshot a red spotlight in the right eye that SHOULD be visible in the left, but isn't)

DKesserich avatar May 09 '23 22:05 DKesserich

So the "Forward+"/forward_clustered renderer is way above my level, but I've inferred that the "clustered" part is crudely this: To improve performance, it "plans" which lights (among other things) need to be processed for each square of the display.

To work properly, the planned spotlight footprint (in screen-space) needs to cover at-least all the squares where the scene shader is actually going to draw the light. This is all well and good in monocular mode. In XR/multiview this doesn't work right, because the clustering is unaware of multiview, so it plans the cone as though the camera were right between your eyes. This leads to the right side of the left eye and the left side of the right eye having squares where the spotlight didn't get rendered (because the clustering thought the cone would not be in those clusters).

I don't know how to make the clustering multiview-aware. But those willing to build their own copy of Godot can misuse the following threshold as a workaround:

https://github.com/godotengine/godot/blob/809a98216267f3066b9fec2f02b2042bdc9d3e0d/servers/rendering/renderer_rd/cluster_builder_rd.h#L134

This was intended to deal with really-broad spotlights which are just handled as though they are spheres. If this threshold is changed to 0.0, all spotlights will be treated as spheres. This will cause way more clusters to process each spotlight, but the resulting sphere will generally cover where the spotlight lands no matter which eye you're looking out of. This is an ugly hack since it will make the spotlight processing wasteful (especially if you have many narrow spotlights side-by-side), but at least you won't get artifacts.

If you wanted to be slightly less hacky you could add || is_multiview_enabled in the following conditional (you'd need to determine is_multiview_enabled from somewhere that isn't in scope). This would only be better in that the non-XR performance would be unaffected: https://github.com/godotengine/godot/blob/809a98216267f3066b9fec2f02b2042bdc9d3e0d/servers/rendering/renderer_rd/cluster_builder_rd.h#L310

luzader avatar May 21 '23 22:05 luzader

@luzader you are very close, indeed in the forward+ renderer builds a map that determines which lights effect a given tile (square) but does this only from a single perspective. In our stereo rendering case that is indeed from between the eyes, but we do this against a view frustum that encompasses the frustum of both eyes.

As this is now sampled in "screen resolution", as a result when rendering each individual eye, it is checking the wrong tile. #78499 resolves that issue by performing an extra projection on this combined frustum to get the right tile and should resolve the OPs problem.

Note that the issue with setting attenuation really low remains, as you correctly state this also happens in the editor and in mono rendering and is caused by the light volume evaluated by the cluster logic being too small resulting in that blocky outline around the spotlight. Disabling the threshold on multiview isn't the right solution though, we need to look into correcting the light volume. We should probably raise this as a separate issue.

BastiaanOlij avatar Jun 21 '23 01:06 BastiaanOlij