Depth based fade (Fog of war)

This shader blends the environment with a selected color based on how deep the environment penetrates the mesh. Similar to Fog of War.

Shader code
shader_type spatial;

render_mode unshaded;

uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;
uniform float max_visible_depth = 3.0;
uniform vec4 fog_color: source_color = vec4(0.0, 0.0, 0.0, 1.0);

float get_linear_depth(float log_depth, vec2 screen_uv, mat4 inv_proj_mat) {
	vec4 ndc = vec4(screen_uv * 2.0 - 1.0, log_depth, 1.0);
    vec4 upos = inv_proj_mat * ndc;
	vec3 pixel_pos = upos.xyz / upos.w;
	return -pixel_pos.z;
}

void fragment() {
	vec3 frag_world_pos = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
	vec3 camera_world_pos = (INV_VIEW_MATRIX * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
	vec3 camera_dir = normalize(frag_world_pos - camera_world_pos);
	vec3 world_normal = normalize((INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz);
	
    float log_depth = textureLod(depth_texture, SCREEN_UV, 0.0).r;
	vec4 screen_albedo = textureLod(screen_texture, SCREEN_UV, 0.0);
	float linear_depth = get_linear_depth(log_depth, SCREEN_UV, INV_PROJECTION_MATRIX);
	float surface_depth = get_linear_depth(FRAGCOORD.z, SCREEN_UV, INV_PROJECTION_MATRIX);
	float penetration_depth = linear_depth - surface_depth;
	float effective_depth = -max_visible_depth / dot(world_normal, camera_dir);
	float mix_percent = clamp(penetration_depth / effective_depth, 0.0, 1.0);
	ALBEDO = mix(screen_albedo, fog_color, mix_percent).rgb;
}
Tags
depth, fog of war
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from lavishbehemoth

Related shaders

guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
sumzbrod
sumzbrod
3 months ago

I tried using your shader, there are no errors, but the ColorRect is all white, what am I doing wrong? Godot 4.5
attached a screenshot below
comment image

Last edited 3 months ago by sumzbrod
sumzbrod
sumzbrod
3 months ago
Reply to  sumzbrod

I realized what the problem is, in godot 4+ you need to add this:

void vertex(){
  POSITION = vec4(VERTEX.xy, 1.,1.);
}