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

Vulkan Mobile: multiple omni lights 3d render incorrectly #70280

Closed
fracteed opened this issue Dec 19, 2022 · 21 comments · Fixed by #70929
Closed

Vulkan Mobile: multiple omni lights 3d render incorrectly #70280

fracteed opened this issue Dec 19, 2022 · 21 comments · Fixed by #70929

Comments

@fracteed
Copy link

Godot version

4.0 beta 8

System information

Windows 10 960m

Issue description

When using multiple omni 3d lights in a scene, surfaces are incorrectly shaded.

2 omni lights seem to be ok, but when a 3rd is added problems arise, and adding more than that just makes it worse.

Vulkan forward renderer is fine, so this exists in Vulkan mobile. I was getting a crash with opengl, so couldn't test it.

In the following video you can see with 3 lights, as I move the camera the cube surface shading changes. When the 4th omni is added and moved, each cube has strongly contrasted shading that shifts with the light.

mobile_omnis.mp4

Steps to reproduce

  • add multiple cubes that butt against each other
  • add 4 omni lights
  • move around the 4th light and note the shading

Minimal reproduction project

mobile_omni.zip

@clayjohn
Copy link
Member

I think this is a duplicate of #55881 which was fixed by #70068 if so, the fix will be in beta 9

@fracteed
Copy link
Author

@clayjohn I just downloaded the latest master autobuild from github and was still having the same issue.

@fracteed
Copy link
Author

@clayjohn just had a better look and it does seem to resolve the camera angle issue like in #55881 as well as the split shading when the 3rd omni is added.
However, when the 4th omni is used you can see the weird popping of the shading as the light is moved over the x axis.

@coobenguy
Copy link

Yes this bug is still present in beta 10. Technically the original bug did get "better" but now it takes 2 or more omni lights to start happening or 3 spotlights or more. Also from what I can tell the camera angle issue is still there when using these amounts of lights.

@coobenguy
Copy link

Not sure why this was closed the issue still exists, atleast in the 4.1 dev release

@clayjohn
Copy link
Member

clayjohn commented May 2, 2023

Running on 4.1 dev the MRP looks fine to me

image

It looks fine in motion too.

If you are running into a related bug, please open a new issue with full details including an MRP that reproduces the issue

@fracteed
Copy link
Author

fracteed commented May 3, 2023

@coobenguy It is working fine for me. Maybe you are seeing the light limitation on some surfaces, which could look like an artifact?

@clayjohn The omni light banding is very obvious in that image. Not sure if you read the discussion between mux and myself on twitter about this? Hopefully this can be rectified as it does make the mobile renderer fairly unusable unless you only use directional lights.

@clayjohn
Copy link
Member

clayjohn commented May 3, 2023

@clayjohn The omni light banding is very obvious in that image. Not sure if you read the discussion between mux and myself on twitter about this? Hopefully this can be rectified as it does make the mobile renderer fairly unusable unless you only use directional lights.

Its a very challenging situation. The simple solution is to use 16bit colors to get rid of banding. While that is supported on mobile it is very bad for performance and defeats the purpose of having a "mobile" renderer. So we need to see if we can expose better options that don't hurt performance so bad (i.e. debanding at draw time, or debanding in a post-process). Taking a quick look now it seems like the debanding project setting isn't working on mobile. So we need to fix it and re-evaluate the situation

@fracteed
Copy link
Author

fracteed commented May 3, 2023

@clayjohn I don't understand why this issue is not seen on the 4.0 Opengl renderer though. Isn't it using 8bit as opposed to the 10bits that mobile is using? This was also never an issue in 3.x and wasn't that also using 8bit lighting as well?

Mux did think that this was odd and that maybe something to do with tonemapping in mobile.

@clayjohn
Copy link
Member

clayjohn commented May 3, 2023

@clayjohn I don't understand why this issue is not seen on the 4.0 Opengl renderer though. Isn't it using 8bit as opposed to the 10bits that mobile is using? This was also never an issue in 3.x and wasn't that also using 8bit lighting as well?

This is kind of expected as the mobile renderer works very different from the OpenGL renderer. The OpenGL renderer tonemaps the lighting into sRGB space before writing color into the framebuffer. We do this to reduce banding as much as we can. The tradeoff is that lighting will look wrong as lights don't blend correctly in sRGB space.

