godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Use two-pass rendering for double sided transparent objects #4825

Open QbieShay opened 2 years ago

QbieShay commented 2 years ago

Describe the project you are working on

Various VFX. Specifically, double sided smoke. For an example, image from: https://twitter.com/qbieshay/status/1422982180339339267?s=20&t=t0oqMyFy3uPLaixxVr4fXA

Describe the problem or limitation you are having in your project

It's hard and cumbersome to have multiple render passes for double sided transparent objects, and a single render pass with cull disabled will create obvious artifacts. Cull off: Screenshot from 2022-07-08 15-11-45

Two-pass: Screenshot from 2022-07-08 15-21-33

Note, this specific texture has hard edges so i could use scissor, but other textures like the first image of the issue don't work with scissor.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a cull_two_sides flag (name up for debate) which will tell godot's renderer to do two draw passes, one first with front face culling, and one after with backface culling.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

There will be a flag that will tell the renderer to render the same object twice, one with front face culling and one with backface culling. These passes will be executed one after the other so there is no need to worry about render priority. Int he shader, it's possible to control the rendering with FRONT_FACING, which is a flag that already exists.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not a few lines of script. It is possible to reimplement a special "shader material" that will actually auto assign a second pass. The problem is that rendering order of draw passes flickers (see https://github.com/godotengine/godot-proposals/issues/4777) and culling flags are part of the shader code (see https://github.com/godotengine/godot-proposals/issues/933) These issues coupled together create an incredibly cumbersome pipeline to work with double sided transparent materials. Overlay material could be a way to fix this issue, but won't work for multi surface meshes. I have no need for multi surface meshes, but maybe someone else does.

Is there a reason why this should be core and not an add-on in the asset library?

It modifies the renderer.

mrjustaguy commented 2 years ago

isn't cull disabled what you're looking for? (one of the 3 cull modes, the other two being front and back)

QbieShay commented 2 years ago

No, cull disable renders in the same render pass, meaning that sometimes you have overlapping triangles and visual artifacts