Raymarched 3D Noise Decal (fork)
fork of https://godotshaders.com/shader/raymarched-3d-noise-decal/ for compatibility / web
sdFBM noise texture and raymarching to create effect decals
– removed the need for MSAA support
– texture() instead of textureLod() for depth sampling
– made object_view_vec not needed anymore
Shader code
shader_type spatial;
#include "sdf_noise.gdshaderinc"
render_mode unshaded;
render_mode depth_test_disabled, cull_front;
uniform sampler2D depth_texture : hint_depth_texture, filter_linear_mipmap;
group_uniforms Color;
uniform float col_distance_scale = 1.0;
uniform vec3 col_near : source_color = vec3(1.0);
uniform vec3 col_far : source_color = vec3(0.0);
uniform float emission_boost = 1.0;
group_uniforms;
group_uniforms SDFNoise;
uniform float sphere_radius = 0.5;
uniform float noise_scale = 1.0;
uniform int detail = 4;
uniform float rough = 0.5;
uniform float inflate = 0.1;
uniform float smooth_fac = 0.2;
uniform float step_mult = 1.0;
group_uniforms;
mat3 y_rot(float angle) {
return mat3(
vec3(cos(angle), 0.0, -sin(angle)),
vec3(0.0, 1.0, 0.0),
vec3(sin(angle), 0.0, cos(angle))
);
}
float sdf_map(vec3 pos) {
float sphere_dist = length(pos) - sphere_radius;
vec3 noise_offset = vec3(0.0, -TIME * 0.1, 0.0);
pos = y_rot(pos.y * 10.0) * pos;
pos = pos * noise_scale + noise_offset;
sphere_dist = sdFbm(pos, detail, rough, inflate, smooth_fac, sphere_dist);
return -sphere_dist;
}
void fragment() {
float depth = texture(depth_texture, SCREEN_UV).x;
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth * 2.0 - 1.0);
vec4 view_coords = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view_coords.xyz /= view_coords.w;
vec3 world_pos = (INV_VIEW_MATRIX * vec4(view_coords.xyz, 1.0)).xyz;
vec3 obj_position = (inverse(MODEL_MATRIX) * vec4(world_pos, 1.0)).xyz;
vec3 cam_pos = (inverse(MODEL_MATRIX) * INV_VIEW_MATRIX * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
vec3 view_dir = normalize(obj_position - cam_pos);
vec3 cur_pos = obj_position;
for (int i = 0; i < 50; i++) {
float offset = sdf_map(cur_pos);
if (offset < -0.005) {break;}
cur_pos += view_dir * offset * step_mult;
}
float cur_dist = sdf_map(cur_pos);
float alpha = 1.0 - clamp(cur_dist * -100.0, 0.0, 1.0);
ALPHA = pow(alpha, 2.0);
float vol_depth = distance(obj_position, cur_pos);
float col_mix_fac = pow(1.0 - exp(-col_distance_scale * vol_depth), 2.0);
vec3 vol_color = mix(col_near, col_far, col_mix_fac);
ALBEDO = vol_color * emission_boost;
}