-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
Implement dithered shadows for semi-transparent objects #3276
Comments
Foliage shadows are generally well-covered by alpha-tested (alpha scissor) shadows, since foliage doesn't have partially translucent areas by nature. Dithered shadows would be more useful in situations where you have partial transparency, such as smoothly fading an object in and out along with its shadow. Nonetheless, I think this feature is worth looking into for Godot 4.x. I'm not sure if it'll be possible to sample the albedo texture's alpha channel though – we may be limited to per-material opacity only (or even per-mesh opacity). |
And what about clothes and fabrics? |
Cloth and fabric also rarely has large semi-transparent areas. I think dithered shadows will be more useful for materials such as (stained) glass, in addition to fading objects (e.g. due to LOD or gameplay reasons). |
Time for colored shadows? 👀 |
Lights in |
For use cases such as this one, you can also use projector textures which are supported for both SpotLights and OmniLights. |
Sounds like a PITA to set up especially because you have to bake the correct colors into the texture, but how do you even do that? |
Exactly the implementation that I had on my mind. |
Also, about coloured shadows, I think one solution would be to have three lights, one for each colour component, and set three object dupes to selectively render in each shadow. I cannot test this theory right now though, 'cause I'm currently limited to GLES2. Frankly, if a pull request were made that implemented what was shown in this article, it would be much more elegant and efficient. Edit: I thought I'd mess with the shader some more, and I think caustics would be another great application of this proposal. |
HOW. I NEED SAUCE. |
It's quite simple really. 🙂 shader_type spatial;
uniform float caustic = 5.0; // The higher this is, the more the light is focused in the effect.
uniform sampler2D bayer;
void fragment() {
if (texture(bayer, FRAGCOORD.xy / 4.0).r > (1.0 - pow(dot(NORMAL, VIEW), caustic))) {
discard;
}
} The trick is to make the assumption that the caustic strength is directly proportional to the angle in which the light shines through the object. I use the same technique to fake caustics in blender eevee. |
@Calinou any chance of this proposal making it into 4.x? |
This proposal needs to be discussed in a proposal review meeting first. It won't be considered for 4.0 due to feature freeze, but we need to evaluate whether this makes sense to support in core for a future 4.x release. However, we are currently not reviewing proposals that are not critical for 4.0 in an effort to focus on releasing 4.0 first. This proposal also already has a workaround available, making it less critical to implement in core. |
It would still be nice to have this as a built-in "Dithered" transparency mode, though. A QoL thing. |
Dithering should use blue noise instead of plain white noise for smoother visual appearance. |
We already use interleaved gradient noise for distance fade dithering and shadow map rendering. It's a cheap approximation of a noise that focuses on high-frequency patterns (instead of low frequency) 🙂 |
I've tried both noise patterns. Downloaded the Free blue noise textures from this article: http://momentsingraphics.de/BlueNoise.html Loaded the uniform sampler2D dither_noise;
// See https://blog.demofox.org/2022/01/01/interleaved-gradient-noise-a-different-kind-of-low-discrepancy-sequence/
float ign(vec2 px)
{
float t = floor(mod(TIME * 60.0, 1024.0));
float x = px.x + 5.588238f * t;
float y = px.y + 5.588238f * t;
return mod(52.9829189f * mod(0.06711056f * x + 0.00583715f * y, 1.0f), 1.0f);
}
float noise(vec2 px)
{
return texelFetch(dither_noise, (ivec2(px) + ivec2(int(TIME * 397.0) % 8191)) & ivec2(511), 0).r;
}
void fragment() {
...
// Here transparency is the color and transparency (alpha) of the glass material in the mesh
ALBEDO = transparency.rgb;
ALPHA = transparency.a >= noise(SCREEN_UV * VIEWPORT_SIZE) ? 1.0 : 0.0;
ALPHA_SCISSOR_THRESHOLD = 0.5;
} The However, it looks completely wrong when animated (slowly rotated) in front of a camera... |
any updates on this one? |
To my knowledge, nobody is currently working on this. |
As someone who just started using Godot literally today, what do I need to put in the Bayer property? I'm just trying to get this shader to work on a translucent sphere and not seeing it make a real impact. There's a tiny hard edge around the sphere's perimeter but it does nothing to the shadow |
Describe the project you are working on
Not working on anything, but could be useful for rendering foliages where transparency have to be used instead of alpha-scissor/cutout rendering.
Describe the problem or limitation you are having in your project
As of currently(3.x, did not test the master branch), you cannot have semi-transparent shadows and thus are limited to Opaque Pre-Pass if you want shadows for your semi-transparent objects. This obviously won't look correct.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
An option to use dithered shadows that try to emulate semi-transparent shadows.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Use the alpha channel to dither between opaque and completely transparent, that's it. Basically how Unity does it.
Example: mrdoob/three.js#10600 (comment)
If this enhancement will not be used often, can it be worked around with a few lines of script?
Currently not possible to implement as a script or an addon.
Is there a reason why this should be core and not an add-on in the asset library?
Currently not possible to implement as a script or an addon.
The text was updated successfully, but these errors were encountered: