110 lines
4.0 KiB
Plaintext
110 lines
4.0 KiB
Plaintext
shader_type spatial;
|
|
render_mode unshaded, cull_disabled;
|
|
|
|
uniform float movement_Factor : hint_range(6.0,36.0) = 6.0;
|
|
uniform float rotation_speed : hint_range(-5.0, 5.0) = 1.0;
|
|
uniform float scroll_speed : hint_range(-5.0, 5.0) = 0.5;
|
|
uniform float vertex_displacement : hint_range(0.0, 5.0) = 0.2;
|
|
uniform float inner_fade = 0.2;
|
|
uniform float outer_fade = 0.8;
|
|
uniform vec4 color : source_color = vec4(1.0);
|
|
uniform vec4 spiral_color : source_color = vec4(0.8, 0.8, 0.8, 1.0);
|
|
uniform float spiral_turns : hint_range(1.0, 48.0) = 1.0;
|
|
uniform float spiral_swirl : hint_range(6.0, 360.0) = 6.0;
|
|
uniform float spiral_width : hint_range(0.02, 0.5) = 0.047;
|
|
uniform float spiral_strands : hint_range(1.0, 2.0) = 1.0;
|
|
|
|
uniform sampler2D noise_tex : source_color;
|
|
uniform sampler2D cloud_tex : source_color;
|
|
|
|
// ── Shared helpers ──────────────────────────────────────────────────────
|
|
|
|
// Rotate UV.x around the cylinder and scroll UV.y over time.
|
|
vec2 rotate_and_scroll(vec2 uv, float t) {
|
|
float angle = uv.x * (2.0 * PI);
|
|
angle += t * rotation_speed;
|
|
uv.x = angle / (2.0 * PI);
|
|
uv.y += t * scroll_speed;
|
|
return uv;
|
|
}
|
|
|
|
// Noise UV used for both distortion and displacement.
|
|
vec2 noise_uv(vec2 uv, float t) {
|
|
return uv * 3.0 + vec2(t * 0.2, t * 0.15);
|
|
}
|
|
|
|
// Sample noise and apply distortion offset to the rotated UVs.
|
|
vec2 distort_uv(vec2 rotated_uv, vec2 raw_uv, float t, float distortion_amount) {
|
|
float n = texture(noise_tex, noise_uv(raw_uv, t)).r;
|
|
return rotated_uv + (n - 0.5) * distortion_amount;
|
|
}
|
|
|
|
// Full cloud colour at a given UV, including noise distortion.
|
|
vec4 sample_cloud(vec2 uv, float t) {
|
|
float distortion_amount = (sin(t * 0.1) * 0.5 + 0.5) / movement_Factor;
|
|
vec2 ruv = rotate_and_scroll(uv, t);
|
|
vec2 final_uv = distort_uv(ruv, uv, t, distortion_amount);
|
|
return texture(cloud_tex, final_uv);
|
|
}
|
|
|
|
// Spiral mask in tunnel UV space. Uses the same motion params as the clouds.
|
|
// `spiral_strands` lets you blend from a single helix (1) to dual helix (2).
|
|
float spiral_mask(vec2 uv, float t) {
|
|
vec2 moved_uv = rotate_and_scroll(uv, t);
|
|
float u = fract(moved_uv.x);
|
|
float v = fract(moved_uv.y);
|
|
|
|
// Primary helix.
|
|
float helix_a = fract(u * spiral_turns - v * spiral_swirl);
|
|
float dist_a = abs(helix_a - 0.5);
|
|
float half_w = spiral_width * 0.5;
|
|
float thread_a = 1.0 - smoothstep(half_w, half_w + 0.06, dist_a);
|
|
|
|
// Optional opposing helix for barber-pole look.
|
|
float helix_b = fract(u * spiral_turns + v * spiral_swirl + 0.5);
|
|
float dist_b = abs(helix_b - 0.5);
|
|
float thread_b = 1.0 - smoothstep(half_w, half_w + 0.06, dist_b);
|
|
float use_second = clamp(spiral_strands - 1.0, 0.0, 1.0);
|
|
return max(thread_a, thread_b * use_second);
|
|
}
|
|
|
|
vec3 apply_spiral_color(vec2 uv, float t, vec3 base_rgb) {
|
|
float mask = spiral_mask(uv, t) * spiral_color.a;
|
|
return mix(base_rgb, spiral_color.rgb, mask);
|
|
}
|
|
|
|
// ── Vertex & Fragment ───────────────────────────────────────────────────
|
|
|
|
void vertex() {
|
|
float t = TIME + 30.0;
|
|
|
|
// Sample the full cloud pattern — same logic as fragment()
|
|
vec4 cloud = sample_cloud(UV, t);
|
|
|
|
// Also grab raw noise for high-frequency displacement
|
|
float n = texture(noise_tex, noise_uv(UV, t)).r;
|
|
|
|
// Combine cloud luminance with noise for displacement
|
|
float luminance = dot(cloud.rgb, vec3(0.299, 0.587, 0.114));
|
|
float disp = ((luminance + n) * 0.5 - 0.5) * vertex_displacement;
|
|
VERTEX += NORMAL * disp;
|
|
}
|
|
|
|
void fragment() {
|
|
float t = TIME + 30.0;
|
|
|
|
// Sample cloud using the shared pipeline
|
|
vec4 col = sample_cloud(UV, t);
|
|
|
|
// Radial fade (soft edges)
|
|
float radius = length(UV - vec2(0.5));
|
|
float fade = smoothstep(inner_fade, outer_fade, radius);
|
|
|
|
col.rgb *= color.rgb;
|
|
col.rgb = apply_spiral_color(UV, t, col.rgb);
|
|
col.a *= fade;
|
|
|
|
ALBEDO = col.rgb;
|
|
ALPHA = col.a;
|
|
}
|