Skip to content

Instantly share code, notes, and snippets.

@partybusiness
Last active September 14, 2024 14:37
Show Gist options
  • Save partybusiness/2fc76d1d1522e7af425288bed85ec36b to your computer and use it in GitHub Desktop.
Save partybusiness/2fc76d1d1522e7af425288bed85ec36b to your computer and use it in GitHub Desktop.
shader_type spatial;
render_mode unshaded, blend_mul, depth_draw_never, depth_test_disabled;
// creates a silhouette that appears when the mesh is behind something else
// you can combine this with another material by assigning this as the Next Pass material
// this might need adjustment to work with 4.3 and later, because of the reversed depth
uniform vec3 shadow_colour:source_color = vec3(0.7,0.7,0.9);
uniform sampler2D depth_texture:hint_depth_texture;
/**
* Minimum distance between wall and character before silhouette starts to appear
*/
uniform float min_threshold = 0.07;
/**
* Distance between wall and character where silhouette reaches full opacity
*/
uniform float max_threshold = 0.08;
// because there wasn't an easy way to just flip the depth testing, I used a depth comparison based on this:
// https://github.com/danilw/godot-utils-and-other/blob/03bbe5112377040506d4498a1c5cc91bdda5f5cf/graphic_demo_3d/game/models/objects/spheres/shield.shader#L48
varying float near;
varying float far;
float linearize(float c_depth) {
c_depth = 2.0 * c_depth - 1.0;
return near * far / (far + c_depth * (near - far));
}
void vertex() {
PROJECTION_MATRIX[0];
near = PROJECTION_MATRIX[3][2] / (PROJECTION_MATRIX[2][2] - 1.0);
far = PROJECTION_MATRIX[3][2] / (PROJECTION_MATRIX[2][2] + 1.0);
}
void fragment() {
float zdepth = linearize(texture(depth_texture, SCREEN_UV).x);
float zpos = linearize(FRAGCOORD.z);
float diff = zpos - zdepth; //difference between depth and
float mix_val = smoothstep(min_threshold, max_threshold, diff);
ALBEDO.rgb = mix(vec3(1.0), shadow_colour, mix_val);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment