SceneDepth VisualShaderNode 4.4
Visual shader node that retrieves the pixel depth buffer from Godot. Equivalent of UE’s SceneDepth node. Captured in the texture is the depth of the opaque objects; translucency is not written to depth buffer
Use raw depth if you just want world units, ranged depth returns a clamped (0-1) depth gradient whose min / max distance values are defined by the input pins.
To install: Copypaste this into a new .gd file. The node will show up under /Addons/Utility
Shader code
@tool
class_name VSNode_SceneDepth
extends VisualShaderNodeCustom
###################
## Base Props
###################
func _get_name() -> String:
return "SceneDepth"
func _get_category() -> String:
return "Utility"
func _get_description() -> String:
return "Returns the scene depth buffer with raw depth and ranged depth outputs"
func _get_return_icon_type() -> PortType:
return VisualShaderNode.PORT_TYPE_SCALAR
#################
## Input props
#################
func _get_input_port_count() -> int:
return 2
func _get_input_port_name(port: int) -> String:
match port:
0: return "Min Distance"
1: return "Max Distance"
return ""
func _get_input_port_type(port: int) -> PortType:
match port:
0: return VisualShaderNode.PORT_TYPE_SCALAR
1: return VisualShaderNode.PORT_TYPE_SCALAR
return VisualShaderNode.PORT_TYPE_SCALAR
func _get_input_port_default_value(port: int) -> Variant:
match port:
0: return 0.0 # Default min distance
1: return 100.0 # Default max distance
return 0.0
#################
## Output props
#################
func _get_output_port_count() -> int:
return 2
func _get_output_port_name(port: int) -> String:
match port:
0: return "Raw Depth"
1: return "Ranged Depth"
return ""
func _get_output_port_type(port: int) -> PortType:
return VisualShaderNode.PORT_TYPE_SCALAR
#################
## Global code
#################
func _get_global_code(mode: Shader.Mode) -> String:
return """
uniform sampler2D depth_texture : hint_depth_texture, filter_nearest;
"""
#################
## Main shader code
#################
func _get_code(input_vars: Array[String], output_vars: Array[String],
mode: Shader.Mode, type: VisualShader.Type) -> String:
var code_template = """
{{
// Sample the depth texture
float depth = texture(depth_texture, SCREEN_UV).x;
// Convert to normalized device coordinates based on renderer
vec3 ndc;
#if CURRENT_RENDERER == RENDERER_COMPATIBILITY
ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;
#else
ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth);
#endif
// Convert to view space
vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;
float linear_depth = -view.z;
// Output raw depth
{raw_output} = linear_depth;
// Calculate ranged depth (normalized between min and max)
float min_dist = {min_input};
float max_dist = {max_input};
float ranged_depth = clamp((linear_depth - min_dist) / (max_dist - min_dist), 0.0, 1.0);
{ranged_output} = ranged_depth;
}}
"""
return code_template.format({
"min_input": input_vars[0] if input_vars[0] != "" else "0.0",
"max_input": input_vars[1] if input_vars[1] != "" else "100.0",
"raw_output": output_vars[0],
"ranged_output": output_vars[1]
})
func _is_available(mode: Shader.Mode, type: VisualShader.Type) -> bool:
return mode == Shader.MODE_SPATIAL && type == VisualShader.TYPE_FRAGMENT


Seems to be broken in 4.5 compatibility
Thanks for the headsup, I’ll take a look!