Transparency ignore shadows

Godot Version

4.3

Question

Hello!
I was following this tutorial (https://www.youtube.com/watch?v=0T-FMkSru64)

To create this behind the wall effect:
godot43_transparent_lighting

It uses a subviewport and 2 cameras to render out a background element, and a foreground element as defined by a view layer, and I modified it so that the view layer is switched when a raycast between the camera and player intersects a collision mesh in the environment group.

The problem is that switching the view layer and being rendered in the foreground is breaking the shadows for that object, when the desired behaviour is for the shadows not to be affected at all.
My lights are affecting the view layer the object is on as well, but it’s still not working.

I know this has to do with the way transparency works, so I’m wondering if Godot has an alternate to transparency like Unreal’s Opacity Mask? Essentially, with an Opacity Mask, the transparency is strictly either 0 or 1 for a given pixel, so features (and performance) act like the material has no transparency, and the pixels in the mask just aren’t rendered.

Failing that, is there an alternate way of getting a see through effect for objects in Godot? Thank you!

The shader:

shader_type canvas_item;

uniform float MULTIPLIER = 0.56;
uniform float SCALE = 0.5;
uniform float PIXEL_SIZE = 10.0;
uniform vec2 SCREEN_SIZE = vec2(1280, 720);
uniform float INNER_BOUND = 0.3;
uniform float MIDDLE_BOUND = 0.6;
uniform float OUTER_BOUND = 0.9;
uniform float BASE_OPACITY = 0.6;
uniform bool APPLY_XRAY = false;

void fragment() {
    if (!APPLY_XRAY) {
        // If x-ray is not applied, just output the original color
        COLOR = texture(TEXTURE, UV);
      
    }

    vec2 pixelatedUV = floor(UV * SCREEN_SIZE / PIXEL_SIZE) * PIXEL_SIZE / SCREEN_SIZE;
    float val = distance(vec2(pixelatedUV.x, pixelatedUV.y * MULTIPLIER), vec2(0.5, 0.5 * MULTIPLIER));
    val = val / SCALE;

    float alpha;
    if (val > OUTER_BOUND) {
        alpha = 1.0;
    } else if (val > MIDDLE_BOUND) {
        alpha = 0.6;
    } else if (val > INNER_BOUND) {
        alpha = 0.3;
    } else {
        alpha = 0.0;
    }

    alpha = max(alpha, 1.0 - BASE_OPACITY);
    vec4 original_color = texture(TEXTURE, UV);
    COLOR = vec4(original_color.rgb, alpha * original_color.a);
}

Workaround for the issue:
Since the geo for my environment is going to very lightweight, I created a copy of the just the mesh instance, set it’s transparency to 1, and use it as an invisible light blocker. Now whenever a portion of the mesh is invisible, the shadows remain as expected.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.