Accessing per-pixel normals in Godot 4.0
Asked Answered
M

12

0

Hi, I was wondering if there is a way to access the screen-space normals in Godot 4.0.
I assume there could be a way because I found the DEBUG_DRAW_NORMAL_BUFFER option in the Viewport class, which shows the view I'm looking for when activating it.

I thought of this 'hack' where you could use a second Viewport, set this debug draw option and save the viewport texture to use it as a shader parameter. But I don't know about the performance and I assume this is not the intended way. Also in the docs it says that these debug normals don't respect the effect of custom vertex displacements from shaders.

Is there an easier way to get the normals, let's say for post-processing?

Monte answered 7/9, 2022 at 18:13 Comment(0)
O
0

While you can't get a normal pass from a forward renderer as far as I am aware, godot's is a depth pre-pass forward renderer, so you should be able to get a depth pass, and while the extra cost is not desirable, you could do some processing to produce a normal pass conversion from the depth pass.

Note that transparent objects don't get drawn to depth pre-pass, however that issue can be worked around by using a dithering shader instead of transparency. Further you can look into "Discontinuity Sensitive Filtering" to smooth out the dithering.

Honestly though I'm not sure it's worth the effort, might just be easier, well more performant anyways, to implement a deferred renderer plugin for godot on the source level.

edit:
https://docs.godotengine.org/en/stable/tutorials/shaders/advanced_postprocessing.html#full-screen-quad

Outstation answered 8/9, 2022 at 23:27 Comment(0)
K
0

Godot is not a deferred renderer, so I don't believe you can access the full normal buffer. However, you can access NORMAL in the fragment shader, but only for that pixel.

Kantian answered 7/9, 2022 at 18:37 Comment(0)
M
0

I've heard about this before, being a property of a forward renderer. But I thought there might be some changes to the renderer.
I wonder how this debug view is implemented, if it's just a this fragment shader you mention on every mesh.

Monte answered 7/9, 2022 at 18:52 Comment(0)
R
0

I think it does a fragment shader on every mesh to get the debug normal view, but I could be totally wrong about that. There was a proposal to expose other viewport modes like the debug modes for use at runtime, but I do not have a link to it and I do not think it was implemented.

Ricardo answered 8/9, 2022 at 0:37 Comment(0)
K
0

Also, AFAIK those debug views are only available in debug mode. So when you ship a game in release mode they will not be there. Performance would probably also be bad trying to hack it, so that may not be a good plan.

Kantian answered 8/9, 2022 at 1:0 Comment(0)
P
0

You didn't say from where you want to access them. GdScript, or Vertex Shader, or Fragment Shader?

Pinprick answered 8/9, 2022 at 18:49 Comment(0)
M
0

Pinprick Thanks for your input! I didn't manage to check if the debug view is available in release mode yet.

Ideally I would like to access the normals in a Post-Processing fragment shader.
So either in a spatial shader with a quad in front of the camera or a canvas shader for the viewport.

Monte answered 8/9, 2022 at 19:55 Comment(0)
P
0

Does this do what you want?

https://godotshaders.com/shader/uv-unwrap-and-normals-unwrapping-world-aligned/

Pinprick answered 8/9, 2022 at 20:20 Comment(0)
O
0

While you can't get a normal pass from a forward renderer as far as I am aware, godot's is a depth pre-pass forward renderer, so you should be able to get a depth pass, and while the extra cost is not desirable, you could do some processing to produce a normal pass conversion from the depth pass.

Note that transparent objects don't get drawn to depth pre-pass, however that issue can be worked around by using a dithering shader instead of transparency. Further you can look into "Discontinuity Sensitive Filtering" to smooth out the dithering.

Honestly though I'm not sure it's worth the effort, might just be easier, well more performant anyways, to implement a deferred renderer plugin for godot on the source level.

edit:
https://docs.godotengine.org/en/stable/tutorials/shaders/advanced_postprocessing.html#full-screen-quad

Outstation answered 8/9, 2022 at 23:27 Comment(0)
K
0

Oh, yeah, I forgot about that. You do have access to DEPTH_TEXTURE. It is relatively simple math to extract a normal from depth (and also world space position). See here, I think this is the best method.

https://wickedengine.net/2019/09/22/improved-normal-reconstruction-from-depth/

Kantian answered 9/9, 2022 at 1:25 Comment(0)
M
0

Thank you both for your answers!
Implementing a Deferred render pipeline option for Godot would definitely be very interesting, but it's over my head for now. I've seen Bastiaan Olij mentioning in his PRs that he's working towards making this kind of customization possible.

Depth pass to normals leads to many results online, it seems to be a common problem for implementing SSAO as well.

Monte answered 9/9, 2022 at 14:11 Comment(0)
M
0

Small addendum, the debug normal view does work in release-mode 🙂

Monte answered 9/9, 2022 at 15:18 Comment(0)
O
0

Monte it seems to be a common problem for implementing SSAO as well.

Sure, though 4.0 should already feature significantly improved AO compared to previous versions so not sure if it's even really worth the effort if it's about implementing better AO. Maybe, I'm just not sure.

Outstation answered 9/9, 2022 at 17:8 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.