In OpenGL 3 the GLES3 renderer defaulted to 16 bit depth on Desktop, but uses RGB10 on mobile (same as the current mobile renderer). On mobile it had the same banding problems that we have with the mobile renderer. The GLES2 renderer used sRGB space, so it had reduced banding, but suffered from the same lighting artifacts that the GL Compatibility renderer does.

In theory we should be able to resolve banding with a debanding shader quite easily. RGB10 gives us 1024 bits to use per-channel. We scale the lighting to the 0-2 range, so we have 512 bits within the 0-1 range (still double RGB8). A small amount of debanding should be sufficient to remove artifacts. But it looks like now debanding just doesn't work at all.

@fracteed
Copy link
Author

fracteed commented May 3, 2023

@clayjohn Ah, that is very interesting...thanks for the explanation! I did try a very hacky dithering shader and it did help somewhat. I look forward to a proper debanding solution or will just move over to the forward clustered renderer eventually. The mobile renderer does have amazing performance on desktop, so hopefully I can stick with that.

@clayjohn
Copy link
Member

clayjohn commented May 3, 2023

@clayjohn Ah, that is very interesting...thanks for the explanation! I did try a very hacky dithering shader and it did help somewhat. I look forward to a proper debanding solution or will just move over to the forward clustered renderer eventually. The mobile renderer does have amazing performance on desktop, so hopefully I can stick with that.

I thought about this some more while having dinner and have myself convinced that we need to dither during the regular draw pass and in the post-process. 10 bits just isn't enough precision to do otherwise. Debanding only during the post process isn't enough as the banding artifacts from the low-bit framebuffer will get worse during tonemapping and linear->sRGB conversion.

@fracteed
Copy link
Author

fracteed commented May 3, 2023

@clayjohn thanks, that seems reasonable. Probably why my very simple dithering attempt with a canvas shader had limited impact. Will be very interested to see how well your idea works...

@clayjohn
Copy link
Member

clayjohn commented May 3, 2023

I should be asleep right now, but I just couldn't help myself, so here is a quick POC:

Master
Screenshot from 2023-05-02 23-19-46

Dithering applied in scene shader
Screenshot from 2023-05-02 23-18-20

Using the MRP from this issue without any changes

@fracteed
Copy link
Author

fracteed commented May 3, 2023

@clayjohn oh wow, that is an amazing difference! I really appreciate you looking at this issue. You should also get some sleep :)

@coobenguy
Copy link

@coobenguy It is working fine for me. Maybe you are seeing the light limitation on some surfaces, which could look like an artifact?

Definitely not light limit. To be fair it happens a lot less than before but its still there. In actual gameplay you also encounter it a lot more just by chance

2023-05-05.23-16-57.mp4
2023-05-05.23-20-20.online-video-cutter.com.mp4

@fracteed
Copy link
Author

fracteed commented May 6, 2023

@coobenguy Interesting, I can of course see it in your videos. Are you able to reproduce this is a simple scene with just some primitives? I do still notice lights sometimes turn off in my game on the ground plane and have just assumed it is the light limit triggering this.

My game is top down, so has a fixed camera angle. It looks like the camera angle shifts in yours is maybe causing this?

@Calinou
Copy link
Member

Calinou commented May 6, 2023

The omni light banding is very obvious in that image. Not sure if you read the discussion between mux and myself on twitter about this? Hopefully this can be rectified as it does make the mobile renderer fairly unusable unless you only use directional lights.

Use https://github.com/fractilegames/godot-gles2-debanding-material/blob/main/debandingmaterial.shader on all materials with a solid color.

@fracteed
Copy link
Author

fracteed commented May 7, 2023

@Calinou there is already a POC solution from clayjohn if you look up a few posts. I tried a post shader with limited success, so will wait until he has time to add his superior solution which I believe is debanding in both the draw and post passes.

@fracteed
Copy link
Author

@clayjohn Just wondering if there are still plans to include the dithering technique you demoed into the mobile renderer? Apologies for the thread bump...

@clayjohn
Copy link
Member

Thanks for the reminder. I put my thoughts into a proposal so the idea doesn't get lost

godotengine/godot-proposals#7336

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

Successfully merging a pull request may close this issue.

4 participants