Depth_draw_opaque not working as expected? Depth is not drawn even when alpha is 1

Godot Version

v4.2.1.stable.mono.official [b09f793f5]

Question

I noticed this problem while using a shader to visualize normals on a mesh imported from Blender. When using depth_draw_opaque, instead of e.g. depth_draw_always, parts of the model do not have depth drawn, even when the shader unconditionally sets fragment ALPHA = 1.0;.

Here’s what it looks like in the Godot editor (depth test not working as expected):

2024-05-08 godot weird geometry

Here’s the shader I’m using:

shader_type spatial;
render_mode unshaded, depth_draw_opaque, cull_back;

void vertex() {
    COLOR = vec4(abs(NORMAL.x), abs(NORMAL.y), abs(NORMAL.z), 1.0);
}

void fragment() {
    ALBEDO = COLOR.rgb;
    METALLIC = 0.0;
    ROUGHNESS = 1.0;
    SPECULAR = 0.0;
    ALPHA = 1.0;
}

Am I misunderstanding, or doing something wrong? Why do depth_draw_always and depth_draw_opaque behave differently even when ALPHA is always set to 1?

Confusingly, this was fixed by adding this line to the fragment shader:

ALPHA_HASH_SCALE = 1.0;

This might be related to ``depth_draw_never`` moves objects into the transparent pipeline for no reason · Issue #73158 · godotengine/godot · GitHub.

Writing to ALPHA_HASH_SCALE will make the material use alpha hash transparency instead of alpha blended transparency, which is a form of 1-bit transparency that can write to depth (like alpha scissor).