Shield Shader with Intersection Highlight

Made for Godot 4.3

This shader creates a shield effect that highlights intersections with other objects by using depth comparisons.
I’m not really sure if this is the most optimized solution, but it works well for small projects.

Instruction:

  • Add a MeshInstance3D
  • Set its mesh
  • Apply the shader
  • Use the commented ndc if you use the compatibility renderer

Tutorial Used:

Shader code
shader_type spatial;

render_mode unshaded, cull_disabled;

uniform sampler2D depth_texture : source_color, hint_depth_texture;
uniform vec4 color1: source_color = vec4(1,1,1,.1);
uniform vec4 color2: source_color = vec4(1,1,1,1);
uniform float threshold = .2;
uniform float fresnel_sharpness = 1.0;


void fragment() {
	float depth = texture(depth_texture, SCREEN_UV).x;
	//vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;
	vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth);
	vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
	view.xyz /= view.w;
	float linear_depth = -view.z;
	
	float object_depth = FRAGCOORD.z;
	//vec3 object_ndc = vec3(SCREEN_UV, object_depth) * 2.0 - 1.0;
	vec3 object_ndc = vec3(SCREEN_UV * 2.0 - 1.0, object_depth);
	vec4 object_view = INV_PROJECTION_MATRIX * vec4(object_ndc, 1.0);
	object_view.xyz /= object_view.w;
	float linear_object_depth = -object_view.z;
	
	float fresnel = pow(1.0 - dot(VIEW, NORMAL), fresnel_sharpness);
	
	if (linear_depth - linear_object_depth > threshold) {
		ALBEDO = color1.rgb;
		ALPHA = color1.a+fresnel;
	}
	else {
		ALBEDO = color2.rgb;
		ALPHA = color2.a+fresnel;
	}
}
Tags
fresnel, intersection, Shield
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.

Related shaders

Magical Shield Shader #3

Magical Shield Shader #2

3D Bubble/Spatial shield shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
john pokr
john pokr
18 hours ago

you can replace the if-statement at the bottom with some fancy gdscript magic using mix and step. I heard somewhere if-statements are bad in shaders, so…

also thank you for showing me how sampling the depth texture works I was pulling my hair out over this

vec4 chosen_color = mix(color2, color1, step(threshold, linear_depth - linear_object_depth));

ALBEDO = chosen_color.rgb;
ALPHA = chosen_color.a+fresnel;