99 lines
3.3 KiB
Plaintext
99 lines
3.3 KiB
Plaintext
|
|
shader_type spatial;
|
||
|
|
render_mode unshaded, blend_mix, cull_disabled, depth_draw_opaque;
|
||
|
|
|
||
|
|
// ===== Your existing params =====
|
||
|
|
uniform vec2 R = vec2(0.8, 0.6);
|
||
|
|
uniform float scale = 0.5;
|
||
|
|
uniform float speed = 1.0;
|
||
|
|
uniform vec3 direction = vec3(1.0, 1.0, 0.0);
|
||
|
|
uniform float distortion = 0.5;
|
||
|
|
uniform float layers = 2.0;
|
||
|
|
uniform float shades = 3.0;
|
||
|
|
uniform int steps = 6;
|
||
|
|
uniform vec3 tint = vec3(0.459, 0.765, 1.0);
|
||
|
|
|
||
|
|
// ===== Waves (Gerstner) =====
|
||
|
|
uniform vec2 wave1_dir = vec2(1.0, 0.2);
|
||
|
|
uniform float wave1_amp = 0.25;
|
||
|
|
uniform float wave1_len = 8.0;
|
||
|
|
uniform float wave1_steep = 0.6;
|
||
|
|
uniform float wave1_speed = 1.0;
|
||
|
|
|
||
|
|
uniform vec2 wave2_dir = vec2(0.3, 1.0);
|
||
|
|
uniform float wave2_amp = 0.12;
|
||
|
|
uniform float wave2_len = 3.5;
|
||
|
|
uniform float wave2_steep = 0.7;
|
||
|
|
uniform float wave2_speed = 1.6;
|
||
|
|
|
||
|
|
uniform float time_scale = 1.0;
|
||
|
|
|
||
|
|
// ---- noise for color ----
|
||
|
|
float gyroid(vec3 seed) { return dot(sin(seed), cos(seed.yzx)); }
|
||
|
|
|
||
|
|
float fbm(vec3 seed) {
|
||
|
|
float result = 0.0;
|
||
|
|
float a = 0.5;
|
||
|
|
for (int i = 0; i < steps; i++) {
|
||
|
|
seed += direction * TIME * speed * 0.01 / a;
|
||
|
|
seed.z += result * distortion;
|
||
|
|
result += gyroid(seed / a) * a;
|
||
|
|
a *= 0.5;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Gerstner in object space
|
||
|
|
vec3 gerstner_obj(vec2 obj_xz, vec2 dir, float amp, float lambda, float steep, float spd, float t) {
|
||
|
|
dir = normalize(dir);
|
||
|
|
float k = 2.0 * PI / max(lambda, 0.001);
|
||
|
|
float phase = dot(dir, obj_xz) * k - spd * t;
|
||
|
|
float A = amp;
|
||
|
|
float Q = clamp(steep, 0.0, 1.0);
|
||
|
|
float c = cos(phase);
|
||
|
|
float s = sin(phase);
|
||
|
|
vec2 disp_xz = dir * (Q * A * c);
|
||
|
|
float disp_y = A * s;
|
||
|
|
return vec3(disp_xz.x, disp_y, disp_xz.y);
|
||
|
|
}
|
||
|
|
|
||
|
|
void vertex() {
|
||
|
|
float t = TIME * time_scale;
|
||
|
|
|
||
|
|
// Use local/object-space XZ for the wave phase (no world matrix needed)
|
||
|
|
vec2 obj_xz = VERTEX.xz;
|
||
|
|
|
||
|
|
vec3 d1 = gerstner_obj(obj_xz, wave1_dir, wave1_amp, wave1_len, wave1_steep, wave1_speed, t);
|
||
|
|
vec3 d2 = gerstner_obj(obj_xz, wave2_dir, wave2_amp, wave2_len, wave2_steep, wave2_speed, t);
|
||
|
|
vec3 disp = d1 + d2;
|
||
|
|
|
||
|
|
VERTEX += disp;
|
||
|
|
|
||
|
|
// Quick procedural normal (only matters if you later use lit shading)
|
||
|
|
vec2 eps = vec2(0.05, 0.0);
|
||
|
|
float h = (gerstner_obj(obj_xz, wave1_dir, wave1_amp, wave1_len, wave1_steep, wave1_speed, t).y
|
||
|
|
+ gerstner_obj(obj_xz, wave2_dir, wave2_amp, wave2_len, wave2_steep, wave2_speed, t).y);
|
||
|
|
float hx = (gerstner_obj(obj_xz + vec2(eps.x,0), wave1_dir, wave1_amp, wave1_len, wave1_steep, wave1_speed, t).y
|
||
|
|
+ gerstner_obj(obj_xz + vec2(eps.x,0), wave2_dir, wave2_amp, wave2_len, wave2_steep, wave2_speed, t).y);
|
||
|
|
float hz = (gerstner_obj(obj_xz + vec2(0,eps.x), wave1_dir, wave1_amp, wave1_len, wave1_steep, wave1_speed, t).y
|
||
|
|
+ gerstner_obj(obj_xz + vec2(0,eps.x), wave2_dir, wave2_amp, wave2_len, wave2_steep, wave2_speed, t).y);
|
||
|
|
|
||
|
|
vec3 dx = vec3(eps.x, hx - h, 0.0);
|
||
|
|
vec3 dz = vec3(0.0, hz - h, eps.x);
|
||
|
|
NORMAL = normalize(cross(dz, dx));
|
||
|
|
}
|
||
|
|
|
||
|
|
void fragment() {
|
||
|
|
// Keep your 2D-water look
|
||
|
|
vec2 p = (2.0 * UV - R) / R.y;
|
||
|
|
|
||
|
|
float shape = fbm(vec3(p * scale, 0.0));
|
||
|
|
float gradient = fract(shape * layers);
|
||
|
|
float shade = round(pow(gradient, 4.0) * shades) / shades;
|
||
|
|
|
||
|
|
vec3 color = mix(tint * mix(0.6, 0.8, gradient), vec3(1.0), shade);
|
||
|
|
|
||
|
|
ALBEDO = color;
|
||
|
|
EMISSION = color;
|
||
|
|
ALPHA = 1.0;
|
||
|
|
}
|