|
|
|
|
@@ -1,56 +0,0 @@
|
|
|
|
|
shader_type spatial;
|
|
|
|
|
render_mode blend_premul_alpha, unshaded, ambient_light_disabled;
|
|
|
|
|
|
|
|
|
|
uniform sampler2D depth_texture : hint_depth_texture;
|
|
|
|
|
uniform int step_count : hint_range(3, 15, 2) = 3; // 2 samples per step
|
|
|
|
|
uniform float thickness : hint_range(1.0, 16.0, 0.1) = 3.0;
|
|
|
|
|
uniform vec3 edge_color : source_color = vec3(0.);
|
|
|
|
|
uniform float fade_start : hint_range(1.0, 1000.0, 0.1) = 100.0;
|
|
|
|
|
uniform float fade_length : hint_range(1.0, 1000.0, 0.1) = 200.0;
|
|
|
|
|
|
|
|
|
|
void fragment() {
|
|
|
|
|
// Setup step parameters
|
|
|
|
|
vec2 step_length = 1.0 / VIEWPORT_SIZE * thickness;
|
|
|
|
|
float step_angle = TAU / float(step_count);
|
|
|
|
|
// Per-pixel jitter to reduce patterning
|
|
|
|
|
float start_angle = fract(sin(dot(SCREEN_UV, vec2(12.9898, 78.233))) * 43758.5453) * TAU;
|
|
|
|
|
vec2 dir = vec2(cos(start_angle), sin(start_angle));
|
|
|
|
|
// step rotation matrix
|
|
|
|
|
mat2 rot = mat2(
|
|
|
|
|
vec2(cos(step_angle), -sin(step_angle)),
|
|
|
|
|
vec2(sin(step_angle), cos(step_angle)));
|
|
|
|
|
vec3 avg_dx = vec3(0.0);
|
|
|
|
|
vec3 avg_dy = vec3(0.0);
|
|
|
|
|
// save closest pixel to uniformly fade line.
|
|
|
|
|
float min_z = 1e6;
|
|
|
|
|
// Sample and average derivatives for all pairs
|
|
|
|
|
for (int i = 0; i < step_count; i++) {
|
|
|
|
|
vec2 uv1 = SCREEN_UV + dir * step_length;
|
|
|
|
|
vec2 uv2 = SCREEN_UV - dir * step_length;
|
|
|
|
|
float d1 = texture(depth_texture, uv1).r;
|
|
|
|
|
float d2 = texture(depth_texture, uv2).r;
|
|
|
|
|
vec4 up1 = INV_PROJECTION_MATRIX * vec4(uv1 * 2.0 - 1.0, d1, 1.0);
|
|
|
|
|
vec4 up2 = INV_PROJECTION_MATRIX * vec4(uv2 * 2.0 - 1.0, d2, 1.0);
|
|
|
|
|
vec3 p1 = up1.xyz / up1.w;
|
|
|
|
|
vec3 p2 = up2.xyz / up2.w;
|
|
|
|
|
min_z = min(min_z, min(-p1.z, -p2.z));
|
|
|
|
|
vec3 diff = p1 - p2;
|
|
|
|
|
avg_dx += diff * dir.x;
|
|
|
|
|
avg_dy += diff * dir.y;
|
|
|
|
|
|
|
|
|
|
dir = rot * dir; // rotate direction for next step
|
|
|
|
|
}
|
|
|
|
|
// fade outline width with distance
|
|
|
|
|
float distance_fade = 1e-4 + smoothstep(fade_start + fade_length, fade_start, min_z);
|
|
|
|
|
|
|
|
|
|
// Edge mask
|
|
|
|
|
float edge = 1.0 - smoothstep(0.1, 0.15, dot(normalize(cross(avg_dy, avg_dx)), VIEW));
|
|
|
|
|
|
|
|
|
|
// Small vignette at screen edges
|
|
|
|
|
edge *= smoothstep(0.00, 0.015 * thickness,
|
|
|
|
|
1.0 - max(abs(SCREEN_UV.x - 0.5), abs(SCREEN_UV.y - 0.5)) * 2.0);
|
|
|
|
|
|
|
|
|
|
// blend_premul_alpha avoids need to sample screentexture.
|
|
|
|
|
ALBEDO = edge_color * edge;
|
|
|
|
|
ALPHA = edge * distance_fade;
|
|
|
|
|
}
|