Add Simplex noise functions and integrate noise-based displacement for enhanced wave detail
This commit is contained in:
129
index.html
129
index.html
@@ -392,6 +392,73 @@
|
||||
varying float v_foamFactor;
|
||||
varying float v_distanceFade;
|
||||
|
||||
// ============ Simplex Noise Functions ============
|
||||
// Permutation polynomial: (34x^2 + x) mod 289
|
||||
vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
|
||||
|
||||
// 2D Simplex noise
|
||||
float snoise(vec2 v) {
|
||||
const vec4 C = vec4(0.211324865405187, 0.366025403784439,
|
||||
-0.577350269189626, 0.024390243902439);
|
||||
vec2 i = floor(v + dot(v, C.yy));
|
||||
vec2 x0 = v - i + dot(i, C.xx);
|
||||
vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
||||
vec4 x12 = x0.xyxy + C.xxzz;
|
||||
x12.xy -= i1;
|
||||
i = mod(i, 289.0);
|
||||
vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
|
||||
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
|
||||
m = m*m; m = m*m;
|
||||
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
||||
vec3 h = abs(x) - 0.5;
|
||||
vec3 ox = floor(x + 0.5);
|
||||
vec3 a0 = x - ox;
|
||||
m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
|
||||
vec3 g;
|
||||
g.x = a0.x * x0.x + h.x * x0.y;
|
||||
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
||||
return 130.0 * dot(m, g);
|
||||
}
|
||||
|
||||
// Fractal Brownian Motion (FBM) using simplex noise
|
||||
float fbm(vec2 p, float time, int octaves, float lacunarity, float gain) {
|
||||
float sum = 0.0;
|
||||
float amp = 1.0;
|
||||
float freq = 1.0;
|
||||
float maxAmp = 0.0;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (i >= octaves) break;
|
||||
// Add subtle animation
|
||||
vec2 animatedP = p * freq + vec2(time * 0.5 * float(i + 1), time * 0.3);
|
||||
sum += snoise(animatedP) * amp;
|
||||
maxAmp += amp;
|
||||
amp *= gain;
|
||||
freq *= lacunarity;
|
||||
}
|
||||
|
||||
return sum / maxAmp;
|
||||
}
|
||||
|
||||
// Get noise-based displacement and normal contribution
|
||||
vec3 noiseWave(vec2 pos, float time, float scale, float amplitude, out vec3 normalContrib) {
|
||||
vec2 p = pos * scale;
|
||||
|
||||
// Sample noise at offset positions for gradient/normal calculation
|
||||
float eps = 0.1;
|
||||
float h = fbm(p, time, 4, 2.0, 0.5) * amplitude;
|
||||
float hx = fbm(p + vec2(eps, 0.0), time, 4, 2.0, 0.5) * amplitude;
|
||||
float hy = fbm(p + vec2(0.0, eps), time, 4, 2.0, 0.5) * amplitude;
|
||||
|
||||
// Calculate normal from height differences
|
||||
vec3 tangent = normalize(vec3(eps, 0.0, hx - h));
|
||||
vec3 binormal = normalize(vec3(0.0, eps, hy - h));
|
||||
normalContrib = normalize(cross(binormal, tangent));
|
||||
|
||||
return vec3(0.0, h, 0.0); // Only vertical displacement for noise
|
||||
}
|
||||
|
||||
// ============ Gerstner Wave Function ============
|
||||
// Gerstner wave function - higher steepness = spikier waves
|
||||
vec3 gerstnerWave(vec2 pos, float time, vec2 direction, float steepness, float wavelength, out vec3 tangent, out vec3 binormal) {
|
||||
float k = 2.0 * 3.14159 / wavelength;
|
||||
@@ -515,49 +582,47 @@
|
||||
vec3 binormal = vec3(0.0, 0.0, 1.0);
|
||||
vec3 t, b;
|
||||
|
||||
// === Large primary waves ===
|
||||
displacement += gerstnerWave(pos, time, vec2(1.0, 0.2), 0.42 * heightMod, 6.0, t, b);
|
||||
// ============ GERSTNER WAVES - Large Scale Motion ============
|
||||
// Primary ocean swells
|
||||
displacement += gerstnerWave(pos, time, vec2(1.0, 0.2), 0.45 * heightMod, 8.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 1.1, vec2(0.4, 1.0), 0.35 * heightMod, 5.0, t, b);
|
||||
displacement += gerstnerWave(pos, time * 1.1, vec2(0.4, 1.0), 0.38 * heightMod, 6.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// === Medium waves ===
|
||||
displacement += gerstnerWave(pos, time * 0.9, vec2(-0.6, 0.8), 0.25 * heightMod, 3.0, t, b);
|
||||
// Secondary waves
|
||||
displacement += gerstnerWave(pos, time * 0.9, vec2(-0.6, 0.8), 0.28 * heightMod, 4.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 1.2, vec2(0.8, -0.5), 0.2 * heightMod, 2.2, t, b);
|
||||
displacement += gerstnerWave(pos, time * 1.15, vec2(0.8, -0.5), 0.22 * heightMod, 3.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time, vec2(-0.3, -0.9), 0.18 * heightMod, 1.8, t, b);
|
||||
// Medium waves
|
||||
displacement += gerstnerWave(pos, time, vec2(-0.3, -0.9), 0.18 * heightMod, 2.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// === Small detail waves ===
|
||||
displacement += gerstnerWave(pos, time * 1.2, vec2(0.9, -0.4), 0.12 * heightMod, 1.2, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
// ============ PERLIN/SIMPLEX NOISE - Small Scale Detail ============
|
||||
// Only apply noise detail when close enough to see it
|
||||
float detailFade = smoothstep(200.0, 50.0, distToCamera);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 0.9, vec2(-0.5, -0.7), 0.10 * heightMod, 1.0, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 1.3, vec2(0.3, 0.95), 0.08 * heightMod, 0.8, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// === Tiny ripples ===
|
||||
displacement += gerstnerWave(pos, time * 2.0, vec2(0.9, 0.1), 0.05 * heightMod, 0.35, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 2.2, vec2(-0.2, 0.95), 0.04 * heightMod, 0.25, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// === Micro ripples for fine surface detail ===
|
||||
displacement += gerstnerWave(pos, time * 2.5, vec2(0.7, -0.7), 0.03 * heightMod, 0.18, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 3.0, vec2(-0.8, 0.6), 0.025 * heightMod, 0.12, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
|
||||
displacement += gerstnerWave(pos, time * 3.5, vec2(0.5, -0.9), 0.02 * heightMod, 0.08, t, b);
|
||||
tangent += t - vec3(1.0, 0.0, 0.0); binormal += b - vec3(0.0, 0.0, 1.0);
|
||||
if (detailFade > 0.01) {
|
||||
vec3 noiseNormal;
|
||||
|
||||
// Medium frequency noise ripples
|
||||
vec3 noise1 = noiseWave(pos, time * 0.8, 0.3, 0.15 * heightMod * detailFade, noiseNormal);
|
||||
displacement += noise1;
|
||||
tangent += (noiseNormal - vec3(0.0, 0.0, 1.0)) * 0.3 * detailFade;
|
||||
|
||||
// High frequency noise for fine detail
|
||||
vec3 noise2 = noiseWave(pos, time * 1.2, 0.8, 0.08 * heightMod * detailFade, noiseNormal);
|
||||
displacement += noise2;
|
||||
tangent += (noiseNormal - vec3(0.0, 0.0, 1.0)) * 0.2 * detailFade;
|
||||
|
||||
// Very fine ripples
|
||||
vec3 noise3 = noiseWave(pos, time * 1.5, 2.0, 0.04 * heightMod * detailFade, noiseNormal);
|
||||
displacement += noise3;
|
||||
tangent += (noiseNormal - vec3(0.0, 0.0, 1.0)) * 0.1 * detailFade;
|
||||
}
|
||||
|
||||
// Store wave height for fragment shader
|
||||
v_waveHeight = displacement.y;
|
||||
|
||||
Reference in New Issue
Block a user