World Coordinate Edge Fade
Colors a rectangular volume around an object’s center and smoothly fades the edges.
Distance from the center is specified in world coordinates (doesn’t change with object scale) as is the fade distance.
Color and min/max alpha values are user-defineable.
Shader code
shader_type spatial;
render_mode unshaded, blend_mix, cull_disabled;
// Distance before
uniform vec3 dist_before_falloff = vec3(0.5);
uniform float falloff_dist = 0.2;
uniform float alpha_max = 1.0;
uniform float alpha_min = 0.0;
uniform vec3 color: source_color;
// varying flat is a fun thing
// https://www.reddit.com/r/godot/comments/h81uwb/what_does_varying_flat_do_in_a_shader/
// basically, in GODOT it seems the last vertex will set this value.
// Its actually not even necessary here since we should get the same Scale value from
// each vertex, interpolation will result in a single value being given to each fragment
varying vec3 Position;
varying flat vec3 Scale;
// Two pages were very helpful in figuring out this math:
// https://math.stackexchange.com/questions/13150/extracting-rotation-scale-values-from-2d-transformation-matrix
// https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
vec3 DecomposeScale(mat4 trans)
{
float len1 = sign(trans[0][0]) * length(trans[0].xyz);
float len2 = sign(trans[1][1]) * length(trans[1].xyz);
float len3 = sign(trans[2][2]) * length(trans[2].xyz);
return vec3(len1, len2, len3);
}
void vertex() {
Position = VERTEX;
// Decompose the scale because we want size in world coordinates
// Was using the straight model_matrix before, but that caused rotational issues (fade shifted
// position as the object rotated)
Scale = DecomposeScale(MODEL_MATRIX);
}
void fragment() {
vec3 tmpVec = max(vec3(0.0), abs(Position * Scale) - dist_before_falloff);
float tmp = length(tmpVec) / max(0, falloff_dist);
tmp = smoothstep(0, 1, tmp);
float alpha = mix(alpha_max, alpha_min, tmp);
ALBEDO = color;
ALPHA = alpha;
}