Get depth of 3D point from camera in Shader

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By path9263

Hi there,

What I would like to do in my fragment shader is discard all pixels beyond a specified depth from the camera. What would be even better is if I could pass in a 3D coordinate and discard all pixels further from the camera than that passed in coordinate.

Thank you so much for any help you can offer!

:bust_in_silhouette: Reply From: path9263

Here is my solution, works great!

shader_type spatial;

render_mode unshaded;

uniform vec4 albedo : hint_color; // color of the material 

uniform vec3 centerPos = vec3(0.0, 0.0, 0.0);  // anything further from this pos from the camera will be discarded, needs to be updated by script each frame
uniform vec3 cameraPos = vec3(34.160301, 136.675003, 127.48799);  // position of the camera, needs to be updated by script each frame, this is the default start pos

varying float distanceToCam; // distance from cam to center
varying vec4 world_pos;  // of current vertex
varying float vertexToCam; // distance from current vertex to the camera

void vertex() {
	world_pos = WORLD_MATRIX * vec4(VERTEX, 1.0);  // get coords as world coords
	
	vertexToCam = distance(world_pos.xyz, cameraPos);
	distanceToCam = distance(centerPos, cameraPos);  // could be computed outside shader but easier to debug this way
}

void fragment() {
	ALBEDO = albedo.rgb;
	
	if(vertexToCam > distanceToCam){
		//ALBEDO.g = 0.0;
		discard;
	}
}

To set the shader uniforms call this on the MeshInstance each frame:

get_surface_material(0).set_shader_param("centerPos", centerNode.get_global_transform().origin)  # vec 3
	get_surface_material(0).set_shader_param("cameraPos", camNode.get_global_transform().origin)  # vec 3

Hope this helps someone!