godotengine / godot-docs

Godot Engine official documentation
https://docs.godotengine.org
Other
3.77k stars 3.07k forks source link

Document need for normal roughness texture conversion for CompositorEffects #9591

Closed pink-arcana closed 10 hours ago

pink-arcana commented 2 months ago

Your Godot version: 4.3 beta 2

Issue description: (I'm working backwards from the source code for this, so apologies if I get the details wrong.)

As of https://github.com/godotengine/godot/pull/86316, it appears that the normal roughness texture is stored in an optimized format. In order for it to work correctly with users' Spatial shaders, it looks like a conversion function (normal_roughness_compatibility()) is applied when the user samples the texture.

normal_roughness_texture before: normal_before

normal_roughness_texture after normal_roughness_compatibility(): normal_after

In a CompositorEffect/compute shader, you have direct access to the texture that is stored in GPU memory. In my testing, applying the normal_roughness_compatibility() function to it manually in the compute shader gives you the same normals data that the Spatial shaders see.

The issue is that it is very difficult to discover, since you must first realize that there is a problem with the normal roughness texture (as you can see, it just looks a bit degraded), and then find this function in the source code.

Perhaps the need for this conversion can be documented along with the existing instructions for accessing the normal roughness texture in the CompositorEffect documentation linked below?

URL to the documentation page (if already existing): https://docs.godotengine.org/en/latest/classes/class_compositoreffect.html#class-compositoreffect-property-needs-normal-roughness

11/07/24: Edited for clarity and screenshots.

tetrapod00 commented 1 month ago

This issue also seems to affect the older fullscreen quad postprocessing effects. There are commonly used outline shaders such as this one that rely on the old behavior of the normal buffer, and whose behavior changed between 4.2 and 4.3.

Is it possible for the reverse-Z blogpost to receive an edit with information about the normal buffer change, or a link to the documentation about it? Many of the users looking to update their old postprocessing effects will need both pieces of information, and are already able to find their way to the blogpost.

Edit: this case was addressed in https://github.com/godotengine/godot/pull/94812.

tetrapod00 commented 3 weeks ago

@pink-arcana Do you have a GLSL compute shader snippet using the normal_roughness_compatibility() function that you have confirmed works? I tried looking in https://github.com/pink-arcana/godot-distance-field-outlines but didn't see anything.

Working on getting this documented.

pink-arcana commented 3 weeks ago

Thanks for creating the PR! In that repo, I renamed it to unpack_normal_roughness(). That's probably why it's hard to find, sorry! It's otherwise just copied directly from the original normal_roughness_compatibility().

I didn't test it vigorously. It was just (1) displaying the resulting normal image and verifying it doesn't have the artifacts, and then (2) using it in a simple normal sobel for outline detection, and it seemed to find the expected outlines. I don't think there's a reason to expect any problems with it, though, as long as the function is the same?

tetrapod00 commented 3 weeks ago

Just wanted to avoid documenting something unconfirmed. That's enough confirmation for me, since I also confirmed it myself in the other case of Spatial shaders before it was patched. Thanks!

pink-arcana commented 3 weeks ago

Totally get it! I also want to be sure it's correct.

I just created a branch for that repo that uses normals. It's very basic but I think it works as expected (some artifacts in shallow areas from using a normal sobel alone). If you download that branch, play the demo, and choose the CE option, it will use normals for outline detection. I also output the result of the conversion function to a debug image that you can see in RenderDoc. This is pretty much the opposite of an MRP, but hopefully it's useful!

Edited to add before/after and collapse the screenshots.

Screenshots

![Screenshot 2024-08-18 151027](https://github.com/user-attachments/assets/bdceb5f9-c55f-427f-95b7-cd7cbcc5dbb4) ![Screenshot 2024-08-18 151103](https://github.com/user-attachments/assets/04c3a9ac-70f0-4da3-a3e5-688af768472f)

Normal roughness texture - before/after

Before: ![Screenshot 2024-08-18 152533](https://github.com/user-attachments/assets/c5c3bb67-d6e4-43b9-9863-b069339505cc) After: ![Screenshot 2024-08-18 152538](https://github.com/user-attachments/assets/78361745-29df-49cd-8be8-85c9412c33fd)

tetrapod00 commented 3 weeks ago

Thanks, that's very helpful! I'm personally satisfied with this level of confirmation already, but I'll check out the branch if more is required.

pink-arcana commented 3 weeks ago

Added a before/after of the normal texture to the last comment, since that's probably the more helpful view!