godotengine / godot-proposals

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

Make refraction a built-in shader feature #6103

Open atirut-w opened 1 year ago

atirut-w commented 1 year ago

Describe the project you are working on

Water shader

Describe the problem or limitation you are having in your project

As of currently, refractions are generated by Godot's Spatial/Standard material. This means that you will have to implement your own refraction codes if you are making a custom shader, whether in code or Visual Shader.

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

Having refraction as a built-in feature makes it so that you don't have to implement your own refractions when making a custom shader. This is a lot more convenient and saves some times as well.

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

A REFRACTION variable in custom shaders or under one of Visual Shader's PBR outputs.

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

Rendering is core

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

See above

Calinou commented 1 year ago

Built-in shader features have a cost even if not used[^1], so I wouldn't recommend doing this with features that aren't used often. This is the reason why parallax mapping isn't part of the scene shader either.

[^1]: While #ifdefs are used to compile out unused code, you still need to maintain a greater number of shader versions active.

paddy-exe commented 1 year ago

To build on top of what @Calinou mentioned, for visual shaders you can have plugins with custom nodes. For 4.0 there are also include files for shaders possible.

atirut-w commented 1 year ago

Can we have refraction as a built in function at least for Visual Shaders then?

Calinou commented 1 year ago

Can we have refraction as a built in function at least for Visual Shaders then?

Yes, as built-in visual shader nodes don't have a performance cost if not used. They still need to be created and maintained though :slightly_smiling_face:

atirut-w commented 1 year ago

Then I'd like to have it as an output slot then. Since Visual Shaders generate codes similar to Spatial Materials, this should be a better approach. Maybe I'll take a peek at the Visual Shader codes this evening.

Calinou commented 1 year ago

Then I'd like to have it as an output slot then.

I believe it can only be a node, not an output slot. Also, output slots should only be used for things that are commonly used, as it would have a performance cost even if not used otherwise.

atirut-w commented 1 year ago

How so? The generated shader codes from Visual Shaders does not include unused output slots.

paddy-exe commented 1 year ago

@atirut-w This is what Calinou means with output slots:

image

What you mean is this "HSV" output port here:

image

The implementation for the extra node for Visual Shaders shoulnd't be that much of a hassle. The only thing I am not sure of is the "Grey" option under the Refraction Channel:

image

Does that mean that every channel is set to 1.0? or to 0.5?

atirut-w commented 1 year ago

@atirut-w This is what Calinou means with output slots:

image

That's also what I meant. Codes for unused slots are not generated at least in Beta 12. I am not sure about 3.x.

paddy-exe commented 1 year ago

@atirut-w This is what Calinou means with output slots:

image

That's also what I meant. Codes for unused slots are not generated at least in Beta 12. I am not sure about 3.x.

That may be true, but the underlying GLSL shader would be more complex to do this with an extra output slot. This can be done in an extra node instead and calculated inside e.g. a visual shader and combined with the other parts of your shader.

Calinou commented 1 year ago

The only thing I am not sure of is the "Grey" option under the Refraction Channel:

The Gray option means the refraction texture's RGB channels are averaged (using value average, not perceptual average). You can see the exact formula used in the BaseMaterial3D shader code: https://github.com/godotengine/godot/blob/629796c333bcc46f2aeb4399c1a5786d6b013289/scene/resources/material.cpp#L1147-L1165

When used on a grayscale texture, it acts identical to either Red, Green, or Blue options (but not Alpha, as Gray ignores the texture's alpha channel, and an opaque grayscale's texture has a fully white alpha channel).

atirut-w commented 1 year ago

That may be true, but the underlying GLSL shader would be more complex to do this with an extra output slot

I don't think it could get more complex than Spatial's, considering they seem to generate Godot shader codes before translating them, at least in Beta 12.(You can see both VS and Spatial's generated shader codes and they omit unused parameters or slots).