Manually Calculating the Depth value in a compute shader

Godot Version

Godot Version 4.3

Question

Hi there,

I am currently working on a small project where I implement an optical Illusion for VR in Godot 4.3


It currently looks like this

To achive this I basicly reversed the depth value for specific Fragments. That worked if nothing obscures the cube. The parts with the Effect will show up infront of any object.

My Solution was to calculate the Depth Value of both Faces for each fragment and then to just flip them. Currently I am doing this in a compute shader and am writing the result in a texture that is then used by my fragment shader.

But right now the calculated depth Values are wrong and I dont know why.

This is my code for projecting the vertecies into screen space. I multiplied the x and y coordinates with the resolution for easier use later on

Vector3 porjectVertex(Vector3 inVertex)
{
    Projection invViewMatrix = new Projection (cam.GetTransform().AffineInverse());
    Projection projectionMatrix = cam.GetCameraProjection();
    Rect2 res = cam.GetViewport().GetVisibleRect();
    
	Vector4 vertex = new Vector4(inVertex.X,inVertex.Y,inVertex.Z,1);
	vertex = projectionMatrix * invViewMatrix * vertex ;
	vertex = vertex * (float)(1.0/vertex.W);
	return new Vector3((float)((vertex.X + 1.0) / 2.0) * res.Size.X ,(float)(1-((vertex.Y + 1.0) / 2.0)) * res.Size.Y,(float)(vertex.Z *  2.0 - 1.0));
}

This is the code that does the actual depth calculation. It mostly consist of a barycentric interpolation of the 3 z Values of my face vertecies


float calcZ(vec2 ScreenUV, vec3 V1, vec3 V2, vec3 V3)
{
    // calculate weights for barycentric Interpolation of z Values 

	float upper = ((V2.y - V3.y) * (ScreenUV.x - V3.x)) + ((V3.x - V2.x) * (ScreenUV.y - V3.y));
	float lower = ((V2.y - V3.y) * (V1.x - V3.x)) + ((V3.x - V2.x) * (V1.y - V3.y));
	float W_v1 = upper / lower ;

	float upper2 = ((V3.y - V1.y) * (ScreenUV.x - V3.x)) + ((V1.x - V3.x) * (ScreenUV.y - V3.y));
	float lower2 = ((V2.y - V3.y) * (V1.x - V3.x)) + ((V3.x-V2.x) * (V1.y - V3.y));
	float W_v2 = upper2 / lower2 ;

	float W_v3 = 1.0 - W_v1 - W_v2;


    // second test if fragment is in triangle
    if(W_v1 < 0 || W_v2 < 0 || W_v3 < 0)
    {
        return -1;
    }

    // calc z Value

    float z1 = V1.z ;
    float z2 = V2.z ;
    float z3 = V3.z ; 

    float z = (W_v1 * z1 + W_v2 * z2 + W_v3 * z3) / (W_v1 + W_v2 + W_v3);


    float depth = (1/z - 1/params.nearPlane)/(1/params.farPlane - 1/params.nearPlane); 



    return 1 - depth;
}

and for testing pourposes I wrote a simple fragment shader that shows me the differences of my calculated Values and the ones godot calculated

	vec4 clip_pos = PROJECTION_MATRIX * vec4(VERTEX, 1.0);
	clip_pos.xyz /= clip_pos.w;

	vec4 tex = texture(exclusionmask,SCREEN_UV);
	
	if(tex.x == 1.0 && tex.y != 1.0 && tex.z != 1.0)
	{
		float zDiff = clip_pos.z - tex.z;
		float zDiff2 = clip_pos.z - tex.y;
		tex = vec4(zDiff,0.0,0.0,1.0);

	}else
	{
		tex = vec4(0.0,0.0,0.0,0.0);
	}
	ALBEDO = tex.xyz;

If any of you have and Idea what I might be doing wrong or have a better solution to my problem please let me know.

Any help is greatly appreciated

Thanks

Did it break after updating Godot or after some refactoring? I think godot 4.3 changed how the z buffer works but since you are using a compute shader it may not apply.

It was always written in Godot 4.3 never tried it in 4.2 or lower
I am aware of the Changes done in 4.3 and my code should account for that.