Distance Alpha Clipping

Godot Version

4.2.1

Question

Hi all,
I recently started working in Godot and i’m currently trying to port a shader I wrote in unity and I have encountered a problem which I can’t figure out.

I’m trying to visually remove faces when a draw distance value of a vertex is out of limits. I did the Vertex shader part, but now I’m trying to clip the alpha value of the entire face in the frag shader, so discarding everything that’s not 1.0, removing the interpolating parts.

Vert:

vec3 world_camera = (INV_VIEW_MATRIX * vec4(vec3(0.0), 1.0)).xyz;
vec3 world_vertex = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
COLOR.a = (draw_distance > 0.0 && distance(world_vertex, world_camera) > draw_distance) ? float(0.0) : float(1.0);

Frag:

if (COLOR.a == 1.0)
{
ALPHA = (texture_color.a);
}
else
{
discard;
}

When running it like this, it seems to work, but it also generates a glitchy noise pattern removing fragment pixels on all faces including the ones which should have a 1.0 alpha value. Messing around with the code I’ve noticed the same glitch effect when I discard at both the 1.0 value and 0.0 value, so it seems I’m doing something wrong.

In unity the frag shader did this:

#if defined(BLEND) || defined(SCISSOR)
clip(-(albedo.a <= alphaCutoff));
#endif
clip(-(i.diff.a && draw_distance == 1));

Any suggestions on clipping like this in the frag shader?

I think after transformation you need to divide by w component. In vertex shader

1 Like

Which vector should be divided by which vector’s w component?
I tried everything i could think of but no luck.

I don’t know much about shaders. But my idea is try only using fragment shader.


void fragment() {
    vec3 len = length(VERTEX);
    if (len < distance) {
        // Draw here
    } else {
        // Discard here
    }
}

Apologies me if I am wrong.

Thx for the suggestions.
I’m not sure how that vertex length works, but it looks pretty much the same.
It might have something to do with the w component though.

When running this line (for affine mapping):
POSITION /= abs(POSITION.w);
The glitches become sort of quantized, so it’s not a noisy mess anymore and leaves most tris that should be visible intact (while still correctly removing out of limit tris), but when moving the camera random faces still get deleted.

However, it’s looking like the code basically works fine but I’m just not passing the data correctly to the frag shader (setting value of COLOR.a manually to 1.0 in vertex shader gives same glitching as distance value, also frag works fine setting the alpha value manually).
So I’d like to try passing the distance float to the frag part with something other than COLOR.a to see what happens, but I’m not experienced enough with godot shaders to know what ways there actually are (unity has a whole bunch of passable Texcoords but I haven’t found equivalents yet in godot).

So I’ll have to figure that out.

I tried passing it trough now with a varying float, it still gives me a noisy mess so that doesn’t seem to be the problem.

EDIT:
I also tried running the third line of the vert part in the frag shader, which works as expected.
So it has to be something I’m missing before passing the COLOR.a value to frag.

Figured it out, in frag shader:
ALPHA = texture_color.a / COLOR.a;

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