@yali-engine/water 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,6 @@ export declare const waterWaves: {
5
5
  };
6
6
  /** Linked from shaders/water/surface.wesl. */
7
7
  export declare const waterSurface: {
8
- readonly hash: "0d0f44afc28096f2";
9
- readonly wgsl: "const PI = 3.14159265;\nconst EARTH_RADIUS = 6371000.0;\nconst MAX_CASCADES = 4u;\nstruct SurfaceParams {\ncascade: array<vec4f, MAX_CASCADES>,\ngrid: vec4f,\nsea: vec4f,\nbody: vec4f,\nsss: vec4f,\nsize: vec4f,\noptics: vec4f,\nshore: vec4f,\nmirror: vec4f,\nsurf0: vec4f,\nsurf1: vec4f,\nsurf2: vec4f,\nsurf3: vec4f,\n}\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lighting: Lighting;\n@group(0) @binding(2) var<uniform> sp: SurfaceParams;\n@group(0) @binding(3) var displacement: texture_2d_array<f32>;\n@group(0) @binding(4) var slopes: texture_2d_array<f32>;\n@group(0) @binding(5) var wrap: sampler;\n@group(0) @binding(6) var env_cube: texture_cube<f32>;\n@group(0) @binding(7) var under: texture_2d<f32>;\n@group(0) @binding(8) var under_depth: texture_2d<f32>;\n@group(0) @binding(9) var clamp_smp: sampler;\n@group(0) @binding(10) var scene_depth: texture_depth_2d;\n@group(0) @binding(11) var depth_out: texture_storage_2d<r32float, write>;\nstruct WaterMotion {\nview_proj: mat4x4f,\nprev_view_proj: mat4x4f,\neye_move: vec4f,\n}\n@group(0) @binding(12) var prev_displacement: texture_2d_array<f32>;\n@group(0) @binding(13) var<uniform> wm: WaterMotion;\n@group(0) @binding(14) var shore_map: texture_2d<f32>;\n@group(0) @binding(15) var spill_map: texture_2d<f32>;\n@group(0) @binding(16) var cloud_pano: texture_2d<f32>;\nstruct Surf {\nd: vec3f,\nslope: vec2f,\nbroken: f32,\nfoam: f32,\nfade: f32,\nground: f32,\nreach: f32,\ncover: f32,\nwet: f32,\nfilm: f32,\nfront: f32,\nface: f32,\namp: f32,\nworld: vec2f,\ndir: vec2f,\nphase: f32,\nonset: f32,\nfresh: f32,\nfront_h: f32,\nwet_h1: f32,\nwet_h2: f32,\nrun: f32,\n}\nfn pcg(v: u32) -> u32 {\nlet state = v * 747796405u + 2891336453u;\nlet word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\nreturn (word >> 22u) ^ word;\n}\nfn hash1(n: f32) -> f32 {\nreturn f32(pcg(bitcast<u32>(i32(n)))) / 4294967296.0;\n}\nfn hash2(p: vec2f) -> f32 {\nlet q = vec2<i32>(p);\nreturn f32(pcg(bitcast<u32>(q.x) ^ pcg(bitcast<u32>(q.y) + 0x9e3779b9u))) / 4294967296.0;\n}\nfn vnoise(p: vec2f) -> f32 {\nlet i = floor(p);\nlet f = fract(p);\nlet u = f * f * (3.0 - 2.0 * f);\nreturn mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x), mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn worley(p: vec2f) -> vec2f {\nlet i = floor(p);\nlet f = fract(p);\nvar d1 = 8.0;\nvar d2 = 8.0;\nfor (var y = -1; y <= 1; y++) {\nfor (var x = -1; x <= 1; x++) {\nlet o = vec2f(f32(x), f32(y));\nlet c = i + o;\nlet j = vec2f(hash2(c), hash2(c + vec2f(1013.0, 7919.0)));\nlet d = length(o + j - f) / (0.55 + 0.9 * hash2(c + vec2f(4241.0, 557.0)));\nif (d < d1) {\nd2 = d1;\nd1 = d;\n} else if (d < d2) {\nd2 = d;\n}\n}\n}\nreturn vec2f(d1, d2);\n}\nfn foam_net(p: vec2f, amount: f32, fw: f32) -> vec2f {\nlet a = saturate(amount);\nlet q = p + vec2f(vnoise(p * 2.0), vnoise(p * 2.0 + vec2f(5.2, 1.3))) * 0.36;\nlet big = worley(q * 3.2);\nvar small = vec2f(0.5, 1.0);\nif (sp.size.w > 1.5) {\nsmall = worley(q * 10.0 + vec2f(3.7, 1.9));\n}\nlet r = mix(0.82, 0.12, pow(a, 1.1));\nlet eb = fw * 3.2;\nlet es = fw * 10.0;\nlet mean = saturate(1.0 - 2.6 * r * r);\nlet hb = mix(smoothstep(r - 0.05 - eb, r + 0.05 + eb, big.x), mean, smoothstep(0.15, 0.6, eb));\nlet rs = r * 0.8 + 0.1;\nlet hs = mix(smoothstep(rs - 0.06 - es, rs + 0.06 + es, small.x), saturate(1.0 - 2.6 * rs * rs), smoothstep(0.15, 0.6, es));\nlet net = hb * mix(1.0, hs, 0.55 * (1.0 - a));\nlet cover = net * smoothstep(0.0, 0.06, a);\nlet lumps = mix(0.8, 1.04, saturate(1.0 - small.x * 0.9)) * mix(0.9, 1.0, saturate(1.0 - big.x * 0.8));\nlet light = mix(lumps, 0.92, smoothstep(0.15, 0.6, es));\nreturn vec2f(cover, light);\n}\nstruct Train {\nth: f32,\nu: f32,\nnw: f32,\namp: f32,\nshoaled: f32,\nperiod: f32,\nblend: f32,\n}\nconst TRAINS = array<vec4f, 3>(vec4f(1.0, 1.0, 0.0, 0.0), vec4f(1.37, 0.45, 0.0, 0.31), vec4f(0.79, 0.3, 0.0, 0.67));\nfn wobble(n: f32, i: u32, world: vec2f) -> f32 {\nlet o = vec2f(n * 0.61 + f32(i) * 7.0, n * 0.37 + f32(i) * 3.0);\nreturn ((vnoise(world / 45.0 + o) - 0.5) * 1.2 + (vnoise(world / 14.0 + o * 1.7) - 0.5) * 0.35) * sp.surf3.y;\n}\nfn wave_amp(n: f32, world: vec2f) -> f32 {\nlet group = 1.0 + 0.3 * sin(2.0 * PI * n / 6.3 + 1.3) + 0.25 * (hash1(n) - 0.5);\nlet section = 0.6 + 0.8 * vnoise(world / 28.0 + vec2f(n * 7.13, n * 3.71));\nreturn mix(1.0, group * section, sp.surf3.y);\n}\nfn swash_front(u: f32, run: f32) -> f32 {\nlet rise = 0.18;\nlet up = 1.0 - (1.0 - saturate(u / rise)) * (1.0 - saturate(u / rise));\nlet down = pow(saturate(1.0 - (u - rise) / 0.57), 1.6);\nreturn run * select(down, up, u < rise);\n}\nfn swash_high(u: f32, run: f32, window: f32) -> f32 {\nlet rise = 0.18;\nlet u0 = u - window;\nif (u0 >= rise) {\nreturn swash_front(u0, run);\n}\nif (u >= rise) {\nreturn run;\n}\nreturn max(swash_front(u, run), select(0.0, swash_front(u0 + 1.0, run), u0 < 0.0));\n}\nfn swash_state(e: f32, front_h: f32, wet_h1: f32, wet_h2: f32, run: f32) -> vec4f {\nlet cover = saturate((front_h - e) / 0.03);\nlet r1 = saturate((wet_h1 - e) / 0.06 + 0.4);\nlet r2 = saturate((wet_h2 - e) / 0.12 + 0.4);\nlet damp = 0.3 * saturate(1.0 - e / max(run, 1e-3));\nlet wet = max(0.75 * (0.55 * r1 + 0.45 * r2), damp) * saturate((run - e) / 0.08 + 0.5);\nlet film = 0.02 + 0.04 * cover * saturate((front_h - e) / 0.15);\nlet front = cover * (1.0 - saturate((front_h - e) / 0.015)) * saturate(front_h * 6.0);\nreturn vec4f(cover, wet, film, front);\n}\nfn surf_at(rest: vec2f, time: f32) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet sp2 = textureSampleLevel(spill_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\nlet period = sp.surf1.y;\ns.world = uv / sp.surf0.z;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\nlet hs = max(depth, 0.15);\nlet start = sp.surf2.z;\nlet shoal = pow(start / hs, 0.25) * smoothstep(start, start * 0.6, depth);\nlet dir = vec2f(cos(f.w), sin(f.w));\ns.dir = dir;\nvar tr: array<Train, 3>;\nlet trains = select(1u, 3u, sp.size.w > 0.5);\nfor (var i = 0u; i < trains; i++) {\nlet ti = TRAINS[i];\nlet pi = period * ti.x;\nvar th: f32;\nvar u: f32;\nvar nw: f32;\nif (i == 0u) {\nth = 2.0 * PI * fract(time / period) - atan2(f.z, f.y);\nu = fract(th / (2.0 * PI));\nnw = round((time - sp2.y) / period + 0.5 - fract(u + 0.5));\n} else {\nlet cyc = (time - sp2.y) / pi + ti.w;\nu = fract(cyc);\nth = 2.0 * PI * u;\nnw = round(cyc + 0.5 - fract(u + 0.5));\n}\nlet ff = fract(u + 0.5);\nlet blend = smoothstep(0.82, 1.0, ff);\nvar amp = wave_amp(nw + f32(i) * 101.0, s.world);\nvar wob = wobble(nw, i, s.world);\nif (blend > 0.0) {\namp = mix(amp, wave_amp(nw + 1.0 + f32(i) * 101.0, s.world), blend);\nwob = mix(wob, wobble(nw + 1.0, i, s.world), blend);\n}\nth -= wob;\ntr[i].th = th;\ntr[i].u = fract(th / (2.0 * PI));\ntr[i].nw = nw;\ntr[i].amp = amp;\ntr[i].shoaled = sp.surf1.x * ti.y * amp * shoal;\ntr[i].blend = blend;\ntr[i].period = pi;\n}\nlet gnoise = mix(vnoise(s.world / 35.0 + vec2f(tr[0].nw * 2.3, 0.0)), vnoise(s.world / 35.0 + vec2f((tr[0].nw + 1.0) * 2.3, 0.0)), tr[0].blend);\nlet gamma = sp.surf1.z * (0.85 + 0.3 * gnoise * sp.surf3.y + 0.15 * (1.0 - sp.surf3.y));\nlet hb = gamma * hs;\nvar eta = 0.0;\nvar lean = vec2f(0.0);\nvar slope = 0.0;\nvar face_k = 0.0;\nvar foam = 0.0;\ns.broken = 0.0;\ns.onset = 0.0;\nfor (var i = 0u; i < trains; i++) {\nvar others = 0.0;\nfor (var j = 0u; j < trains; j++) {\nif (j != i) {\nothers += 0.4 * tr[j].shoaled * (0.5 + 0.5 * cos(tr[j].th));\n}\n}\nlet ratio = (tr[i].shoaled + others) / max(hb, 1e-3);\nlet broken = saturate((ratio - 1.0) * 3.0);\nlet share = tr[i].shoaled / max(tr[i].shoaled + others, 1e-4);\nlet H = min(tr[i].shoaled, hb * share + tr[i].shoaled * (1.0 - broken)) * smoothstep(-0.05, 0.25, depth);\nlet th = tr[i].th;\nlet u = tr[i].u;\nlet wn = mix(vnoise(s.world / 22.0 + vec2f(tr[i].nw * 5.1, f32(i) * 9.0)), vnoise(s.world / 22.0 + vec2f((tr[i].nw + 1.0) * 5.1, f32(i) * 9.0)), tr[i].blend);\nlet w = 0.12 * mix(1.0, 0.6 + 0.8 * wn, sp.surf3.y);\nlet stokes = 0.5 * (cos(th) + 0.3 * cos(2.0 * th));\nlet dstokes = 0.5 * (-sin(th) - 0.6 * sin(2.0 * th));\nlet bore = select(1.0 - (u - w) / (1.0 - w), u / w, u < w) - 0.5;\nlet dw = min(0.6 * w, 1.2 / (tr[i].period * sqrt(9.81 * hs)));\nlet rise = saturate(0.5 + u / dw) * saturate(0.5 - (u - w) / dw) + saturate(0.5 + (u - 1.0) / dw);\nlet dbore = (-1.0 / (1.0 - w) + (1.0 / w + 1.0 / (1.0 - w)) * rise) / (2.0 * PI);\nvar e = H * mix(stokes, bore, broken);\nlet de = H * mix(dstokes, dbore, broken);\nlet q = sp.surf1.w * (1.0 - 0.6 * broken);\nvar l = dir * (q * H * 0.5 * sin(th));\nlet onset = broken * (1.0 - broken) * 4.0 * saturate((ratio - 0.9) * 10.0);\nlet top = smoothstep(0.1, 0.5, e / max(H, 1e-3));\nl += dir * (sp.surf3.z * H * 0.55 * onset * top);\ne *= 1.0 + 0.25 * onset * top;\nlet k = 2.0 * PI / (tr[i].period * sqrt(9.81 * hs));\neta += e;\nlean += l;\nslope += -k * de;\nface_k += smoothstep(-0.2, 0.45, e / max(H, 1e-3)) * saturate(H * 1.2) * (1.0 - 0.65 * broken + 0.5 * onset) * TRAINS[i].y;\nlet fo = broken * smoothstep(0.0, w, u) * (exp(-(u - w) * 9.0) + 0.15 * exp(-(u - w) * 3.0)) * saturate(H * 3.0) * TRAINS[i].y;\nfoam = 1.0 - (1.0 - foam) * (1.0 - fo);\ns.broken = max(s.broken, broken);\ns.onset = max(s.onset, onset * TRAINS[i].y);\n}\ns.slope = slope * dir;\ns.d = vec3f(lean.x, eta, lean.y);\ns.face = saturate(-slope * 1.5) * saturate(face_k);\ns.foam = foam;\nlet u = tr[0].u;\ns.phase = u;\ns.amp = tr[0].amp;\ns.ground = -depth;\ns.reach = max(sp2.x, s.ground);\nif (s.ground > -0.05) {\nlet e = s.reach;\nlet rn = mix(vnoise(s.world / 9.0 + vec2f(tr[0].nw * 3.3, 1.0)), vnoise(s.world / 9.0 + vec2f((tr[0].nw + 1.0) * 3.3, 1.0)), tr[0].blend);\nlet run = sp.surf1.x * s.amp * 0.8 * mix(1.0, 0.7 + 0.6 * rn, sp.surf3.y);\ns.run = run;\ns.front_h = swash_front(u, run);\ns.wet_h1 = swash_high(u, run, 1.5 / sp.surf1.y);\ns.wet_h2 = swash_high(u, run, 4.0 / sp.surf1.y);\nlet w = swash_state(e, s.front_h, s.wet_h1, s.wet_h2, run);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\nreturn s;\n}\nfn on_beach(d: vec3f, s: Surf, spacing: f32) -> vec3f {\nif (s.ground <= 0.0) {\nreturn d;\n}\nlet reach = sp.surf1.x * 0.8 * 2.0 + 0.05;\nlet y = select(s.ground - 1.0, s.ground + s.film + 0.03 + 0.03 * spacing, s.reach < reach);\nlet k = smoothstep(0.0, 0.04, s.ground);\nreturn vec3f(d.x * (1.0 - k), mix(d.y, y, k), d.z * (1.0 - k));\n}\n@group(0) @binding(17) var surf_a: texture_2d<f32>;\n@group(0) @binding(18) var surf_b: texture_2d<f32>;\n@group(0) @binding(19) var surf_c: texture_2d<f32>;\n@group(0) @binding(20) var surf_d: texture_2d<f32>;\n@group(0) @binding(21) var surf_a_prev: texture_2d<f32>;\n@group(0) @binding(22) var surf_d_prev: texture_2d<f32>;\n@group(0) @binding(23) var out_a: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(24) var out_b: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(25) var out_c: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(26) var out_d: texture_storage_2d<rgba16float, write>;\n@compute @workgroup_size(8, 8) fn surf_field(@builtin(global_invocation_id) id: vec3u) {\nlet n = textureDimensions(out_a);\nif (any(id.xy >= n)) {\nreturn;\n}\nlet uv = (vec2f(id.xy) + 0.5) / vec2f(n);\nlet rest = (uv - sp.surf0.xy) / sp.surf0.z;\nlet s = surf_at(rest, sp.surf3.x);\ntextureStore(out_a, vec2i(id.xy), vec4f(s.d, s.broken));\ntextureStore(out_b, vec2i(id.xy), vec4f(s.slope, s.face, s.onset));\ntextureStore(out_c, vec2i(id.xy), vec4f(s.foam, s.front_h, s.wet_h1, s.wet_h2));\nlet dt = clamp(sp.surf3.x - sp.surf3.w, 0.0, 0.1);\nlet v = surf_flow(s);\nlet extent = 1.0 / sp.surf0.z;\nlet back = uv - v * dt / extent;\nlet texel = 1.0 / vec2f(n);\nlet f0 = textureSampleLevel(surf_d_prev, clamp_smp, back, 0.0).w;\nlet fs = textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(0.0, texel.y), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(0.0, texel.y), 0.0).w;\nlet carried = mix(f0, fs * 0.25, 0.12 * saturate(dt * 60.0));\nlet life = mix(3.0, 1.2, saturate(carried));\nvar f = carried * exp(-dt / life) * select(1.0, 0.0, s.ground > 0.0 && s.cover < 0.01 && s.wet < 0.05) * select(0.0, 1.0, dt > 0.0);\nf = max(f, saturate(s.foam * 0.9 + s.front * 0.8));\ntextureStore(out_d, vec2i(id.xy), vec4f(s.run, s.phase, s.amp, f));\n}\nfn smooth_sample(t: texture_2d<f32>, uv: vec2f) -> vec4f {\nlet size = vec2f(textureDimensions(t));\nlet p = uv * size - 0.5;\nlet i = floor(p);\nlet f = p - i;\nlet w0 = (1.0 - f) * (1.0 - f) * (1.0 - f) / 6.0;\nlet w1 = (4.0 - 6.0 * f * f + 3.0 * f * f * f) / 6.0;\nlet w2 = (1.0 + 3.0 * f + 3.0 * f * f - 3.0 * f * f * f) / 6.0;\nlet w3 = f * f * f / 6.0;\nlet g0 = w0 + w1;\nlet g1 = w2 + w3;\nlet h0 = (i - 0.5 + w1 / g0) / size;\nlet h1 = (i + 1.5 + w3 / g1) / size;\nlet a = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h0.y), 0.0);\nlet b = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h0.y), 0.0);\nlet c = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h1.y), 0.0);\nlet d = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h1.y), 0.0);\nreturn mix(mix(a, b, g1.x), mix(c, d, g1.x), g1.y);\n}\nfn surf_tex(rest: vec2f, prev: bool) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\ns.dir = vec2f(cos(f.w), sin(f.w));\ns.world = uv / sp.surf0.z;\ns.ground = -depth;\ns.reach = max(textureSampleLevel(spill_map, clamp_smp, uv, 0.0).x, s.ground);\nlet a = select(textureSampleLevel(surf_a, clamp_smp, uv, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv, 0.0), prev);\ns.d = a.xyz;\ns.broken = a.w;\nlet b = textureSampleLevel(surf_b, clamp_smp, uv, 0.0);\ns.slope = b.xy;\ns.face = b.z;\ns.onset = b.w;\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nif (s.ground > -0.05) {\nlet e = max(smooth_sample(spill_map, uv).x, -smooth_sample(shore_map, uv).x);\nlet w = swash_state(e, c.y, c.z, c.w, dd.x);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\ns.front_h = c.y;\ns.run = dd.x;\ns.phase = dd.y;\ns.amp = dd.z;\ns.fresh = c.x;\ns.foam = max(c.x, dd.w);\nreturn s;\n}\nfn surf_disp(rest: vec2f, spacing: f32, prev: bool) -> vec3f {\nif (sp.surf0.w < 0.5) {\nreturn vec3f(0.0);\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec3f(0.0);\n}\nlet r = 0.35 * spacing * sp.surf0.z;\nvar d = vec3f(0.0);\nfor (var k = 0u; k < 5u; k++) {\nlet o = array<vec2f, 5>(vec2f(0.0), vec2f(r, 0.0), vec2f(-r, 0.0), vec2f(0.0, r), vec2f(0.0, -r))[k];\nlet w = select(0.125, 0.5, k == 0u);\nlet t = select(textureSampleLevel(surf_a, clamp_smp, uv + o, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv + o, 0.0), prev);\nd += t.xyz * w;\n}\nreturn d;\n}\nfn surf_flow(s: Surf) -> vec2f {\nlet hs = max(-s.ground, 0.15);\nif (s.ground > -0.05) {\nreturn s.dir * select(-0.9, 1.6, s.phase < 0.18) * s.cover;\n}\nreturn s.dir * clamp(sqrt(9.81 * hs) * max(s.d.y, 0.0) / hs, 0.0, 3.0);\n}\nconst SPRAY_SIDE = 192u;\nconst SPRAY_SPACING = 0.75;\nstruct SprayOut {\n@builtin(position) clip: vec4f,\n@location(0) q: vec4f,\n@location(1) p: vec3f,\n}\n@vertex fn vs_spray(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> SprayOut {\nvar o: SprayOut;\no.clip = vec4f(0.0, 0.0, -1.0, 1.0);\nif (sp.surf0.w < 0.5 || sp.size.y <= 0.0) {\nreturn o;\n}\nlet extent = 1.0 / sp.surf0.z;\nlet eye = sp.surf0.xy * extent;\nlet gx = f32(ii % SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet gz = f32(ii / SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet cell = floor(eye / SPRAY_SPACING) + vec2f(gx, gz);\nlet j = vec2f(hash2(cell), hash2(cell + vec2f(91.0, 37.0)));\nlet rest = (cell + j) * SPRAY_SPACING - eye;\nvar s = surf_tex(rest, false);\nlet tuv = sp.surf0.xy + rest * sp.surf0.z;\ns.phase = textureLoad(surf_d, vec2i(clamp(tuv, vec2f(0.0), vec2f(0.9999)) * vec2f(textureDimensions(surf_d))), 0).y;\nlet age = (s.phase - 0.12) * sp.surf1.y;\nlet life = 0.6 + 0.6 * hash2(cell + vec2f(13.0, 71.0));\nif (s.broken < 0.05 || age < 0.0 || age > life || s.ground > 0.3) {\nreturn o;\n}\nlet H = sp.surf1.x * s.amp;\nlet strength = (0.05 * s.broken + s.onset) * saturate(H * 1.2) * (0.4 + 1.2 * hash2(cell + vec2f(5.0, 3.0)));\nlet v0 = (2.0 + 3.0 * hash2(cell + vec2f(2.0, 9.0))) * saturate(H);\nlet k = 1.8;\nlet rise = v0 / k * (1.0 - exp(-k * age)) - 4.0 * age * age * 0.5;\nlet fwd = s.dir * (1.2 * (1.0 - exp(-1.5 * age)));\nlet base = s.d.y + 0.15;\nlet centre = vec3f(rest.x + fwd.x, sp.sea.x + base + max(rise, 0.0), rest.y + fwd.y);\nlet t = age / life;\nlet size = (0.12 + 0.5 * t) * (0.7 + 0.6 * hash2(cell + vec2f(17.0, 23.0))) * (0.6 + 0.6 * saturate(H));\nlet corner = array<vec2f, 6>(vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0))[vi];\nlet fwdv = normalize(centre);\nlet right = normalize(cross(vec3f(0.0, 1.0, 0.0), fwdv));\nlet up = cross(fwdv, right);\nlet pos = centre + (right * corner.x + up * corner.y) * size;\no.clip = camera.view_proj * vec4f(pos, 1.0);\nlet alpha = strength * smoothstep(0.0, 0.1, t) * (1.0 - smoothstep(0.4, 1.0, t)) * sp.size.y * 0.32;\no.q = vec4f(corner, alpha, length(centre));\no.p = centre;\nreturn o;\n}\n@fragment fn fs_spray(in: SprayOut) -> @location(0) vec4f {\nlet r2 = dot(in.q.xy, in.q.xy);\nif (r2 > 1.0) {\ndiscard;\n}\nlet wisp = vnoise(in.q.xy * 1.8 + in.p.xz * 3.1) * 0.6 + vnoise(in.q.xy * 4.3 + in.p.xz * 1.7) * 0.4;\nvar a = in.q.z * (1.0 - r2) * (1.0 - r2) * smoothstep(0.38, 0.62, wisp) * 1.6;\nlet d = textureLoad(under_depth, vec2i(in.clip.xy), 0).x;\nif (d > 0.0) {\nlet gap = in.q.w * (in.clip.z / d - 1.0);\na *= saturate(gap / 0.5);\n}\nlet v = normalize(in.p);\nlet l = camera.light_dir.xyz;\nlet g = 0.75;\nlet cosv = dot(v, l);\nlet hg = (1.0 - g * g) / (4.0 * PI * pow(1.0 + g * g - 2.0 * g * cosv, 1.5));\nlet light = sh_irradiance(vec3f(0.0, 1.0, 0.0)) * 0.6 + lighting.sun_color.rgb * (hg * 3.0 + 0.05);\nlet fogged = apply_fog(light, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(v), lighting.sun_color.rgb, l);\nreturn vec4f(fogged * lighting.env.z * a, a);\n}\nstruct VsOut {\n@builtin(position) clip: vec4f,\n@location(0) p: vec3f,\n@location(1) rest: vec2f,\n@location(2) height: f32,\n}\nfn ring_radius(i: f32) -> f32 {\nlet k = sp.grid.y;\nreturn sp.grid.x * (pow(1.0 + k, i) - 1.0) / k;\n}\nfn grid_point(vi: u32) -> vec3f {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nreturn vec3f(vec2f(cos(a), sin(a)) * r, max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs)));\n}\nfn calm(c: u32, fade: f32) -> f32 {\nreturn mix(1.0, fade, saturate(1.0 / (sp.cascade[c].z * 150.0)));\n}\nfn displaced(field: texture_2d_array<f32>, rest: vec2f, spacing: f32, fade: f32) -> vec3f {\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(field, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nreturn d;\n}\nstruct MotionOut {\n@builtin(position) clip: vec4f,\n@location(0) now: vec4f,\n@location(1) then: vec4f,\n}\n@vertex fn vs_motion(@builtin(vertex_index) vi: u32) -> MotionOut {\nlet g = grid_point(vi);\nlet rest = g.xy;\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet sn = surf_tex(rest, false);\nlet sq = surf_tex(rest, wm.eye_move.w > 0.5);\nlet dn = on_beach(displaced(displacement, rest, g.z, sn.fade) + surf_disp(rest, g.z, false), sn, g.z);\nlet dp = select(dn, on_beach(displaced(prev_displacement, rest, g.z, sq.fade) + surf_disp(rest, g.z, true), sq, g.z), wm.eye_move.w > 0.5);\nlet p = vec3f(rest.x + dn.x, sp.sea.x + dn.y - drop, rest.y + dn.z);\nlet q = vec3f(rest.x + dp.x, sp.sea.x + dp.y - drop, rest.y + dp.z) + wm.eye_move.xyz;\nvar o: MotionOut;\no.now = wm.view_proj * vec4f(p, 1.0);\no.clip = camera.view_proj * vec4f(p, 1.0);\no.then = wm.prev_view_proj * vec4f(q, 1.0);\nreturn o;\n}\n@fragment fn fs_motion(in: MotionOut) -> @location(0) vec4f {\nlet now = in.now.xy / in.now.w;\nlet then = in.then.xy / max(in.then.w, 1e-6);\nreturn vec4f((now - then) * vec2f(0.5, -0.5), in.then.w, 1.0);\n}\n@vertex fn vs(@builtin(vertex_index) vi: u32) -> VsOut {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nlet rest = vec2f(cos(a), sin(a)) * r;\nlet spacing = max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs));\nlet sf = surf_tex(rest, false);\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, sf.fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(displacement, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nd = on_beach(d + surf_disp(rest, spacing, false), sf, spacing);\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet p = vec3f(rest.x + d.x, sp.sea.x + d.y - drop, rest.y + d.z);\nvar o: VsOut;\no.clip = camera.view_proj * vec4f(p, 1.0);\no.p = p;\no.rest = rest;\no.height = d.y;\nreturn o;\n}\nfn sh_irradiance(n: vec3f) -> vec3f {\nreturn max(lighting.sh[0].rgb * 0.282095 + lighting.sh[1].rgb * (0.488603 * n.y) + lighting.sh[2].rgb * (0.488603 * n.z) + lighting.sh[3].rgb * (0.488603 * n.x) + lighting.sh[4].rgb * (1.092548 * n.x * n.y) + lighting.sh[5].rgb * (1.092548 * n.y * n.z) + lighting.sh[6].rgb * (0.315392 * (3.0 * n.z * n.z - 1.0)) + lighting.sh[7].rgb * (1.092548 * n.x * n.z) + lighting.sh[8].rgb * (0.546274 * (n.x * n.x - n.y * n.y)), vec3f(0.0));\n}\n@compute @workgroup_size(8, 8) fn copy_depth(@builtin(global_invocation_id) id: vec3u) {\nlet size = textureDimensions(scene_depth);\nif (id.x >= size.x || id.y >= size.y) {\nreturn;\n}\ntextureStore(depth_out, vec2i(id.xy), vec4f(textureLoad(scene_depth, vec2i(id.xy), 0), 0.0, 0.0, 0.0));\n}\nfn thickness(dist: f32, ds: f32, dop: f32) -> f32 {\nreturn select(1.0e9, dist * max(ds / dop - 1.0, 0.0), dop > 0.0);\n}\nfn mirror_probe(p: vec3f, r: vec3f, t: f32, size: vec2f) -> vec4f {\nlet c = camera.view_proj * vec4f(p + r * t, 1.0);\nif (c.w <= 0.0) {\nreturn vec4f(0.0);\n}\nlet ndc = c.xyz / c.w;\nlet uv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec4f(0.0);\n}\nlet d = textureLoad(under_depth, vec2i(uv * size), 0).x;\nlet gap = select(-1.0e9, c.w * (1.0 - ndc.z / d), d > 0.0);\nreturn vec4f(uv, gap, 1.0);\n}\nfn mirror_scene(p: vec3f, r: vec3f, size: vec2f, jitter: f32) -> vec4f {\nlet len = sp.mirror.x;\nlet steps = u32(sp.mirror.y);\nif (len <= 0.0 || steps == 0u || sp.shore.y < 0.5 || r.y <= 0.0) {\nreturn vec4f(0.0);\n}\nvar prev = 0.0;\nvar was_behind = false;\nfor (var i = 1u; i <= steps; i++) {\nlet f = (f32(i) - jitter) / f32(steps);\nlet t = len * f * f;\nlet s = mirror_probe(p, r, t, size);\nif (s.w < 0.5) {\nbreak;\n}\nlet behind = s.z > 0.0;\nif (behind && !was_behind) {\nvar a = prev;\nvar b = t;\nvar hit = s;\nfor (var k = 0u; k < 6u; k++) {\nlet m = 0.5 * (a + b);\nlet sm = mirror_probe(p, r, m, size);\nif (sm.w > 0.5 && sm.z > 0.0) {\nb = m;\nhit = sm;\n} else {\na = m;\n}\n}\nif (hit.z < sp.mirror.z + 0.03 * b) {\nlet uv = hit.xy;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nlet fade = saturate(edge * 12.0) * (1.0 - smoothstep(0.7, 1.0, b / len));\nreturn vec4f(textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z, fade);\n}\n}\nwas_behind = behind;\nprev = t;\n}\nreturn vec4f(0.0);\n}\nfn ign(px: vec2f) -> f32 {\nlet frame = floor(camera.light_dir.w * 60.0) % 64.0;\nlet q = px + 5.588238 * frame;\nreturn fract(52.9829189 * fract(dot(q, vec2f(0.06711056, 0.00583715))));\n}\n@fragment fn fs(in: VsOut) -> @location(0) vec4f {\nlet frag = in.clip;\nvar sx = 0.0;\nvar sz = 0.0;\nvar lost = 0.0;\nvar fold = 0.0;\nlet sf = surf_tex(in.rest, false);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet uv = cc.xy + in.rest * cc.z;\nlet texels = length(fwidth(uv)) * sp.size.x;\nlet resolved = 1.0 - smoothstep(0.5, 2.0, texels);\nlet w = resolved * calm(c, sf.fade);\nlet s = textureSampleLevel(slopes, wrap, uv, c, 0.0);\nsx += s.x * w;\nsz += s.y * w;\nlost += cc.w * (1.0 - resolved) * calm(c, sf.fade);\nfold = max(fold, max(saturate((sp.sea.z - s.z) * 2.0), s.w) * w);\n}\nlet fine = u32(sp.sea.y) - 1u;\nfor (var k = 0u; k < 2u; k++) {\nlet scale = select(8.3, 3.1, k == 0u);\nlet amp = select(0.5, 0.7, k == 0u) * sp.shore.w;\nlet ang = select(1.24, 0.65, k == 0u);\nlet rot = mat2x2f(cos(ang), sin(ang), -sin(ang), cos(ang));\nlet q = rot * (sp.cascade[fine].xy + in.rest * sp.cascade[fine].z) * scale + vec2f(0.37, 0.71) * f32(k + 1u);\nlet resolved = 1.0 - smoothstep(0.5, 2.0, length(fwidth(q)) * sp.size.x);\nlet t = textureSampleLevel(slopes, wrap, q, fine, 0.0).xy * amp;\nlet back = transpose(rot) * t;\nsx += back.x * resolved;\nsz += back.y * resolved;\nlost += sp.cascade[fine].w * amp * amp * (1.0 - resolved);\n}\nsx += sf.slope.x;\nsz += sf.slope.y;\nfold *= sf.fade;\nlet n = normalize(vec3f(-sx, 1.0, -sz));\nlet v = normalize(-in.p);\nlet l = camera.light_dir.xyz;\nlet nv = max(dot(n, v), 1e-3);\nlet nl = max(dot(n, l), 0.0);\nlet a2 = max(sp.body.w * sp.body.w + 2.0 * lost, 1e-4);\nlet f0 = 0.02;\nlet fresnel = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0);\nvar r = reflect(-v, n);\nr.y = abs(r.y);\nlet lod = clamp(sqrt(sqrt(a2)) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0);\nvar sky = textureSampleLevel(env_cube, wrap, r, lod).rgb * lighting.view.rgb;\nif (sp.size.z > 0.5) {\nlet pn = vec2f(textureDimensions(cloud_pano));\nlet pv = clamp(sqrt(max(r.y, 0.0)), 0.5 / pn.y, 1.0 - 0.5 / pn.y);\nlet cl = textureSampleLevel(cloud_pano, wrap, vec2f(fract(atan2(r.z, r.x) / (2.0 * PI)), pv), 0.0);\nsky = sky * cl.a + cl.rgb;\n}\nlet seen = mirror_scene(in.p, reflect(-v, n), vec2f(textureDimensions(under)), ign(frag.xy));\nsky = mix(sky, seen.rgb, seen.a);\nif (sp.mirror.w > 0.5) {\nreturn vec4f(select(vec3f(seen.a * 0.2, 0.0, 0.0) + seen.rgb * seen.a, vec3f(0.3, 0.0, 0.0), seen.a <= 0.0) * lighting.env.z, 1.0);\n}\nlet h = normalize(v + l);\nlet nh = max(dot(n, h), 0.0);\nlet dd = nh * nh * (a2 - 1.0) + 1.0;\nlet ggx = a2 / (PI * dd * dd);\nlet vis = 0.5 / (nl * sqrt(nv * nv * (1.0 - a2) + a2) + nv * sqrt(nl * nl * (1.0 - a2) + a2) + 1e-5);\nlet fh = f0 + (1.0 - f0) * pow(1.0 - max(dot(v, h), 0.0), 5.0);\nlet sun = lighting.sun_color.rgb;\nlet spec = sun * (ggx * vis * fh * nl);\nlet up = sh_irradiance(vec3f(0.0, 1.0, 0.0));\nlet body = sp.body.rgb * (up + sun * (max(l.y, 0.0) / PI) * 0.5);\nlet behind = pow(saturate(dot(-v, l)), 8.0);\nlet crest = saturate(in.height * 0.5) * saturate(1.0 - n.y * 0.9 + 0.2);\nvar sss = sp.sss.rgb * sun * (behind * crest * sp.sss.w);\nlet wide = 0.35 + 0.65 * pow(saturate(dot(-v, l) * 0.5 + 0.5), 3.0);\nlet thin = sf.face * (0.6 + 0.4 * saturate(1.0 - abs(n.y) * 1.2));\nsss += sp.sss.rgb * (up * 4.5 + sun * (0.8 * wide)) * (thin * sp.sss.w * 2.5);\nvar below = body;\nvar shore_foam = 0.0;\nif (sp.shore.y > 0.5) {\nlet px = vec2i(frag.xy);\nlet size = vec2f(textureDimensions(under));\nlet dist = length(in.p);\nlet t0 = thickness(dist, frag.z, textureLoad(under_depth, px, 0).x);\nlet bend = n.xz * sp.optics.w * min(t0, 1.0);\nvar uv = (frag.xy + bend) / size;\nif (any(uv < vec2f(0.0)) || any(uv >= vec2f(1.0))) {\nuv = frag.xy / size;\n}\nvar t = thickness(dist, frag.z, textureLoad(under_depth, vec2i(uv * size), 0).x);\nif (textureLoad(under_depth, vec2i(uv * size), 0).x > frag.z) {\nuv = frag.xy / size;\nt = t0;\n}\nvar behind_light = textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z;\nlet down = max(t * v.y, 0.0);\nlet sun_in = sqrt(max(1.0 - (1.0 - l.y * l.y) / 1.7689, 0.04));\nlet above = (in.p - v * t).xz + vec2f(l.x, l.z) / sun_in * down * (1.0 / 1.33);\nvar lap = 0.0;\nlet cn = u32(sp.sea.y);\nlet c0 = select(0u, cn - 2u, cn >= 2u);\nfor (var c = c0; c < select(c0, select(1u, cn - 1u, cn >= 2u), sp.size.w > 0.5); c++) {\nlet cc = sp.cascade[c];\nlet e = 2.0 / (cc.z * sp.size.x);\nlet q = cc.xy + above * cc.z;\nlet ex = vec2f(cc.z * e, 0.0);\nlet ez = vec2f(0.0, cc.z * e);\nlet dsx = textureSampleLevel(slopes, wrap, q + ex, c, 0.0).x - textureSampleLevel(slopes, wrap, q - ex, c, 0.0).x;\nlet dsz = textureSampleLevel(slopes, wrap, q + ez, c, 0.0).y - textureSampleLevel(slopes, wrap, q - ez, c, 0.0).y;\nlap += (dsx + dsz) / (2.0 * e);\n}\nlet focus = 1.0 / max(abs(1.0 - down * 0.248 * lap), 0.25);\nlet caustic = mix(1.0, focus, saturate(down * 3.0) * exp(-down / 4.0) * saturate(l.y * 4.0));\nbehind_light *= mix(1.0, caustic, 0.65);\nlet trans = exp(-sp.optics.rgb * (t + down / sun_in));\nbelow = behind_light * trans + body * (vec3f(1.0) - exp(-sp.optics.rgb * t));\nlet vertical = t0 * max(v.y, 0.02);\nshore_foam = saturate(1.0 - vertical / sp.shore.x) * saturate(vertical * 40.0);\n}\nlet sigma = sqrt(lost);\nlet mean_f = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0 * exp(-2.69 * sigma)) / (1.0 + 22.7 * pow(sigma, 1.5));\nlet fr = min(fresnel, mean_f);\nlet water = sky * fr + (below + sss) * (1.0 - fr) + spec;\nlet foam_light = (sh_irradiance(n) + sun * (nl / PI)) * 0.85;\nvar fp = (sp.cascade[0].xy + in.rest * sp.cascade[0].z) / sp.cascade[0].z;\nif (sf.foam > 0.001 || sf.front > 0.001) {\nfp = sf.world;\n}\nlet flow = surf_flow(sf);\nlet cyc = 1.0;\nlet ph0 = fract(sp.surf3.x / cyc);\nlet ph1 = fract(sp.surf3.x / cyc + 0.5);\nlet fp0 = fp - flow * (ph0 * cyc) + vec2f(13.7, 5.1) * floor(sp.surf3.x / cyc);\nlet fp1 = fp - flow * (ph1 * cyc) + vec2f(7.3, 11.9) * floor(sp.surf3.x / cyc + 0.5);\nlet wflow = abs(2.0 * ph0 - 1.0);\nlet beach = smoothstep(0.0, 0.04, sf.ground);\nvar cover = saturate(fold * sp.sea.w + shore_foam * (1.0 - beach) + sf.foam + sf.front * 0.9);\nif (cover > 0.002) {\nlet spots = vnoise(fp * 0.22) * 0.65 + vnoise(fp * 0.61 + vec2f(9.0, 4.0)) * 0.35;\ncover *= mix(smoothstep(0.35, 0.75, spots), 1.0, smoothstep(0.35, 0.8, cover));\nlet clumps = vnoise(fp * 0.35 + vec2f(3.0, 7.0)) * 0.6 + vnoise(fp * 1.1 + vec2f(11.0, 2.0)) * 0.4;\ncover *= mix(1.0, 0.45 + 0.75 * clumps, smoothstep(0.3, 0.7, cover));\n}\nlet fw = length(fwidth(fp0));\nvar foam = 0.0;\nvar bubbles = 1.0;\nif (cover > 0.002) {\nvar net = foam_net(fp0, cover, fw);\nif (dot(flow, flow) > 1e-4) {\nnet = mix(net, foam_net(fp1, cover, fw), wflow);\n}\nfoam = net.x;\nbubbles = net.y;\n}\nlet aerated = saturate(sf.fresh * 1.6) * (1.0 - beach);\nlet milky = mix(sp.sss.rgb * 2.5, vec3f(0.85, 0.95, 0.95), 0.55) * (sh_irradiance(n) + sun * (nl / PI));\nvar foam_lit = foam_light;\nif (foam > 0.01 && sp.surf0.w > 0.5) {\nlet fuv = sp.surf0.xy + in.rest * sp.surf0.z;\nlet ft = 1.0 / vec2f(textureDimensions(surf_d));\nlet gx = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(ft.x, 0.0), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(ft.x, 0.0), 0.0).w;\nlet gz = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(0.0, ft.y), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(0.0, ft.y), 0.0).w;\nlet per_m = 0.1 / (2.0 * ft.x / sp.surf0.z);\nlet nf = normalize(n + vec3f(-gx, 0.0, -gz) * per_m * 0.5);\nfoam_lit = (sh_irradiance(nf) + sun * (max(dot(nf, l), 0.0) / PI)) * 0.85;\n}\nvar lit = mix(mix(water, milky, aerated * 0.65), foam_lit * bubbles, foam);\nif (sf.ground > 0.0 && sp.shore.y > 0.5) {\nlet sand = textureLoad(under, vec2i(frag.xy), 0).rgb * sp.shore.z;\nlet wet_rough = 0.12;\nlet sheen = textureSampleLevel(env_cube, wrap, r, clamp(sqrt(wet_rough) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0)).rgb * lighting.view.rgb;\nlet wet_sand = sand * mix(1.0, 0.5, sf.wet) + sheen * fresnel * sf.wet * 0.8;\nlit = mix(wet_sand, lit, max(sf.cover, foam));\n}\nlet fogged = apply_fog(lit, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(normalize(in.p)), sun, l);\nreturn vec4f(fogged * lighting.env.z, 1.0);\n}\nstruct Camera {\nview_proj: mat4x4f,\nfrustum: array<vec4f, 6>,\nlight_dir: vec4f,\norigin: vec4f,\n}\nstruct Lighting {\nsun_color: vec4f,\nenv: vec4f,\nsh: array<vec4f, 9>,\nscreen: vec4f,\nview: vec4f,\nao_reproject: mat4x4f,\nao: vec4f,\nfog: vec4f,\nfog2: vec4f,\nfog_air: vec4f,\ngi_grid: vec4f,\ngi_counts: vec4f,\nssr: vec4f,\ngi_cascades: array<vec4f, 3>,\n}\nfn apply_fog(color: vec3f, p: vec3f, fog: vec4f, fog2: vec4f, air: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet dist = length(p);\nif (dist <= 0.0 || (fog.x <= 0.0 && fog2.x <= 0.0)) {\nreturn color;\n}\nlet dir = p / dist;\nlet t = exp(-(air * (fog2.x * dist) + vec3f(height_fog_depth(fog, dir, dist))));\nreturn color * t + fog_inscatter(fog2, dir, ambient, sun, sun_dir) * (vec3f(1.0) - t);\n}\nfn height_fog_depth(fog: vec4f, dir: vec3f, dist: f32) -> f32 {\nif (fog.x <= 0.0) {\nreturn 0.0;\n}\nlet falloff = max(fog.y, 1e-5);\nlet len = max(dist - fog.w, 0.0);\nlet h0 = fog.z + dir.y * min(dist, fog.w);\nlet k = falloff * dir.y * len;\nlet shape = select((1.0 - exp(-k)) / k, 1.0 - 0.5 * k, abs(k) < 1e-3);\nreturn fog.x * exp(-falloff * h0) * len * shape;\n}\nfn fog_inscatter(fog2: vec4f, dir: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet g = fog2.z;\nlet c = dot(dir, sun_dir);\nlet phase = (1.0 - g * g) / (FOUR_PI * pow(max(1.0 + g * g - 2.0 * g * c, 1e-4), 1.5));\nreturn ambient + sun * (phase * fog2.y);\n}\nconst FOUR_PI = 12.5663706;";
8
+ readonly hash: "b6a83798dfc992f7";
9
+ readonly wgsl: "const PI = 3.14159265;\nconst EARTH_RADIUS = 6371000.0;\nconst MAX_CASCADES = 4u;\nstruct SurfaceParams {\ncascade: array<vec4f, MAX_CASCADES>,\ngrid: vec4f,\nsea: vec4f,\nbody: vec4f,\nsss: vec4f,\nsize: vec4f,\noptics: vec4f,\nshore: vec4f,\nmirror: vec4f,\nsurf0: vec4f,\nsurf1: vec4f,\nsurf2: vec4f,\nsurf3: vec4f,\nglint: vec4f,\ncshadow: vec4f,\n}\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lighting: Lighting;\n@group(0) @binding(2) var<uniform> sp: SurfaceParams;\n@group(0) @binding(3) var displacement: texture_2d_array<f32>;\n@group(0) @binding(4) var slopes: texture_2d_array<f32>;\n@group(0) @binding(5) var wrap: sampler;\n@group(0) @binding(6) var env_cube: texture_cube<f32>;\n@group(0) @binding(7) var under: texture_2d<f32>;\n@group(0) @binding(8) var under_depth: texture_2d<f32>;\n@group(0) @binding(9) var clamp_smp: sampler;\n@group(0) @binding(10) var scene_depth: texture_depth_2d;\n@group(0) @binding(11) var depth_out: texture_storage_2d<r32float, write>;\nstruct WaterMotion {\nview_proj: mat4x4f,\nprev_view_proj: mat4x4f,\neye_move: vec4f,\nreactive: vec4f,\n}\n@group(0) @binding(12) var prev_displacement: texture_2d_array<f32>;\n@group(0) @binding(13) var<uniform> wm: WaterMotion;\n@group(0) @binding(14) var shore_map: texture_2d<f32>;\n@group(0) @binding(15) var spill_map: texture_2d<f32>;\n@group(0) @binding(16) var cloud_pano: texture_2d<f32>;\n@group(0) @binding(27) var cloud_shadow: texture_2d<f32>;\nfn cloud_light(p: vec3f, l: vec3f) -> f32 {\nif (sp.cshadow.w < 0.5) {\nreturn 1.0;\n}\nlet at = p - l * ((p.y - sp.sea.x) / max(l.y, 0.05));\nlet uv = (at.xz - sp.cshadow.xy) * sp.cshadow.z + 0.5;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nreturn mix(1.0, textureSampleLevel(cloud_shadow, clamp_smp, uv, 0.0).r, saturate(edge * 16.0));\n}\nstruct Surf {\nd: vec3f,\nslope: vec2f,\nbroken: f32,\nfoam: f32,\nfade: f32,\nground: f32,\nreach: f32,\ncover: f32,\nwet: f32,\nfilm: f32,\nfront: f32,\nface: f32,\namp: f32,\nworld: vec2f,\ndir: vec2f,\nphase: f32,\nonset: f32,\nfresh: f32,\nfront_h: f32,\nwet_h1: f32,\nwet_h2: f32,\nrun: f32,\nmark: f32,\n}\nfn pcg(v: u32) -> u32 {\nlet state = v * 747796405u + 2891336453u;\nlet word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\nreturn (word >> 22u) ^ word;\n}\nfn hash1(n: f32) -> f32 {\nreturn f32(pcg(bitcast<u32>(i32(n)))) / 4294967296.0;\n}\nfn hash2(p: vec2f) -> f32 {\nlet q = vec2<i32>(p);\nreturn f32(pcg(bitcast<u32>(q.x) ^ pcg(bitcast<u32>(q.y) + 0x9e3779b9u))) / 4294967296.0;\n}\nfn vnoise(p: vec2f) -> f32 {\nlet i = floor(p);\nlet f = fract(p);\nlet u = f * f * (3.0 - 2.0 * f);\nreturn mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x), mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn worley(p: vec2f) -> vec2f {\nlet i = floor(p);\nlet f = fract(p);\nvar d1 = 8.0;\nvar d2 = 8.0;\nfor (var y = -1; y <= 1; y++) {\nfor (var x = -1; x <= 1; x++) {\nlet o = vec2f(f32(x), f32(y));\nlet c = i + o;\nlet j = vec2f(hash2(c), hash2(c + vec2f(1013.0, 7919.0)));\nlet d = length(o + j - f) / (0.55 + 0.9 * hash2(c + vec2f(4241.0, 557.0)));\nif (d < d1) {\nd2 = d1;\nd1 = d;\n} else if (d < d2) {\nd2 = d;\n}\n}\n}\nreturn vec2f(d1, d2);\n}\nfn foam_net(p: vec2f, amount: f32, fw: f32) -> vec2f {\nlet a = saturate(amount);\nlet q = p + vec2f(vnoise(p * 2.0), vnoise(p * 2.0 + vec2f(5.2, 1.3))) * 0.36;\nlet big = worley(q * 3.2);\nvar small = vec2f(0.5, 1.0);\nif (sp.size.w > 1.5) {\nsmall = worley(q * 10.0 + vec2f(3.7, 1.9));\n}\nlet r = mix(0.82, 0.12, pow(a, 1.1));\nlet eb = fw * 3.2;\nlet es = fw * 10.0;\nlet mean = saturate(1.0 - 2.6 * r * r);\nlet hb = mix(smoothstep(r - 0.05 - eb, r + 0.05 + eb, big.x), mean, smoothstep(0.15, 0.6, eb));\nlet rs = r * 0.8 + 0.1;\nlet hs = mix(smoothstep(rs - 0.06 - es, rs + 0.06 + es, small.x), saturate(1.0 - 2.6 * rs * rs), smoothstep(0.15, 0.6, es));\nlet net = hb * mix(1.0, hs, 0.55 * (1.0 - a));\nlet cover = net * smoothstep(0.0, 0.06, a);\nlet lumps = mix(0.8, 1.04, saturate(1.0 - small.x * 0.9)) * mix(0.9, 1.0, saturate(1.0 - big.x * 0.8));\nlet light = mix(lumps, 0.92, smoothstep(0.15, 0.6, es));\nreturn vec2f(cover, light);\n}\nstruct Train {\nth: f32,\nu: f32,\nnw: f32,\namp: f32,\nshoaled: f32,\nperiod: f32,\nblend: f32,\n}\nconst TRAINS = array<vec4f, 3>(vec4f(1.0, 1.0, 0.0, 0.0), vec4f(1.37, 0.45, 0.0, 0.31), vec4f(0.79, 0.3, 0.0, 0.67));\nfn wobble(n: f32, i: u32, world: vec2f) -> f32 {\nlet o = vec2f(n * 0.61 + f32(i) * 7.0, n * 0.37 + f32(i) * 3.0);\nreturn ((vnoise(world / 45.0 + o) - 0.5) * 1.2 + (vnoise(world / 14.0 + o * 1.7) - 0.5) * 0.35) * sp.surf3.y;\n}\nfn wave_amp(n: f32, world: vec2f) -> f32 {\nlet group = 1.0 + 0.3 * sin(2.0 * PI * n / 6.3 + 1.3) + 0.25 * (hash1(n) - 0.5);\nlet section = 0.6 + 0.8 * vnoise(world / 28.0 + vec2f(n * 7.13, n * 3.71));\nreturn mix(1.0, group * section, sp.surf3.y);\n}\nfn swash_front(u: f32, run: f32) -> f32 {\nlet rise = 0.18;\nlet up = 1.0 - (1.0 - saturate(u / rise)) * (1.0 - saturate(u / rise));\nlet down = pow(saturate(1.0 - (u - rise) / 0.57), 1.6);\nreturn run * select(down, up, u < rise);\n}\nfn swash_high(u: f32, run: f32, window: f32) -> f32 {\nlet rise = 0.18;\nlet u0 = u - window;\nif (u0 >= rise) {\nreturn swash_front(u0, run);\n}\nif (u >= rise) {\nreturn run;\n}\nreturn max(swash_front(u, run), select(0.0, swash_front(u0 + 1.0, run), u0 < 0.0));\n}\nfn swash_state(e: f32, front_h: f32, wet_h1: f32, wet_h2: f32, run: f32) -> vec4f {\nlet cover = saturate((front_h - e) / 0.03);\nlet r1 = saturate((wet_h1 - e) / 0.06 + 0.4);\nlet r2 = saturate((wet_h2 - e) / 0.12 + 0.4);\nlet damp = 0.3 * saturate(1.0 - e / max(run, 1e-3));\nlet wet = max(0.75 * (0.55 * r1 + 0.45 * r2), damp) * saturate((run - e) / 0.08 + 0.5);\nlet film = 0.02 + 0.04 * cover * saturate((front_h - e) / 0.15);\nlet front = cover * (1.0 - saturate((front_h - e) / 0.015)) * saturate(front_h * 6.0);\nreturn vec4f(cover, wet, film, front);\n}\nfn surf_at(rest: vec2f, time: f32) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet sp2 = textureSampleLevel(spill_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\nlet period = sp.surf1.y;\ns.world = uv / sp.surf0.z;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\nlet hs = max(depth, 0.15);\nlet start = sp.surf2.z;\nlet shoal = pow(start / hs, 0.25) * smoothstep(start, start * 0.6, depth);\nlet dir = vec2f(cos(f.w), sin(f.w));\ns.dir = dir;\nvar tr: array<Train, 3>;\nlet trains = select(1u, 3u, sp.size.w > 0.5);\nfor (var i = 0u; i < trains; i++) {\nlet ti = TRAINS[i];\nlet pi = period * ti.x;\nvar th: f32;\nvar u: f32;\nvar nw: f32;\nif (i == 0u) {\nth = 2.0 * PI * fract(time / period) - atan2(f.z, f.y);\nu = fract(th / (2.0 * PI));\nnw = round((time - sp2.y) / period + 0.5 - fract(u + 0.5));\n} else {\nlet cyc = (time - sp2.y) / pi + ti.w;\nu = fract(cyc);\nth = 2.0 * PI * u;\nnw = round(cyc + 0.5 - fract(u + 0.5));\n}\nlet ff = fract(u + 0.5);\nlet blend = smoothstep(0.82, 1.0, ff);\nvar amp = wave_amp(nw + f32(i) * 101.0, s.world);\nvar wob = wobble(nw, i, s.world);\nif (blend > 0.0) {\namp = mix(amp, wave_amp(nw + 1.0 + f32(i) * 101.0, s.world), blend);\nwob = mix(wob, wobble(nw + 1.0, i, s.world), blend);\n}\nth -= wob;\ntr[i].th = th;\ntr[i].u = fract(th / (2.0 * PI));\ntr[i].nw = nw;\ntr[i].amp = amp;\ntr[i].shoaled = sp.surf1.x * ti.y * amp * shoal;\ntr[i].blend = blend;\ntr[i].period = pi;\n}\nlet gnoise = mix(vnoise(s.world / 35.0 + vec2f(tr[0].nw * 2.3, 0.0)), vnoise(s.world / 35.0 + vec2f((tr[0].nw + 1.0) * 2.3, 0.0)), tr[0].blend);\nlet gamma = sp.surf1.z * (0.85 + 0.3 * gnoise * sp.surf3.y + 0.15 * (1.0 - sp.surf3.y));\nlet hb = gamma * hs;\nvar eta = 0.0;\nvar lean = vec2f(0.0);\nvar slope = 0.0;\nvar face_k = 0.0;\nvar foam = 0.0;\ns.broken = 0.0;\ns.onset = 0.0;\nfor (var i = 0u; i < trains; i++) {\nvar others = 0.0;\nfor (var j = 0u; j < trains; j++) {\nif (j != i) {\nothers += 0.4 * tr[j].shoaled * (0.5 + 0.5 * cos(tr[j].th));\n}\n}\nlet ratio = (tr[i].shoaled + others) / max(hb, 1e-3);\nlet broken = saturate((ratio - 1.0) * 3.0);\nlet share = tr[i].shoaled / max(tr[i].shoaled + others, 1e-4);\nlet H = min(tr[i].shoaled, hb * share + tr[i].shoaled * (1.0 - broken)) * smoothstep(-0.05, 0.25, depth);\nlet th = tr[i].th;\nlet u = tr[i].u;\nlet wn = mix(vnoise(s.world / 22.0 + vec2f(tr[i].nw * 5.1, f32(i) * 9.0)), vnoise(s.world / 22.0 + vec2f((tr[i].nw + 1.0) * 5.1, f32(i) * 9.0)), tr[i].blend);\nlet w = 0.12 * mix(1.0, 0.6 + 0.8 * wn, sp.surf3.y);\nlet stokes = 0.5 * (cos(th) + 0.3 * cos(2.0 * th));\nlet dstokes = 0.5 * (-sin(th) - 0.6 * sin(2.0 * th));\nlet bore = select(1.0 - (u - w) / (1.0 - w), u / w, u < w) - 0.5;\nlet dw = min(0.6 * w, 1.2 / (tr[i].period * sqrt(9.81 * hs)));\nlet rise = saturate(0.5 + u / dw) * saturate(0.5 - (u - w) / dw) + saturate(0.5 + (u - 1.0) / dw);\nlet dbore = (-1.0 / (1.0 - w) + (1.0 / w + 1.0 / (1.0 - w)) * rise) / (2.0 * PI);\nvar e = H * mix(stokes, bore, broken);\nlet de = H * mix(dstokes, dbore, broken);\nlet q = sp.surf1.w * (1.0 - 0.6 * broken);\nvar l = dir * (q * H * 0.5 * sin(th));\nlet onset = broken * (1.0 - broken) * 4.0 * saturate((ratio - 0.9) * 10.0);\nlet top = smoothstep(0.1, 0.5, e / max(H, 1e-3));\nl += dir * (sp.surf3.z * H * 0.55 * onset * top);\ne *= 1.0 + 0.25 * onset * top;\nlet k = 2.0 * PI / (tr[i].period * sqrt(9.81 * hs));\neta += e;\nlean += l;\nslope += -k * de;\nface_k += smoothstep(-0.2, 0.45, e / max(H, 1e-3)) * saturate(H * 1.2) * (1.0 - 0.65 * broken + 0.5 * onset) * TRAINS[i].y;\nlet fo = broken * smoothstep(0.0, w, u) * (exp(-(u - w) * 9.0) + 0.15 * exp(-(u - w) * 3.0)) * saturate(H * 3.0) * TRAINS[i].y;\nfoam = 1.0 - (1.0 - foam) * (1.0 - fo);\ns.broken = max(s.broken, broken);\ns.onset = max(s.onset, onset * TRAINS[i].y);\n}\ns.slope = slope * dir;\ns.d = vec3f(lean.x, eta, lean.y);\ns.face = saturate(-slope * 1.5) * saturate(face_k);\ns.foam = foam;\nlet u = tr[0].u;\ns.phase = u;\ns.amp = tr[0].amp;\ns.ground = -depth;\ns.reach = max(sp2.x, s.ground);\nif (s.ground > -0.05) {\nlet e = s.reach;\nlet rn = mix(vnoise(s.world / 9.0 + vec2f(tr[0].nw * 3.3, 1.0)), vnoise(s.world / 9.0 + vec2f((tr[0].nw + 1.0) * 3.3, 1.0)), tr[0].blend);\nlet run = sp.surf1.x * s.amp * 0.8 * mix(1.0, 0.7 + 0.6 * rn, sp.surf3.y);\ns.run = run;\ns.front_h = swash_front(u, run);\ns.wet_h1 = swash_high(u, run, 1.5 / sp.surf1.y);\ns.wet_h2 = swash_high(u, run, 4.0 / sp.surf1.y);\nlet w = swash_state(e, s.front_h, s.wet_h1, s.wet_h2, run);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\nreturn s;\n}\nfn on_beach(d: vec3f, s: Surf, spacing: f32) -> vec3f {\nif (s.ground <= 0.0) {\nreturn d;\n}\nlet reach = sp.surf1.x * 0.8 * 2.0 + 0.05;\nlet y = select(s.ground - 1.0, s.ground + s.film + 0.03 + 0.03 * spacing, s.reach < reach);\nlet k = smoothstep(0.0, 0.04, s.ground);\nreturn vec3f(d.x * (1.0 - k), mix(d.y, y, k), d.z * (1.0 - k));\n}\n@group(0) @binding(17) var surf_a: texture_2d<f32>;\n@group(0) @binding(18) var surf_b: texture_2d<f32>;\n@group(0) @binding(19) var surf_c: texture_2d<f32>;\n@group(0) @binding(20) var surf_d: texture_2d<f32>;\n@group(0) @binding(21) var surf_a_prev: texture_2d<f32>;\n@group(0) @binding(22) var surf_d_prev: texture_2d<f32>;\n@group(0) @binding(23) var out_a: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(24) var out_b: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(25) var out_c: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(26) var out_d: texture_storage_2d<rgba16float, write>;\n@compute @workgroup_size(8, 8) fn surf_field(@builtin(global_invocation_id) id: vec3u) {\nlet n = textureDimensions(out_a);\nif (any(id.xy >= n)) {\nreturn;\n}\nlet uv = (vec2f(id.xy) + 0.5) / vec2f(n);\nlet rest = (uv - sp.surf0.xy) / sp.surf0.z;\nlet s = surf_at(rest, sp.surf3.x);\ntextureStore(out_a, vec2i(id.xy), vec4f(s.d, s.broken));\ntextureStore(out_b, vec2i(id.xy), vec4f(s.slope, s.face, s.onset));\ntextureStore(out_c, vec2i(id.xy), vec4f(s.foam, s.front_h, s.wet_h1, s.wet_h2));\nlet dt = clamp(sp.surf3.x - sp.surf3.w, 0.0, 0.1);\nlet v = surf_flow(s);\nlet extent = 1.0 / sp.surf0.z;\nlet back = uv - v * dt / extent;\nlet texel = 1.0 / vec2f(n);\nlet f0 = textureSampleLevel(surf_d_prev, clamp_smp, back, 0.0).w;\nlet fs = textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(0.0, texel.y), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(0.0, texel.y), 0.0).w;\nlet carried = mix(f0, fs * 0.25, 0.12 * saturate(dt * 60.0));\nlet life = mix(3.0, 1.2, saturate(carried));\nvar f = carried * exp(-dt / life) * select(1.0, 0.0, s.ground > 0.0 && s.cover < 0.01 && s.wet < 0.05) * select(0.0, 1.0, dt > 0.0);\nf = max(f, saturate(s.foam * 0.9 + s.front * 0.8));\ntextureStore(out_d, vec2i(id.xy), vec4f(s.run, s.phase, s.amp, f));\n}\nfn smooth_sample(t: texture_2d<f32>, uv: vec2f) -> vec4f {\nlet size = vec2f(textureDimensions(t));\nlet p = uv * size - 0.5;\nlet i = floor(p);\nlet f = p - i;\nlet w0 = (1.0 - f) * (1.0 - f) * (1.0 - f) / 6.0;\nlet w1 = (4.0 - 6.0 * f * f + 3.0 * f * f * f) / 6.0;\nlet w2 = (1.0 + 3.0 * f + 3.0 * f * f - 3.0 * f * f * f) / 6.0;\nlet w3 = f * f * f / 6.0;\nlet g0 = w0 + w1;\nlet g1 = w2 + w3;\nlet h0 = (i - 0.5 + w1 / g0) / size;\nlet h1 = (i + 1.5 + w3 / g1) / size;\nlet a = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h0.y), 0.0);\nlet b = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h0.y), 0.0);\nlet c = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h1.y), 0.0);\nlet d = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h1.y), 0.0);\nreturn mix(mix(a, b, g1.x), mix(c, d, g1.x), g1.y);\n}\nfn surf_tex(rest: vec2f, prev: bool) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\ns.dir = vec2f(cos(f.w), sin(f.w));\ns.world = uv / sp.surf0.z;\ns.ground = -depth;\ns.reach = max(textureSampleLevel(spill_map, clamp_smp, uv, 0.0).x, s.ground);\nlet a = select(textureSampleLevel(surf_a, clamp_smp, uv, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv, 0.0), prev);\ns.d = a.xyz;\ns.broken = a.w;\nlet b = textureSampleLevel(surf_b, clamp_smp, uv, 0.0);\ns.slope = b.xy;\ns.face = b.z;\ns.onset = b.w;\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nif (s.ground > -0.05) {\nlet e = max(smooth_sample(spill_map, uv).x, -smooth_sample(shore_map, uv).x);\nlet w = swash_state(e, c.y, c.z, c.w, dd.x);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\nlet band = saturate(1.0 - abs(c.w - 0.008 - e) / 0.012);\nlet age = saturate(1.0 - (c.w - c.z) / max(dd.x * 0.6, 0.02));\ns.mark = band * (1.0 - w.x) * mix(0.35, 1.0, age) * saturate(c.w * 8.0);\n}\ns.front_h = c.y;\ns.run = dd.x;\ns.phase = dd.y;\ns.amp = dd.z;\ns.fresh = c.x;\ns.foam = max(c.x, dd.w);\nreturn s;\n}\nfn surf_disp(rest: vec2f, spacing: f32, prev: bool) -> vec3f {\nif (sp.surf0.w < 0.5) {\nreturn vec3f(0.0);\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec3f(0.0);\n}\nlet r = 0.35 * spacing * sp.surf0.z;\nvar d = vec3f(0.0);\nfor (var k = 0u; k < 5u; k++) {\nlet o = array<vec2f, 5>(vec2f(0.0), vec2f(r, 0.0), vec2f(-r, 0.0), vec2f(0.0, r), vec2f(0.0, -r))[k];\nlet w = select(0.125, 0.5, k == 0u);\nlet t = select(textureSampleLevel(surf_a, clamp_smp, uv + o, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv + o, 0.0), prev);\nd += t.xyz * w;\n}\nreturn d;\n}\nfn surf_flow(s: Surf) -> vec2f {\nlet hs = max(-s.ground, 0.15);\nif (s.ground > -0.05) {\nreturn s.dir * select(-0.9, 1.6, s.phase < 0.18) * s.cover;\n}\nreturn s.dir * clamp(sqrt(9.81 * hs) * max(s.d.y, 0.0) / hs, 0.0, 3.0);\n}\nconst SPRAY_SIDE = 192u;\nconst SPRAY_SPACING = 0.75;\nstruct SprayOut {\n@builtin(position) clip: vec4f,\n@location(0) q: vec4f,\n@location(1) p: vec3f,\n}\n@vertex fn vs_spray(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> SprayOut {\nvar o: SprayOut;\no.clip = vec4f(0.0, 0.0, -1.0, 1.0);\nif (sp.surf0.w < 0.5 || sp.size.y <= 0.0) {\nreturn o;\n}\nlet extent = 1.0 / sp.surf0.z;\nlet eye = sp.surf0.xy * extent;\nlet gx = f32(ii % SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet gz = f32(ii / SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet cell = floor(eye / SPRAY_SPACING) + vec2f(gx, gz);\nlet j = vec2f(hash2(cell), hash2(cell + vec2f(91.0, 37.0)));\nlet rest = (cell + j) * SPRAY_SPACING - eye;\nvar s = surf_tex(rest, false);\nlet tuv = sp.surf0.xy + rest * sp.surf0.z;\ns.phase = textureLoad(surf_d, vec2i(clamp(tuv, vec2f(0.0), vec2f(0.9999)) * vec2f(textureDimensions(surf_d))), 0).y;\nlet age = (s.phase - 0.12) * sp.surf1.y;\nlet life = 0.6 + 0.6 * hash2(cell + vec2f(13.0, 71.0));\nif (s.broken < 0.05 || age < 0.0 || age > life || s.ground > 0.3) {\nreturn o;\n}\nlet H = sp.surf1.x * s.amp;\nlet strength = (0.05 * s.broken + s.onset) * saturate(H * 1.2) * (0.4 + 1.2 * hash2(cell + vec2f(5.0, 3.0)));\nlet v0 = (2.0 + 3.0 * hash2(cell + vec2f(2.0, 9.0))) * saturate(H);\nlet k = 1.8;\nlet rise = v0 / k * (1.0 - exp(-k * age)) - 4.0 * age * age * 0.5;\nlet fwd = s.dir * (1.2 * (1.0 - exp(-1.5 * age)));\nlet base = s.d.y + 0.15;\nlet centre = vec3f(rest.x + fwd.x, sp.sea.x + base + max(rise, 0.0), rest.y + fwd.y);\nlet t = age / life;\nlet size = (0.12 + 0.5 * t) * (0.7 + 0.6 * hash2(cell + vec2f(17.0, 23.0))) * (0.6 + 0.6 * saturate(H));\nlet corner = array<vec2f, 6>(vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0))[vi];\nlet fwdv = normalize(centre);\nlet right = normalize(cross(vec3f(0.0, 1.0, 0.0), fwdv));\nlet up = cross(fwdv, right);\nlet pos = centre + (right * corner.x + up * corner.y) * size;\no.clip = camera.view_proj * vec4f(pos, 1.0);\nlet alpha = strength * smoothstep(0.0, 0.1, t) * (1.0 - smoothstep(0.4, 1.0, t)) * sp.size.y * 0.32;\no.q = vec4f(corner, alpha, length(centre));\no.p = centre;\nreturn o;\n}\nfn spray_alpha(in: SprayOut) -> f32 {\nlet r2 = dot(in.q.xy, in.q.xy);\nif (r2 > 1.0) {\nreturn 0.0;\n}\nlet wisp = vnoise(in.q.xy * 1.8 + in.p.xz * 3.1) * 0.6 + vnoise(in.q.xy * 4.3 + in.p.xz * 1.7) * 0.4;\nreturn in.q.z * (1.0 - r2) * (1.0 - r2) * smoothstep(0.38, 0.62, wisp) * 1.6;\n}\n@fragment fn fs_spray_reactive(in: SprayOut) -> @location(0) vec4f {\nlet a = spray_alpha(in);\nif (a <= 0.002) {\ndiscard;\n}\nreturn vec4f(saturate(a * 2.0) * wm.reactive.x);\n}\n@fragment fn fs_spray(in: SprayOut) -> @location(0) vec4f {\nvar a = spray_alpha(in);\nif (a <= 0.0) {\ndiscard;\n}\nlet d = textureLoad(under_depth, vec2i(in.clip.xy), 0).x;\nif (d > 0.0) {\nlet gap = in.q.w * (in.clip.z / d - 1.0);\na *= saturate(gap / 0.5);\n}\nlet v = normalize(in.p);\nlet l = camera.light_dir.xyz;\nlet g = 0.75;\nlet cosv = dot(v, l);\nlet hg = (1.0 - g * g) / (4.0 * PI * pow(1.0 + g * g - 2.0 * g * cosv, 1.5));\nlet light = sh_irradiance(vec3f(0.0, 1.0, 0.0)) * 0.6 + lighting.sun_color.rgb * cloud_light(in.p, l) * (hg * 3.0 + 0.05);\nlet fogged = apply_fog(light, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(v), lighting.sun_color.rgb, l);\nreturn vec4f(fogged * lighting.env.z * a, a);\n}\nstruct VsOut {\n@builtin(position) clip: vec4f,\n@location(0) p: vec3f,\n@location(1) rest: vec2f,\n@location(2) height: f32,\n}\nfn ring_radius(i: f32) -> f32 {\nlet k = sp.grid.y;\nreturn sp.grid.x * (pow(1.0 + k, i) - 1.0) / k;\n}\nfn grid_point(vi: u32) -> vec3f {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nreturn vec3f(vec2f(cos(a), sin(a)) * r, max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs)));\n}\nfn calm(c: u32, fade: f32) -> f32 {\nreturn mix(1.0, fade, saturate(1.0 / (sp.cascade[c].z * 150.0)));\n}\nfn displaced(field: texture_2d_array<f32>, rest: vec2f, spacing: f32, fade: f32) -> vec3f {\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(field, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nreturn d;\n}\nstruct MotionOut {\n@builtin(position) clip: vec4f,\n@location(0) now: vec4f,\n@location(1) then: vec4f,\n@location(2) rest: vec2f,\n}\n@vertex fn vs_motion(@builtin(vertex_index) vi: u32) -> MotionOut {\nlet g = grid_point(vi);\nlet rest = g.xy;\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet sn = surf_tex(rest, false);\nlet sq = surf_tex(rest, wm.eye_move.w > 0.5);\nlet dn = on_beach(displaced(displacement, rest, g.z, sn.fade) + surf_disp(rest, g.z, false), sn, g.z);\nlet dp = select(dn, on_beach(displaced(prev_displacement, rest, g.z, sq.fade) + surf_disp(rest, g.z, true), sq, g.z), wm.eye_move.w > 0.5);\nlet p = vec3f(rest.x + dn.x, sp.sea.x + dn.y - drop, rest.y + dn.z);\nlet q = vec3f(rest.x + dp.x, sp.sea.x + dp.y - drop, rest.y + dp.z) + wm.eye_move.xyz;\nvar o: MotionOut;\no.now = wm.view_proj * vec4f(p, 1.0);\no.clip = camera.view_proj * vec4f(p, 1.0);\no.then = wm.prev_view_proj * vec4f(q, 1.0);\no.rest = rest;\nreturn o;\n}\nfn motion_of(in: MotionOut) -> vec4f {\nlet now = in.now.xy / in.now.w;\nlet then = in.then.xy / max(in.then.w, 1e-6);\nreturn vec4f((now - then) * vec2f(0.5, -0.5), in.then.w, 1.0);\n}\n@fragment fn fs_motion(in: MotionOut) -> @location(0) vec4f {\nreturn motion_of(in);\n}\nstruct MotionReactive {\n@location(0) motion: vec4f,\n@location(1) reactive: vec4f,\n}\n@fragment fn fs_motion_reactive(in: MotionOut) -> MotionReactive {\nvar o: MotionReactive;\no.motion = motion_of(in);\nlet s = surf_tex(in.rest, false);\no.reactive = vec4f(saturate(s.fresh * 0.9 + s.front * 0.7 + s.onset * 0.6) * wm.reactive.x);\nreturn o;\n}\n@vertex fn vs(@builtin(vertex_index) vi: u32) -> VsOut {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nlet rest = vec2f(cos(a), sin(a)) * r;\nlet spacing = max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs));\nlet sf = surf_tex(rest, false);\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, sf.fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(displacement, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nd = on_beach(d + surf_disp(rest, spacing, false), sf, spacing);\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet p = vec3f(rest.x + d.x, sp.sea.x + d.y - drop, rest.y + d.z);\nvar o: VsOut;\no.clip = camera.view_proj * vec4f(p, 1.0);\no.p = p;\no.rest = rest;\no.height = d.y;\nreturn o;\n}\nfn sh_irradiance(n: vec3f) -> vec3f {\nreturn max(lighting.sh[0].rgb * 0.282095 + lighting.sh[1].rgb * (0.488603 * n.y) + lighting.sh[2].rgb * (0.488603 * n.z) + lighting.sh[3].rgb * (0.488603 * n.x) + lighting.sh[4].rgb * (1.092548 * n.x * n.y) + lighting.sh[5].rgb * (1.092548 * n.y * n.z) + lighting.sh[6].rgb * (0.315392 * (3.0 * n.z * n.z - 1.0)) + lighting.sh[7].rgb * (1.092548 * n.x * n.z) + lighting.sh[8].rgb * (0.546274 * (n.x * n.x - n.y * n.y)), vec3f(0.0));\n}\n@compute @workgroup_size(8, 8) fn copy_depth(@builtin(global_invocation_id) id: vec3u) {\nlet size = textureDimensions(scene_depth);\nif (id.x >= size.x || id.y >= size.y) {\nreturn;\n}\ntextureStore(depth_out, vec2i(id.xy), vec4f(textureLoad(scene_depth, vec2i(id.xy), 0), 0.0, 0.0, 0.0));\n}\nfn thickness(dist: f32, ds: f32, dop: f32) -> f32 {\nreturn select(1.0e9, dist * max(ds / dop - 1.0, 0.0), dop > 0.0);\n}\nfn mirror_probe(p: vec3f, r: vec3f, t: f32, size: vec2f) -> vec4f {\nlet c = camera.view_proj * vec4f(p + r * t, 1.0);\nif (c.w <= 0.0) {\nreturn vec4f(0.0);\n}\nlet ndc = c.xyz / c.w;\nlet uv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec4f(0.0);\n}\nlet d = textureLoad(under_depth, vec2i(uv * size), 0).x;\nlet gap = select(-1.0e9, c.w * (1.0 - ndc.z / d), d > 0.0);\nreturn vec4f(uv, gap, 1.0);\n}\nfn mirror_scene(p: vec3f, r: vec3f, size: vec2f, jitter: f32) -> vec4f {\nlet len = sp.mirror.x;\nlet steps = u32(sp.mirror.y);\nif (len <= 0.0 || steps == 0u || sp.shore.y < 0.5 || r.y <= 0.0) {\nreturn vec4f(0.0);\n}\nvar prev = 0.0;\nvar was_behind = false;\nfor (var i = 1u; i <= steps; i++) {\nlet f = (f32(i) - jitter) / f32(steps);\nlet t = len * f * f;\nlet s = mirror_probe(p, r, t, size);\nif (s.w < 0.5) {\nbreak;\n}\nlet behind = s.z > 0.0;\nif (behind && !was_behind) {\nvar a = prev;\nvar b = t;\nvar hit = s;\nfor (var k = 0u; k < 6u; k++) {\nlet m = 0.5 * (a + b);\nlet sm = mirror_probe(p, r, m, size);\nif (sm.w > 0.5 && sm.z > 0.0) {\nb = m;\nhit = sm;\n} else {\na = m;\n}\n}\nif (hit.z < sp.mirror.z + 0.03 * b) {\nlet uv = hit.xy;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nlet fade = saturate(edge * 12.0) * (1.0 - smoothstep(0.7, 1.0, b / len));\nreturn vec4f(textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z, fade);\n}\n}\nwas_behind = behind;\nprev = t;\n}\nreturn vec4f(0.0);\n}\nstruct WetParams { inv_view_proj: mat4x4f }\n@group(0) @binding(28) var<uniform> wp: WetParams;\nstruct WetOut { @builtin(position) clip: vec4f }\n@vertex fn vs_wet(@builtin(vertex_index) i: u32) -> WetOut {\nlet p = vec2f(f32((i << 1u) & 2u), f32(i & 2u)) * 2.0 - 1.0;\nvar o: WetOut;\no.clip = vec4f(p, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs_wet(in: WetOut) -> @location(0) vec4f {\nlet px = vec2i(in.clip.xy);\nlet d = textureLoad(scene_depth, px, 0);\nif (d <= 0.0 || sp.surf0.w < 0.5) {\ndiscard;\n}\nlet size = vec2f(textureDimensions(scene_depth));\nlet ndc = vec2f(in.clip.x / size.x * 2.0 - 1.0, 1.0 - in.clip.y / size.y * 2.0);\nlet w4 = wp.inv_view_proj * vec4f(ndc, d, 1.0);\nlet p = w4.xyz / w4.w;\nlet uv = sp.surf0.xy + p.xz * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\ndiscard;\n}\nlet h = p.y - sp.sea.x;\nlet ground = -smooth_sample(shore_map, uv).x;\nif (h < ground + 0.05) {\ndiscard;\n}\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nlet wash = select(sp.surf1.x * 0.6 * dd.z, 0.0, ground > 0.0);\nlet world = uv / sp.surf0.z;\nlet ragged = (vnoise(world * 3.0) - 0.5) * 0.12 + (vnoise(vec2f(world.x * 9.0, world.y * 9.0) + vec2f(5.0, 1.0)) - 0.5) * 0.05;\nlet top = max(c.w, wash) + ragged;\nlet drip = smoothstep(0.55, 0.9, vnoise(vec2f(world.x * 14.0 + world.y * 14.0, 0.5))) * 0.08;\nlet wet = (1.0 - smoothstep(top - 0.02, top + 0.04 + drip, h)) * saturate(top * 6.0);\nif (wet <= 0.001) {\ndiscard;\n}\nreturn vec4f(vec3f(mix(1.0, 0.58, wet)), 1.0);\n}\nfn ign(px: vec2f) -> f32 {\nlet frame = floor(camera.light_dir.w * 60.0) % 64.0;\nlet q = px + 5.588238 * frame;\nreturn fract(52.9829189 * fract(dot(q, vec2f(0.06711056, 0.00583715))));\n}\nfn glint_hash(c: vec2i, lod: i32, bucket: i32, s: u32) -> f32 {\nlet h = pcg(bitcast<u32>(c.x) ^ pcg(bitcast<u32>(c.y) ^ pcg(bitcast<u32>(lod * 7919 + bucket) + s * 0x9e3779b9u)));\nreturn f32(h) / 4294967296.0;\n}\nfn poisson(mu: f32, u: f32, g: vec3f) -> f32 {\nif (mu > 12.0) {\nreturn max(0.0, round(mu + sqrt(mu) * (g.x + g.y + g.z - 1.5) * 2.0));\n}\nvar k = 0.0;\nvar pk = exp(-mu);\nvar cdf = pk;\nfor (var i = 0u; i < 32u; i++) {\nif (u <= cdf) {\nbreak;\n}\nk += 1.0;\npk *= mu / k;\ncdf += pk;\n}\nreturn k;\n}\nfn glint_level(w: vec2f, size: vec2f, lod: i32, mu: f32) -> f32 {\nlet c = vec2i(floor(w / size));\nlet t = sp.surf3.x / sp.glint.w;\nvar sum = 0.0;\nfor (var j = 0; j < 2; j++) {\nlet phase = t + 0.5 * f32(j);\nlet bucket = i32(floor(phase)) * 2 + j;\nlet wt = 1.0 - abs(2.0 * fract(phase) - 1.0);\nlet k = poisson(mu, glint_hash(c, lod, bucket, 0u), vec3f(glint_hash(c, lod, bucket, 1u), glint_hash(c, lod, bucket, 2u), glint_hash(c, lod, bucket, 3u)));\nsum += wt * k / max(mu, 1e-12);\n}\nreturn sum;\n}\nconst GLINT_ANGLE = 1.0e-5;\nfn glint_ratio(w: vec2f, ext: vec2f, p: f32) -> f32 {\nif (sp.glint.x <= 0.0 || p <= 0.0) {\nreturn 1.0;\n}\nlet facet = sp.glint.y;\nlet r = max(w.y, 1e-3);\nlet facets = ext.x * ext.y / (facet * facet);\nlet level = vec2f(log2(max(ext.x / (r * GLINT_ANGLE), 1.0)), log2(max(ext.y / facet, 1.0)));\nlet l0 = floor(level);\nlet f = level - l0;\nlet s0 = vec2f(GLINT_ANGLE, facet) * exp2(l0);\nlet mu = s0.x * r * s0.y / (facet * facet) * p;\nlet id = i32(l0.x) * 64 + i32(l0.y);\nlet r0 = mix(glint_level(w, s0, id, mu), glint_level(w, s0 * vec2f(2.0, 1.0), id + 64, mu * 2.0), f.x);\nlet r1 = mix(glint_level(w, s0 * vec2f(1.0, 2.0), id + 1, mu * 2.0), glint_level(w, s0 * 2.0, id + 65, mu * 4.0), f.x);\nreturn mix(1.0, mix(r0, r1, f.y), sp.glint.x * smoothstep(1.0, 16.0, facets));\n}\n@fragment fn fs(in: VsOut) -> @location(0) vec4f {\nlet frag = in.clip;\nvar sx = 0.0;\nvar sz = 0.0;\nvar lost = 0.0;\nvar fold = 0.0;\nlet sf = surf_tex(in.rest, false);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet uv = cc.xy + in.rest * cc.z;\nlet texels = length(fwidth(uv)) * sp.size.x;\nlet resolved = 1.0 - smoothstep(0.5, 2.0, texels);\nlet w = resolved * calm(c, sf.fade);\nlet s = textureSampleLevel(slopes, wrap, uv, c, 0.0);\nsx += s.x * w;\nsz += s.y * w;\nlost += cc.w * (1.0 - resolved) * calm(c, sf.fade);\nfold = max(fold, max(saturate((sp.sea.z - s.z) * 2.0), s.w) * w);\n}\nlet fine = u32(sp.sea.y) - 1u;\nfor (var k = 0u; k < 2u; k++) {\nlet scale = select(8.3, 3.1, k == 0u);\nlet amp = select(0.5, 0.7, k == 0u) * sp.shore.w;\nlet ang = select(1.24, 0.65, k == 0u);\nlet rot = mat2x2f(cos(ang), sin(ang), -sin(ang), cos(ang));\nlet q = rot * (sp.cascade[fine].xy + in.rest * sp.cascade[fine].z) * scale + vec2f(0.37, 0.71) * f32(k + 1u);\nlet resolved = 1.0 - smoothstep(0.5, 2.0, length(fwidth(q)) * sp.size.x);\nlet t = textureSampleLevel(slopes, wrap, q, fine, 0.0).xy * amp;\nlet back = transpose(rot) * t;\nsx += back.x * resolved;\nsz += back.y * resolved;\nlost += sp.cascade[fine].w * amp * amp * (1.0 - resolved);\n}\nsx += sf.slope.x;\nsz += sf.slope.y;\nfold *= sf.fade;\nlet n = normalize(vec3f(-sx, 1.0, -sz));\nlet v = normalize(-in.p);\nlet l = camera.light_dir.xyz;\nlet nv = max(dot(n, v), 1e-3);\nlet nl = max(dot(n, l), 0.0);\nlet dnx = dpdx(n);\nlet dny = dpdy(n);\nlet kernel = min(0.25 * (dot(dnx, dnx) + dot(dny, dny)), 0.18);\nlet a2 = max(sp.body.w * sp.body.w + 2.0 * lost + kernel, 1e-4);\nlet rdx = dpdx(in.rest);\nlet rdy = dpdy(in.rest);\nlet gr = length(in.rest);\nlet ahead = select(vec2f(0.0, 1.0), in.rest / gr, gr > 1e-4);\nlet across = vec2f(-ahead.y, ahead.x);\nlet gpos = vec2f(atan2(in.rest.y, in.rest.x), gr);\nlet gext = vec2f(length(vec2f(dot(rdx, across), dot(rdy, across))), length(vec2f(dot(rdx, ahead), dot(rdy, ahead))));\nlet f0 = 0.02;\nlet fresnel = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0);\nvar r = reflect(-v, n);\nr.y = abs(r.y);\nlet lod = clamp(sqrt(sqrt(a2)) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0);\nvar sky = textureSampleLevel(env_cube, wrap, r, lod).rgb * lighting.view.rgb;\nif (sp.size.z > 0.5) {\nlet pn = vec2f(textureDimensions(cloud_pano));\nlet pv = clamp(sqrt(max(r.y, 0.0)), 0.5 / pn.y, 1.0 - 0.5 / pn.y);\nlet cl = textureSampleLevel(cloud_pano, wrap, vec2f(fract(atan2(r.z, r.x) / (2.0 * PI)), pv), 0.0);\nsky = sky * cl.a + cl.rgb;\n}\nlet seen = mirror_scene(in.p, reflect(-v, n), vec2f(textureDimensions(under)), ign(frag.xy));\nsky = mix(sky, seen.rgb, seen.a);\nif (sp.mirror.w > 0.5) {\nreturn vec4f(select(vec3f(seen.a * 0.2, 0.0, 0.0) + seen.rgb * seen.a, vec3f(0.3, 0.0, 0.0), seen.a <= 0.0) * lighting.env.z, 1.0);\n}\nlet h = normalize(v + l);\nlet nh = max(dot(n, h), 0.0);\nlet dd = nh * nh * (a2 - 1.0) + 1.0;\nlet ggx = a2 / (PI * dd * dd);\nlet vis = 0.5 / (nl * sqrt(nv * nv * (1.0 - a2) + a2) + nv * sqrt(nl * nl * (1.0 - a2) + a2) + 1e-5);\nlet fh = f0 + (1.0 - f0) * pow(1.0 - max(dot(v, h), 0.0), 5.0);\nlet shade = cloud_light(in.p, l);\nlet sun = lighting.sun_color.rgb * shade;\nlet vh = max(dot(v, h), 1e-3);\nlet p_facet = min(ggx * nh * sp.glint.z / (4.0 * vh), 1.0);\nlet spec = sun * (ggx * vis * fh * nl * glint_ratio(gpos, gext, p_facet));\nlet up = sh_irradiance(vec3f(0.0, 1.0, 0.0));\nlet body = sp.body.rgb * (up + sun * (max(l.y, 0.0) / PI) * 0.5);\nlet behind = pow(saturate(dot(-v, l)), 8.0);\nlet crest = saturate(in.height * 0.5) * saturate(1.0 - n.y * 0.9 + 0.2);\nvar sss = sp.sss.rgb * sun * (behind * crest * sp.sss.w);\nlet wide = 0.35 + 0.65 * pow(saturate(dot(-v, l) * 0.5 + 0.5), 3.0);\nlet thin = sf.face * (0.6 + 0.4 * saturate(1.0 - abs(n.y) * 1.2));\nsss += sp.sss.rgb * (up * 4.5 + sun * (0.8 * wide)) * (thin * sp.sss.w * 2.5);\nvar below = body;\nvar shore_foam = 0.0;\nif (sp.shore.y > 0.5) {\nlet px = vec2i(frag.xy);\nlet size = vec2f(textureDimensions(under));\nlet dist = length(in.p);\nlet t0 = thickness(dist, frag.z, textureLoad(under_depth, px, 0).x);\nlet bend = n.xz * sp.optics.w * min(t0, 1.0);\nvar uv = (frag.xy + bend) / size;\nif (any(uv < vec2f(0.0)) || any(uv >= vec2f(1.0))) {\nuv = frag.xy / size;\n}\nvar t = thickness(dist, frag.z, textureLoad(under_depth, vec2i(uv * size), 0).x);\nif (textureLoad(under_depth, vec2i(uv * size), 0).x > frag.z) {\nuv = frag.xy / size;\nt = t0;\n}\nvar behind_light = textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z;\nlet down = max(t * v.y, 0.0);\nlet sun_in = sqrt(max(1.0 - (1.0 - l.y * l.y) / 1.7689, 0.04));\nlet above = (in.p - v * t).xz + vec2f(l.x, l.z) / sun_in * down * (1.0 / 1.33);\nvar lap = 0.0;\nlet cn = u32(sp.sea.y);\nlet c0 = select(0u, cn - 2u, cn >= 2u);\nfor (var c = c0; c < select(c0, select(1u, cn - 1u, cn >= 2u), sp.size.w > 0.5); c++) {\nlet cc = sp.cascade[c];\nlet e = 2.0 / (cc.z * sp.size.x);\nlet q = cc.xy + above * cc.z;\nlet ex = vec2f(cc.z * e, 0.0);\nlet ez = vec2f(0.0, cc.z * e);\nlet dsx = textureSampleLevel(slopes, wrap, q + ex, c, 0.0).x - textureSampleLevel(slopes, wrap, q - ex, c, 0.0).x;\nlet dsz = textureSampleLevel(slopes, wrap, q + ez, c, 0.0).y - textureSampleLevel(slopes, wrap, q - ez, c, 0.0).y;\nlap += (dsx + dsz) / (2.0 * e);\n}\nlet focus = 1.0 / max(abs(1.0 - down * 0.248 * lap), 0.25);\nlet caustic = mix(1.0, focus, saturate(down * 3.0) * exp(-down / 4.0) * saturate(l.y * 4.0) * shade);\nbehind_light *= mix(1.0, caustic, 0.65);\nlet trans = exp(-sp.optics.rgb * (t + down / sun_in));\nbelow = behind_light * trans + body * (vec3f(1.0) - exp(-sp.optics.rgb * t));\nlet vertical = t0 * max(v.y, 0.02);\nshore_foam = saturate(1.0 - vertical / sp.shore.x) * saturate(vertical * 40.0);\nif (sp.surf0.w > 0.5) {\nlet object = saturate((-sf.ground - vertical - 0.15) / 0.3);\nshore_foam = mix(shore_foam, saturate(1.0 - vertical / 0.035) * saturate(vertical * 60.0) * 0.8, object);\n}\n}\nlet sigma = sqrt(lost);\nlet mean_f = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0 * exp(-2.69 * sigma)) / (1.0 + 22.7 * pow(sigma, 1.5));\nlet fr = min(fresnel, mean_f);\nlet water = sky * fr + (below + sss) * (1.0 - fr) + spec;\nlet foam_light = (sh_irradiance(n) + sun * (nl / PI)) * 0.85;\nvar fp = (sp.cascade[0].xy + in.rest * sp.cascade[0].z) / sp.cascade[0].z;\nif (sf.foam > 0.001 || sf.front > 0.001) {\nfp = sf.world;\n}\nlet flow = surf_flow(sf);\nlet cyc = 1.0;\nlet ph0 = fract(sp.surf3.x / cyc);\nlet ph1 = fract(sp.surf3.x / cyc + 0.5);\nlet fp0 = fp - flow * (ph0 * cyc) + vec2f(13.7, 5.1) * floor(sp.surf3.x / cyc);\nlet fp1 = fp - flow * (ph1 * cyc) + vec2f(7.3, 11.9) * floor(sp.surf3.x / cyc + 0.5);\nlet wflow = abs(2.0 * ph0 - 1.0);\nlet beach = smoothstep(0.0, 0.04, sf.ground);\nvar drain = 1.0;\nif (beach > 0.0 && sf.cover > 0.0 && sf.phase > 0.18) {\nlet along = dot(sf.world, sf.dir);\nlet across = dot(sf.world, vec2f(-sf.dir.y, sf.dir.x)) + (vnoise(vec2f(along * 0.6, 0.0)) - 0.5) * 1.4 + (vnoise(vec2f(along * 1.7, 5.0)) - 0.5) * 0.5;\nlet rill = vnoise(vec2f(across * 1.5, along * 0.12)) * 0.6 + vnoise(vec2f(across * 4.3, along * 0.3) + vec2f(17.0, 3.0)) * 0.4;\nlet k = smoothstep(0.2, 0.5, sf.phase) * beach * smoothstep(0.35, 0.65, vnoise(sf.world / 7.0 + vec2f(3.0, 9.0)));\ndrain = mix(1.0, smoothstep(0.38, 0.62, rill), k);\n}\nvar cover = saturate(fold * sp.sea.w + shore_foam * (1.0 - beach) + (sf.foam + sf.front * 0.9) * mix(1.0, drain, beach) + sf.mark * 0.55);\nif (cover > 0.002) {\nlet spots = vnoise(fp * 0.22) * 0.65 + vnoise(fp * 0.61 + vec2f(9.0, 4.0)) * 0.35;\ncover *= mix(smoothstep(0.35, 0.75, spots), 1.0, smoothstep(0.35, 0.8, cover));\nlet clumps = vnoise(fp * 0.35 + vec2f(3.0, 7.0)) * 0.6 + vnoise(fp * 1.1 + vec2f(11.0, 2.0)) * 0.4;\ncover *= mix(1.0, 0.45 + 0.75 * clumps, smoothstep(0.3, 0.7, cover));\n}\nlet fw = length(fwidth(fp0));\nvar foam = 0.0;\nvar bubbles = 1.0;\nif (cover > 0.002) {\nvar net = foam_net(fp0, cover, fw);\nif (dot(flow, flow) > 1e-4) {\nnet = mix(net, foam_net(fp1, cover, fw), wflow);\n}\nfoam = net.x;\nbubbles = net.y;\n}\nlet aerated = saturate(sf.fresh * 1.6) * (1.0 - beach);\nlet milky = mix(sp.sss.rgb * 2.5, vec3f(0.85, 0.95, 0.95), 0.55) * (sh_irradiance(n) + sun * (nl / PI));\nvar foam_lit = foam_light;\nif (foam > 0.01 && sp.surf0.w > 0.5) {\nlet fuv = sp.surf0.xy + in.rest * sp.surf0.z;\nlet ft = 1.0 / vec2f(textureDimensions(surf_d));\nlet gx = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(ft.x, 0.0), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(ft.x, 0.0), 0.0).w;\nlet gz = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(0.0, ft.y), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(0.0, ft.y), 0.0).w;\nlet per_m = 0.1 / (2.0 * ft.x / sp.surf0.z);\nlet nf = normalize(n + vec3f(-gx, 0.0, -gz) * per_m * 0.5);\nfoam_lit = (sh_irradiance(nf) + sun * (max(dot(nf, l), 0.0) / PI)) * 0.85;\n}\nvar lit = mix(mix(water, milky, aerated * 0.65), foam_lit * bubbles, foam);\nif (sf.ground > 0.0 && sp.shore.y > 0.5) {\nlet sand = textureLoad(under, vec2i(frag.xy), 0).rgb * sp.shore.z;\nlet wet_rough = 0.12;\nlet sheen = textureSampleLevel(env_cube, wrap, r, clamp(sqrt(wet_rough) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0)).rgb * lighting.view.rgb;\nlet wet_sand = sand * mix(1.0, 0.5, sf.wet) + sheen * fresnel * sf.wet * 0.8;\nlit = mix(wet_sand, lit, max(sf.cover * drain, foam));\n}\nlet fogged = apply_fog(lit, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(normalize(in.p)), sun, l);\nreturn vec4f(fogged * lighting.env.z, 1.0);\n}\nstruct Camera {\nview_proj: mat4x4f,\nfrustum: array<vec4f, 6>,\nlight_dir: vec4f,\norigin: vec4f,\n}\nstruct Lighting {\nsun_color: vec4f,\nenv: vec4f,\nsh: array<vec4f, 9>,\nscreen: vec4f,\nview: vec4f,\nao_reproject: mat4x4f,\nao: vec4f,\nfog: vec4f,\nfog2: vec4f,\nfog_air: vec4f,\ngi_grid: vec4f,\ngi_counts: vec4f,\nssr: vec4f,\ngi_cascades: array<vec4f, 3>,\nclouds: vec4f,\n}\nfn apply_fog(color: vec3f, p: vec3f, fog: vec4f, fog2: vec4f, air: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet dist = length(p);\nif (dist <= 0.0 || (fog.x <= 0.0 && fog2.x <= 0.0)) {\nreturn color;\n}\nlet dir = p / dist;\nlet t = exp(-(air * (fog2.x * dist) + vec3f(height_fog_depth(fog, dir, dist))));\nreturn color * t + fog_inscatter(fog2, dir, ambient, sun, sun_dir) * (vec3f(1.0) - t);\n}\nfn height_fog_depth(fog: vec4f, dir: vec3f, dist: f32) -> f32 {\nif (fog.x <= 0.0) {\nreturn 0.0;\n}\nlet falloff = max(fog.y, 1e-5);\nlet len = max(dist - fog.w, 0.0);\nlet h0 = fog.z + dir.y * min(dist, fog.w);\nlet k = falloff * dir.y * len;\nlet shape = select((1.0 - exp(-k)) / k, 1.0 - 0.5 * k, abs(k) < 1e-3);\nreturn fog.x * exp(-falloff * h0) * len * shape;\n}\nfn fog_inscatter(fog2: vec4f, dir: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet g = fog2.z;\nlet c = dot(dir, sun_dir);\nlet phase = (1.0 - g * g) / (FOUR_PI * pow(max(1.0 + g * g - 2.0 * g * c, 1e-4), 1.5));\nreturn ambient + sun * (phase * fog2.y);\n}\nconst FOUR_PI = 12.5663706;";
10
10
  };
@@ -7,7 +7,7 @@ export const waterWaves = {
7
7
  };
8
8
  /** Linked from shaders/water/surface.wesl. */
9
9
  export const waterSurface = {
10
- hash: '0d0f44afc28096f2',
11
- wgsl: "const PI = 3.14159265;\nconst EARTH_RADIUS = 6371000.0;\nconst MAX_CASCADES = 4u;\nstruct SurfaceParams {\ncascade: array<vec4f, MAX_CASCADES>,\ngrid: vec4f,\nsea: vec4f,\nbody: vec4f,\nsss: vec4f,\nsize: vec4f,\noptics: vec4f,\nshore: vec4f,\nmirror: vec4f,\nsurf0: vec4f,\nsurf1: vec4f,\nsurf2: vec4f,\nsurf3: vec4f,\n}\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lighting: Lighting;\n@group(0) @binding(2) var<uniform> sp: SurfaceParams;\n@group(0) @binding(3) var displacement: texture_2d_array<f32>;\n@group(0) @binding(4) var slopes: texture_2d_array<f32>;\n@group(0) @binding(5) var wrap: sampler;\n@group(0) @binding(6) var env_cube: texture_cube<f32>;\n@group(0) @binding(7) var under: texture_2d<f32>;\n@group(0) @binding(8) var under_depth: texture_2d<f32>;\n@group(0) @binding(9) var clamp_smp: sampler;\n@group(0) @binding(10) var scene_depth: texture_depth_2d;\n@group(0) @binding(11) var depth_out: texture_storage_2d<r32float, write>;\nstruct WaterMotion {\nview_proj: mat4x4f,\nprev_view_proj: mat4x4f,\neye_move: vec4f,\n}\n@group(0) @binding(12) var prev_displacement: texture_2d_array<f32>;\n@group(0) @binding(13) var<uniform> wm: WaterMotion;\n@group(0) @binding(14) var shore_map: texture_2d<f32>;\n@group(0) @binding(15) var spill_map: texture_2d<f32>;\n@group(0) @binding(16) var cloud_pano: texture_2d<f32>;\nstruct Surf {\nd: vec3f,\nslope: vec2f,\nbroken: f32,\nfoam: f32,\nfade: f32,\nground: f32,\nreach: f32,\ncover: f32,\nwet: f32,\nfilm: f32,\nfront: f32,\nface: f32,\namp: f32,\nworld: vec2f,\ndir: vec2f,\nphase: f32,\nonset: f32,\nfresh: f32,\nfront_h: f32,\nwet_h1: f32,\nwet_h2: f32,\nrun: f32,\n}\nfn pcg(v: u32) -> u32 {\nlet state = v * 747796405u + 2891336453u;\nlet word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\nreturn (word >> 22u) ^ word;\n}\nfn hash1(n: f32) -> f32 {\nreturn f32(pcg(bitcast<u32>(i32(n)))) / 4294967296.0;\n}\nfn hash2(p: vec2f) -> f32 {\nlet q = vec2<i32>(p);\nreturn f32(pcg(bitcast<u32>(q.x) ^ pcg(bitcast<u32>(q.y) + 0x9e3779b9u))) / 4294967296.0;\n}\nfn vnoise(p: vec2f) -> f32 {\nlet i = floor(p);\nlet f = fract(p);\nlet u = f * f * (3.0 - 2.0 * f);\nreturn mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x), mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn worley(p: vec2f) -> vec2f {\nlet i = floor(p);\nlet f = fract(p);\nvar d1 = 8.0;\nvar d2 = 8.0;\nfor (var y = -1; y <= 1; y++) {\nfor (var x = -1; x <= 1; x++) {\nlet o = vec2f(f32(x), f32(y));\nlet c = i + o;\nlet j = vec2f(hash2(c), hash2(c + vec2f(1013.0, 7919.0)));\nlet d = length(o + j - f) / (0.55 + 0.9 * hash2(c + vec2f(4241.0, 557.0)));\nif (d < d1) {\nd2 = d1;\nd1 = d;\n} else if (d < d2) {\nd2 = d;\n}\n}\n}\nreturn vec2f(d1, d2);\n}\nfn foam_net(p: vec2f, amount: f32, fw: f32) -> vec2f {\nlet a = saturate(amount);\nlet q = p + vec2f(vnoise(p * 2.0), vnoise(p * 2.0 + vec2f(5.2, 1.3))) * 0.36;\nlet big = worley(q * 3.2);\nvar small = vec2f(0.5, 1.0);\nif (sp.size.w > 1.5) {\nsmall = worley(q * 10.0 + vec2f(3.7, 1.9));\n}\nlet r = mix(0.82, 0.12, pow(a, 1.1));\nlet eb = fw * 3.2;\nlet es = fw * 10.0;\nlet mean = saturate(1.0 - 2.6 * r * r);\nlet hb = mix(smoothstep(r - 0.05 - eb, r + 0.05 + eb, big.x), mean, smoothstep(0.15, 0.6, eb));\nlet rs = r * 0.8 + 0.1;\nlet hs = mix(smoothstep(rs - 0.06 - es, rs + 0.06 + es, small.x), saturate(1.0 - 2.6 * rs * rs), smoothstep(0.15, 0.6, es));\nlet net = hb * mix(1.0, hs, 0.55 * (1.0 - a));\nlet cover = net * smoothstep(0.0, 0.06, a);\nlet lumps = mix(0.8, 1.04, saturate(1.0 - small.x * 0.9)) * mix(0.9, 1.0, saturate(1.0 - big.x * 0.8));\nlet light = mix(lumps, 0.92, smoothstep(0.15, 0.6, es));\nreturn vec2f(cover, light);\n}\nstruct Train {\nth: f32,\nu: f32,\nnw: f32,\namp: f32,\nshoaled: f32,\nperiod: f32,\nblend: f32,\n}\nconst TRAINS = array<vec4f, 3>(vec4f(1.0, 1.0, 0.0, 0.0), vec4f(1.37, 0.45, 0.0, 0.31), vec4f(0.79, 0.3, 0.0, 0.67));\nfn wobble(n: f32, i: u32, world: vec2f) -> f32 {\nlet o = vec2f(n * 0.61 + f32(i) * 7.0, n * 0.37 + f32(i) * 3.0);\nreturn ((vnoise(world / 45.0 + o) - 0.5) * 1.2 + (vnoise(world / 14.0 + o * 1.7) - 0.5) * 0.35) * sp.surf3.y;\n}\nfn wave_amp(n: f32, world: vec2f) -> f32 {\nlet group = 1.0 + 0.3 * sin(2.0 * PI * n / 6.3 + 1.3) + 0.25 * (hash1(n) - 0.5);\nlet section = 0.6 + 0.8 * vnoise(world / 28.0 + vec2f(n * 7.13, n * 3.71));\nreturn mix(1.0, group * section, sp.surf3.y);\n}\nfn swash_front(u: f32, run: f32) -> f32 {\nlet rise = 0.18;\nlet up = 1.0 - (1.0 - saturate(u / rise)) * (1.0 - saturate(u / rise));\nlet down = pow(saturate(1.0 - (u - rise) / 0.57), 1.6);\nreturn run * select(down, up, u < rise);\n}\nfn swash_high(u: f32, run: f32, window: f32) -> f32 {\nlet rise = 0.18;\nlet u0 = u - window;\nif (u0 >= rise) {\nreturn swash_front(u0, run);\n}\nif (u >= rise) {\nreturn run;\n}\nreturn max(swash_front(u, run), select(0.0, swash_front(u0 + 1.0, run), u0 < 0.0));\n}\nfn swash_state(e: f32, front_h: f32, wet_h1: f32, wet_h2: f32, run: f32) -> vec4f {\nlet cover = saturate((front_h - e) / 0.03);\nlet r1 = saturate((wet_h1 - e) / 0.06 + 0.4);\nlet r2 = saturate((wet_h2 - e) / 0.12 + 0.4);\nlet damp = 0.3 * saturate(1.0 - e / max(run, 1e-3));\nlet wet = max(0.75 * (0.55 * r1 + 0.45 * r2), damp) * saturate((run - e) / 0.08 + 0.5);\nlet film = 0.02 + 0.04 * cover * saturate((front_h - e) / 0.15);\nlet front = cover * (1.0 - saturate((front_h - e) / 0.015)) * saturate(front_h * 6.0);\nreturn vec4f(cover, wet, film, front);\n}\nfn surf_at(rest: vec2f, time: f32) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet sp2 = textureSampleLevel(spill_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\nlet period = sp.surf1.y;\ns.world = uv / sp.surf0.z;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\nlet hs = max(depth, 0.15);\nlet start = sp.surf2.z;\nlet shoal = pow(start / hs, 0.25) * smoothstep(start, start * 0.6, depth);\nlet dir = vec2f(cos(f.w), sin(f.w));\ns.dir = dir;\nvar tr: array<Train, 3>;\nlet trains = select(1u, 3u, sp.size.w > 0.5);\nfor (var i = 0u; i < trains; i++) {\nlet ti = TRAINS[i];\nlet pi = period * ti.x;\nvar th: f32;\nvar u: f32;\nvar nw: f32;\nif (i == 0u) {\nth = 2.0 * PI * fract(time / period) - atan2(f.z, f.y);\nu = fract(th / (2.0 * PI));\nnw = round((time - sp2.y) / period + 0.5 - fract(u + 0.5));\n} else {\nlet cyc = (time - sp2.y) / pi + ti.w;\nu = fract(cyc);\nth = 2.0 * PI * u;\nnw = round(cyc + 0.5 - fract(u + 0.5));\n}\nlet ff = fract(u + 0.5);\nlet blend = smoothstep(0.82, 1.0, ff);\nvar amp = wave_amp(nw + f32(i) * 101.0, s.world);\nvar wob = wobble(nw, i, s.world);\nif (blend > 0.0) {\namp = mix(amp, wave_amp(nw + 1.0 + f32(i) * 101.0, s.world), blend);\nwob = mix(wob, wobble(nw + 1.0, i, s.world), blend);\n}\nth -= wob;\ntr[i].th = th;\ntr[i].u = fract(th / (2.0 * PI));\ntr[i].nw = nw;\ntr[i].amp = amp;\ntr[i].shoaled = sp.surf1.x * ti.y * amp * shoal;\ntr[i].blend = blend;\ntr[i].period = pi;\n}\nlet gnoise = mix(vnoise(s.world / 35.0 + vec2f(tr[0].nw * 2.3, 0.0)), vnoise(s.world / 35.0 + vec2f((tr[0].nw + 1.0) * 2.3, 0.0)), tr[0].blend);\nlet gamma = sp.surf1.z * (0.85 + 0.3 * gnoise * sp.surf3.y + 0.15 * (1.0 - sp.surf3.y));\nlet hb = gamma * hs;\nvar eta = 0.0;\nvar lean = vec2f(0.0);\nvar slope = 0.0;\nvar face_k = 0.0;\nvar foam = 0.0;\ns.broken = 0.0;\ns.onset = 0.0;\nfor (var i = 0u; i < trains; i++) {\nvar others = 0.0;\nfor (var j = 0u; j < trains; j++) {\nif (j != i) {\nothers += 0.4 * tr[j].shoaled * (0.5 + 0.5 * cos(tr[j].th));\n}\n}\nlet ratio = (tr[i].shoaled + others) / max(hb, 1e-3);\nlet broken = saturate((ratio - 1.0) * 3.0);\nlet share = tr[i].shoaled / max(tr[i].shoaled + others, 1e-4);\nlet H = min(tr[i].shoaled, hb * share + tr[i].shoaled * (1.0 - broken)) * smoothstep(-0.05, 0.25, depth);\nlet th = tr[i].th;\nlet u = tr[i].u;\nlet wn = mix(vnoise(s.world / 22.0 + vec2f(tr[i].nw * 5.1, f32(i) * 9.0)), vnoise(s.world / 22.0 + vec2f((tr[i].nw + 1.0) * 5.1, f32(i) * 9.0)), tr[i].blend);\nlet w = 0.12 * mix(1.0, 0.6 + 0.8 * wn, sp.surf3.y);\nlet stokes = 0.5 * (cos(th) + 0.3 * cos(2.0 * th));\nlet dstokes = 0.5 * (-sin(th) - 0.6 * sin(2.0 * th));\nlet bore = select(1.0 - (u - w) / (1.0 - w), u / w, u < w) - 0.5;\nlet dw = min(0.6 * w, 1.2 / (tr[i].period * sqrt(9.81 * hs)));\nlet rise = saturate(0.5 + u / dw) * saturate(0.5 - (u - w) / dw) + saturate(0.5 + (u - 1.0) / dw);\nlet dbore = (-1.0 / (1.0 - w) + (1.0 / w + 1.0 / (1.0 - w)) * rise) / (2.0 * PI);\nvar e = H * mix(stokes, bore, broken);\nlet de = H * mix(dstokes, dbore, broken);\nlet q = sp.surf1.w * (1.0 - 0.6 * broken);\nvar l = dir * (q * H * 0.5 * sin(th));\nlet onset = broken * (1.0 - broken) * 4.0 * saturate((ratio - 0.9) * 10.0);\nlet top = smoothstep(0.1, 0.5, e / max(H, 1e-3));\nl += dir * (sp.surf3.z * H * 0.55 * onset * top);\ne *= 1.0 + 0.25 * onset * top;\nlet k = 2.0 * PI / (tr[i].period * sqrt(9.81 * hs));\neta += e;\nlean += l;\nslope += -k * de;\nface_k += smoothstep(-0.2, 0.45, e / max(H, 1e-3)) * saturate(H * 1.2) * (1.0 - 0.65 * broken + 0.5 * onset) * TRAINS[i].y;\nlet fo = broken * smoothstep(0.0, w, u) * (exp(-(u - w) * 9.0) + 0.15 * exp(-(u - w) * 3.0)) * saturate(H * 3.0) * TRAINS[i].y;\nfoam = 1.0 - (1.0 - foam) * (1.0 - fo);\ns.broken = max(s.broken, broken);\ns.onset = max(s.onset, onset * TRAINS[i].y);\n}\ns.slope = slope * dir;\ns.d = vec3f(lean.x, eta, lean.y);\ns.face = saturate(-slope * 1.5) * saturate(face_k);\ns.foam = foam;\nlet u = tr[0].u;\ns.phase = u;\ns.amp = tr[0].amp;\ns.ground = -depth;\ns.reach = max(sp2.x, s.ground);\nif (s.ground > -0.05) {\nlet e = s.reach;\nlet rn = mix(vnoise(s.world / 9.0 + vec2f(tr[0].nw * 3.3, 1.0)), vnoise(s.world / 9.0 + vec2f((tr[0].nw + 1.0) * 3.3, 1.0)), tr[0].blend);\nlet run = sp.surf1.x * s.amp * 0.8 * mix(1.0, 0.7 + 0.6 * rn, sp.surf3.y);\ns.run = run;\ns.front_h = swash_front(u, run);\ns.wet_h1 = swash_high(u, run, 1.5 / sp.surf1.y);\ns.wet_h2 = swash_high(u, run, 4.0 / sp.surf1.y);\nlet w = swash_state(e, s.front_h, s.wet_h1, s.wet_h2, run);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\nreturn s;\n}\nfn on_beach(d: vec3f, s: Surf, spacing: f32) -> vec3f {\nif (s.ground <= 0.0) {\nreturn d;\n}\nlet reach = sp.surf1.x * 0.8 * 2.0 + 0.05;\nlet y = select(s.ground - 1.0, s.ground + s.film + 0.03 + 0.03 * spacing, s.reach < reach);\nlet k = smoothstep(0.0, 0.04, s.ground);\nreturn vec3f(d.x * (1.0 - k), mix(d.y, y, k), d.z * (1.0 - k));\n}\n@group(0) @binding(17) var surf_a: texture_2d<f32>;\n@group(0) @binding(18) var surf_b: texture_2d<f32>;\n@group(0) @binding(19) var surf_c: texture_2d<f32>;\n@group(0) @binding(20) var surf_d: texture_2d<f32>;\n@group(0) @binding(21) var surf_a_prev: texture_2d<f32>;\n@group(0) @binding(22) var surf_d_prev: texture_2d<f32>;\n@group(0) @binding(23) var out_a: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(24) var out_b: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(25) var out_c: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(26) var out_d: texture_storage_2d<rgba16float, write>;\n@compute @workgroup_size(8, 8) fn surf_field(@builtin(global_invocation_id) id: vec3u) {\nlet n = textureDimensions(out_a);\nif (any(id.xy >= n)) {\nreturn;\n}\nlet uv = (vec2f(id.xy) + 0.5) / vec2f(n);\nlet rest = (uv - sp.surf0.xy) / sp.surf0.z;\nlet s = surf_at(rest, sp.surf3.x);\ntextureStore(out_a, vec2i(id.xy), vec4f(s.d, s.broken));\ntextureStore(out_b, vec2i(id.xy), vec4f(s.slope, s.face, s.onset));\ntextureStore(out_c, vec2i(id.xy), vec4f(s.foam, s.front_h, s.wet_h1, s.wet_h2));\nlet dt = clamp(sp.surf3.x - sp.surf3.w, 0.0, 0.1);\nlet v = surf_flow(s);\nlet extent = 1.0 / sp.surf0.z;\nlet back = uv - v * dt / extent;\nlet texel = 1.0 / vec2f(n);\nlet f0 = textureSampleLevel(surf_d_prev, clamp_smp, back, 0.0).w;\nlet fs = textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(0.0, texel.y), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(0.0, texel.y), 0.0).w;\nlet carried = mix(f0, fs * 0.25, 0.12 * saturate(dt * 60.0));\nlet life = mix(3.0, 1.2, saturate(carried));\nvar f = carried * exp(-dt / life) * select(1.0, 0.0, s.ground > 0.0 && s.cover < 0.01 && s.wet < 0.05) * select(0.0, 1.0, dt > 0.0);\nf = max(f, saturate(s.foam * 0.9 + s.front * 0.8));\ntextureStore(out_d, vec2i(id.xy), vec4f(s.run, s.phase, s.amp, f));\n}\nfn smooth_sample(t: texture_2d<f32>, uv: vec2f) -> vec4f {\nlet size = vec2f(textureDimensions(t));\nlet p = uv * size - 0.5;\nlet i = floor(p);\nlet f = p - i;\nlet w0 = (1.0 - f) * (1.0 - f) * (1.0 - f) / 6.0;\nlet w1 = (4.0 - 6.0 * f * f + 3.0 * f * f * f) / 6.0;\nlet w2 = (1.0 + 3.0 * f + 3.0 * f * f - 3.0 * f * f * f) / 6.0;\nlet w3 = f * f * f / 6.0;\nlet g0 = w0 + w1;\nlet g1 = w2 + w3;\nlet h0 = (i - 0.5 + w1 / g0) / size;\nlet h1 = (i + 1.5 + w3 / g1) / size;\nlet a = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h0.y), 0.0);\nlet b = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h0.y), 0.0);\nlet c = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h1.y), 0.0);\nlet d = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h1.y), 0.0);\nreturn mix(mix(a, b, g1.x), mix(c, d, g1.x), g1.y);\n}\nfn surf_tex(rest: vec2f, prev: bool) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\ns.dir = vec2f(cos(f.w), sin(f.w));\ns.world = uv / sp.surf0.z;\ns.ground = -depth;\ns.reach = max(textureSampleLevel(spill_map, clamp_smp, uv, 0.0).x, s.ground);\nlet a = select(textureSampleLevel(surf_a, clamp_smp, uv, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv, 0.0), prev);\ns.d = a.xyz;\ns.broken = a.w;\nlet b = textureSampleLevel(surf_b, clamp_smp, uv, 0.0);\ns.slope = b.xy;\ns.face = b.z;\ns.onset = b.w;\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nif (s.ground > -0.05) {\nlet e = max(smooth_sample(spill_map, uv).x, -smooth_sample(shore_map, uv).x);\nlet w = swash_state(e, c.y, c.z, c.w, dd.x);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\ns.front_h = c.y;\ns.run = dd.x;\ns.phase = dd.y;\ns.amp = dd.z;\ns.fresh = c.x;\ns.foam = max(c.x, dd.w);\nreturn s;\n}\nfn surf_disp(rest: vec2f, spacing: f32, prev: bool) -> vec3f {\nif (sp.surf0.w < 0.5) {\nreturn vec3f(0.0);\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec3f(0.0);\n}\nlet r = 0.35 * spacing * sp.surf0.z;\nvar d = vec3f(0.0);\nfor (var k = 0u; k < 5u; k++) {\nlet o = array<vec2f, 5>(vec2f(0.0), vec2f(r, 0.0), vec2f(-r, 0.0), vec2f(0.0, r), vec2f(0.0, -r))[k];\nlet w = select(0.125, 0.5, k == 0u);\nlet t = select(textureSampleLevel(surf_a, clamp_smp, uv + o, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv + o, 0.0), prev);\nd += t.xyz * w;\n}\nreturn d;\n}\nfn surf_flow(s: Surf) -> vec2f {\nlet hs = max(-s.ground, 0.15);\nif (s.ground > -0.05) {\nreturn s.dir * select(-0.9, 1.6, s.phase < 0.18) * s.cover;\n}\nreturn s.dir * clamp(sqrt(9.81 * hs) * max(s.d.y, 0.0) / hs, 0.0, 3.0);\n}\nconst SPRAY_SIDE = 192u;\nconst SPRAY_SPACING = 0.75;\nstruct SprayOut {\n@builtin(position) clip: vec4f,\n@location(0) q: vec4f,\n@location(1) p: vec3f,\n}\n@vertex fn vs_spray(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> SprayOut {\nvar o: SprayOut;\no.clip = vec4f(0.0, 0.0, -1.0, 1.0);\nif (sp.surf0.w < 0.5 || sp.size.y <= 0.0) {\nreturn o;\n}\nlet extent = 1.0 / sp.surf0.z;\nlet eye = sp.surf0.xy * extent;\nlet gx = f32(ii % SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet gz = f32(ii / SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet cell = floor(eye / SPRAY_SPACING) + vec2f(gx, gz);\nlet j = vec2f(hash2(cell), hash2(cell + vec2f(91.0, 37.0)));\nlet rest = (cell + j) * SPRAY_SPACING - eye;\nvar s = surf_tex(rest, false);\nlet tuv = sp.surf0.xy + rest * sp.surf0.z;\ns.phase = textureLoad(surf_d, vec2i(clamp(tuv, vec2f(0.0), vec2f(0.9999)) * vec2f(textureDimensions(surf_d))), 0).y;\nlet age = (s.phase - 0.12) * sp.surf1.y;\nlet life = 0.6 + 0.6 * hash2(cell + vec2f(13.0, 71.0));\nif (s.broken < 0.05 || age < 0.0 || age > life || s.ground > 0.3) {\nreturn o;\n}\nlet H = sp.surf1.x * s.amp;\nlet strength = (0.05 * s.broken + s.onset) * saturate(H * 1.2) * (0.4 + 1.2 * hash2(cell + vec2f(5.0, 3.0)));\nlet v0 = (2.0 + 3.0 * hash2(cell + vec2f(2.0, 9.0))) * saturate(H);\nlet k = 1.8;\nlet rise = v0 / k * (1.0 - exp(-k * age)) - 4.0 * age * age * 0.5;\nlet fwd = s.dir * (1.2 * (1.0 - exp(-1.5 * age)));\nlet base = s.d.y + 0.15;\nlet centre = vec3f(rest.x + fwd.x, sp.sea.x + base + max(rise, 0.0), rest.y + fwd.y);\nlet t = age / life;\nlet size = (0.12 + 0.5 * t) * (0.7 + 0.6 * hash2(cell + vec2f(17.0, 23.0))) * (0.6 + 0.6 * saturate(H));\nlet corner = array<vec2f, 6>(vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0))[vi];\nlet fwdv = normalize(centre);\nlet right = normalize(cross(vec3f(0.0, 1.0, 0.0), fwdv));\nlet up = cross(fwdv, right);\nlet pos = centre + (right * corner.x + up * corner.y) * size;\no.clip = camera.view_proj * vec4f(pos, 1.0);\nlet alpha = strength * smoothstep(0.0, 0.1, t) * (1.0 - smoothstep(0.4, 1.0, t)) * sp.size.y * 0.32;\no.q = vec4f(corner, alpha, length(centre));\no.p = centre;\nreturn o;\n}\n@fragment fn fs_spray(in: SprayOut) -> @location(0) vec4f {\nlet r2 = dot(in.q.xy, in.q.xy);\nif (r2 > 1.0) {\ndiscard;\n}\nlet wisp = vnoise(in.q.xy * 1.8 + in.p.xz * 3.1) * 0.6 + vnoise(in.q.xy * 4.3 + in.p.xz * 1.7) * 0.4;\nvar a = in.q.z * (1.0 - r2) * (1.0 - r2) * smoothstep(0.38, 0.62, wisp) * 1.6;\nlet d = textureLoad(under_depth, vec2i(in.clip.xy), 0).x;\nif (d > 0.0) {\nlet gap = in.q.w * (in.clip.z / d - 1.0);\na *= saturate(gap / 0.5);\n}\nlet v = normalize(in.p);\nlet l = camera.light_dir.xyz;\nlet g = 0.75;\nlet cosv = dot(v, l);\nlet hg = (1.0 - g * g) / (4.0 * PI * pow(1.0 + g * g - 2.0 * g * cosv, 1.5));\nlet light = sh_irradiance(vec3f(0.0, 1.0, 0.0)) * 0.6 + lighting.sun_color.rgb * (hg * 3.0 + 0.05);\nlet fogged = apply_fog(light, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(v), lighting.sun_color.rgb, l);\nreturn vec4f(fogged * lighting.env.z * a, a);\n}\nstruct VsOut {\n@builtin(position) clip: vec4f,\n@location(0) p: vec3f,\n@location(1) rest: vec2f,\n@location(2) height: f32,\n}\nfn ring_radius(i: f32) -> f32 {\nlet k = sp.grid.y;\nreturn sp.grid.x * (pow(1.0 + k, i) - 1.0) / k;\n}\nfn grid_point(vi: u32) -> vec3f {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nreturn vec3f(vec2f(cos(a), sin(a)) * r, max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs)));\n}\nfn calm(c: u32, fade: f32) -> f32 {\nreturn mix(1.0, fade, saturate(1.0 / (sp.cascade[c].z * 150.0)));\n}\nfn displaced(field: texture_2d_array<f32>, rest: vec2f, spacing: f32, fade: f32) -> vec3f {\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(field, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nreturn d;\n}\nstruct MotionOut {\n@builtin(position) clip: vec4f,\n@location(0) now: vec4f,\n@location(1) then: vec4f,\n}\n@vertex fn vs_motion(@builtin(vertex_index) vi: u32) -> MotionOut {\nlet g = grid_point(vi);\nlet rest = g.xy;\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet sn = surf_tex(rest, false);\nlet sq = surf_tex(rest, wm.eye_move.w > 0.5);\nlet dn = on_beach(displaced(displacement, rest, g.z, sn.fade) + surf_disp(rest, g.z, false), sn, g.z);\nlet dp = select(dn, on_beach(displaced(prev_displacement, rest, g.z, sq.fade) + surf_disp(rest, g.z, true), sq, g.z), wm.eye_move.w > 0.5);\nlet p = vec3f(rest.x + dn.x, sp.sea.x + dn.y - drop, rest.y + dn.z);\nlet q = vec3f(rest.x + dp.x, sp.sea.x + dp.y - drop, rest.y + dp.z) + wm.eye_move.xyz;\nvar o: MotionOut;\no.now = wm.view_proj * vec4f(p, 1.0);\no.clip = camera.view_proj * vec4f(p, 1.0);\no.then = wm.prev_view_proj * vec4f(q, 1.0);\nreturn o;\n}\n@fragment fn fs_motion(in: MotionOut) -> @location(0) vec4f {\nlet now = in.now.xy / in.now.w;\nlet then = in.then.xy / max(in.then.w, 1e-6);\nreturn vec4f((now - then) * vec2f(0.5, -0.5), in.then.w, 1.0);\n}\n@vertex fn vs(@builtin(vertex_index) vi: u32) -> VsOut {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nlet rest = vec2f(cos(a), sin(a)) * r;\nlet spacing = max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs));\nlet sf = surf_tex(rest, false);\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, sf.fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(displacement, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nd = on_beach(d + surf_disp(rest, spacing, false), sf, spacing);\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet p = vec3f(rest.x + d.x, sp.sea.x + d.y - drop, rest.y + d.z);\nvar o: VsOut;\no.clip = camera.view_proj * vec4f(p, 1.0);\no.p = p;\no.rest = rest;\no.height = d.y;\nreturn o;\n}\nfn sh_irradiance(n: vec3f) -> vec3f {\nreturn max(lighting.sh[0].rgb * 0.282095 + lighting.sh[1].rgb * (0.488603 * n.y) + lighting.sh[2].rgb * (0.488603 * n.z) + lighting.sh[3].rgb * (0.488603 * n.x) + lighting.sh[4].rgb * (1.092548 * n.x * n.y) + lighting.sh[5].rgb * (1.092548 * n.y * n.z) + lighting.sh[6].rgb * (0.315392 * (3.0 * n.z * n.z - 1.0)) + lighting.sh[7].rgb * (1.092548 * n.x * n.z) + lighting.sh[8].rgb * (0.546274 * (n.x * n.x - n.y * n.y)), vec3f(0.0));\n}\n@compute @workgroup_size(8, 8) fn copy_depth(@builtin(global_invocation_id) id: vec3u) {\nlet size = textureDimensions(scene_depth);\nif (id.x >= size.x || id.y >= size.y) {\nreturn;\n}\ntextureStore(depth_out, vec2i(id.xy), vec4f(textureLoad(scene_depth, vec2i(id.xy), 0), 0.0, 0.0, 0.0));\n}\nfn thickness(dist: f32, ds: f32, dop: f32) -> f32 {\nreturn select(1.0e9, dist * max(ds / dop - 1.0, 0.0), dop > 0.0);\n}\nfn mirror_probe(p: vec3f, r: vec3f, t: f32, size: vec2f) -> vec4f {\nlet c = camera.view_proj * vec4f(p + r * t, 1.0);\nif (c.w <= 0.0) {\nreturn vec4f(0.0);\n}\nlet ndc = c.xyz / c.w;\nlet uv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec4f(0.0);\n}\nlet d = textureLoad(under_depth, vec2i(uv * size), 0).x;\nlet gap = select(-1.0e9, c.w * (1.0 - ndc.z / d), d > 0.0);\nreturn vec4f(uv, gap, 1.0);\n}\nfn mirror_scene(p: vec3f, r: vec3f, size: vec2f, jitter: f32) -> vec4f {\nlet len = sp.mirror.x;\nlet steps = u32(sp.mirror.y);\nif (len <= 0.0 || steps == 0u || sp.shore.y < 0.5 || r.y <= 0.0) {\nreturn vec4f(0.0);\n}\nvar prev = 0.0;\nvar was_behind = false;\nfor (var i = 1u; i <= steps; i++) {\nlet f = (f32(i) - jitter) / f32(steps);\nlet t = len * f * f;\nlet s = mirror_probe(p, r, t, size);\nif (s.w < 0.5) {\nbreak;\n}\nlet behind = s.z > 0.0;\nif (behind && !was_behind) {\nvar a = prev;\nvar b = t;\nvar hit = s;\nfor (var k = 0u; k < 6u; k++) {\nlet m = 0.5 * (a + b);\nlet sm = mirror_probe(p, r, m, size);\nif (sm.w > 0.5 && sm.z > 0.0) {\nb = m;\nhit = sm;\n} else {\na = m;\n}\n}\nif (hit.z < sp.mirror.z + 0.03 * b) {\nlet uv = hit.xy;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nlet fade = saturate(edge * 12.0) * (1.0 - smoothstep(0.7, 1.0, b / len));\nreturn vec4f(textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z, fade);\n}\n}\nwas_behind = behind;\nprev = t;\n}\nreturn vec4f(0.0);\n}\nfn ign(px: vec2f) -> f32 {\nlet frame = floor(camera.light_dir.w * 60.0) % 64.0;\nlet q = px + 5.588238 * frame;\nreturn fract(52.9829189 * fract(dot(q, vec2f(0.06711056, 0.00583715))));\n}\n@fragment fn fs(in: VsOut) -> @location(0) vec4f {\nlet frag = in.clip;\nvar sx = 0.0;\nvar sz = 0.0;\nvar lost = 0.0;\nvar fold = 0.0;\nlet sf = surf_tex(in.rest, false);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet uv = cc.xy + in.rest * cc.z;\nlet texels = length(fwidth(uv)) * sp.size.x;\nlet resolved = 1.0 - smoothstep(0.5, 2.0, texels);\nlet w = resolved * calm(c, sf.fade);\nlet s = textureSampleLevel(slopes, wrap, uv, c, 0.0);\nsx += s.x * w;\nsz += s.y * w;\nlost += cc.w * (1.0 - resolved) * calm(c, sf.fade);\nfold = max(fold, max(saturate((sp.sea.z - s.z) * 2.0), s.w) * w);\n}\nlet fine = u32(sp.sea.y) - 1u;\nfor (var k = 0u; k < 2u; k++) {\nlet scale = select(8.3, 3.1, k == 0u);\nlet amp = select(0.5, 0.7, k == 0u) * sp.shore.w;\nlet ang = select(1.24, 0.65, k == 0u);\nlet rot = mat2x2f(cos(ang), sin(ang), -sin(ang), cos(ang));\nlet q = rot * (sp.cascade[fine].xy + in.rest * sp.cascade[fine].z) * scale + vec2f(0.37, 0.71) * f32(k + 1u);\nlet resolved = 1.0 - smoothstep(0.5, 2.0, length(fwidth(q)) * sp.size.x);\nlet t = textureSampleLevel(slopes, wrap, q, fine, 0.0).xy * amp;\nlet back = transpose(rot) * t;\nsx += back.x * resolved;\nsz += back.y * resolved;\nlost += sp.cascade[fine].w * amp * amp * (1.0 - resolved);\n}\nsx += sf.slope.x;\nsz += sf.slope.y;\nfold *= sf.fade;\nlet n = normalize(vec3f(-sx, 1.0, -sz));\nlet v = normalize(-in.p);\nlet l = camera.light_dir.xyz;\nlet nv = max(dot(n, v), 1e-3);\nlet nl = max(dot(n, l), 0.0);\nlet a2 = max(sp.body.w * sp.body.w + 2.0 * lost, 1e-4);\nlet f0 = 0.02;\nlet fresnel = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0);\nvar r = reflect(-v, n);\nr.y = abs(r.y);\nlet lod = clamp(sqrt(sqrt(a2)) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0);\nvar sky = textureSampleLevel(env_cube, wrap, r, lod).rgb * lighting.view.rgb;\nif (sp.size.z > 0.5) {\nlet pn = vec2f(textureDimensions(cloud_pano));\nlet pv = clamp(sqrt(max(r.y, 0.0)), 0.5 / pn.y, 1.0 - 0.5 / pn.y);\nlet cl = textureSampleLevel(cloud_pano, wrap, vec2f(fract(atan2(r.z, r.x) / (2.0 * PI)), pv), 0.0);\nsky = sky * cl.a + cl.rgb;\n}\nlet seen = mirror_scene(in.p, reflect(-v, n), vec2f(textureDimensions(under)), ign(frag.xy));\nsky = mix(sky, seen.rgb, seen.a);\nif (sp.mirror.w > 0.5) {\nreturn vec4f(select(vec3f(seen.a * 0.2, 0.0, 0.0) + seen.rgb * seen.a, vec3f(0.3, 0.0, 0.0), seen.a <= 0.0) * lighting.env.z, 1.0);\n}\nlet h = normalize(v + l);\nlet nh = max(dot(n, h), 0.0);\nlet dd = nh * nh * (a2 - 1.0) + 1.0;\nlet ggx = a2 / (PI * dd * dd);\nlet vis = 0.5 / (nl * sqrt(nv * nv * (1.0 - a2) + a2) + nv * sqrt(nl * nl * (1.0 - a2) + a2) + 1e-5);\nlet fh = f0 + (1.0 - f0) * pow(1.0 - max(dot(v, h), 0.0), 5.0);\nlet sun = lighting.sun_color.rgb;\nlet spec = sun * (ggx * vis * fh * nl);\nlet up = sh_irradiance(vec3f(0.0, 1.0, 0.0));\nlet body = sp.body.rgb * (up + sun * (max(l.y, 0.0) / PI) * 0.5);\nlet behind = pow(saturate(dot(-v, l)), 8.0);\nlet crest = saturate(in.height * 0.5) * saturate(1.0 - n.y * 0.9 + 0.2);\nvar sss = sp.sss.rgb * sun * (behind * crest * sp.sss.w);\nlet wide = 0.35 + 0.65 * pow(saturate(dot(-v, l) * 0.5 + 0.5), 3.0);\nlet thin = sf.face * (0.6 + 0.4 * saturate(1.0 - abs(n.y) * 1.2));\nsss += sp.sss.rgb * (up * 4.5 + sun * (0.8 * wide)) * (thin * sp.sss.w * 2.5);\nvar below = body;\nvar shore_foam = 0.0;\nif (sp.shore.y > 0.5) {\nlet px = vec2i(frag.xy);\nlet size = vec2f(textureDimensions(under));\nlet dist = length(in.p);\nlet t0 = thickness(dist, frag.z, textureLoad(under_depth, px, 0).x);\nlet bend = n.xz * sp.optics.w * min(t0, 1.0);\nvar uv = (frag.xy + bend) / size;\nif (any(uv < vec2f(0.0)) || any(uv >= vec2f(1.0))) {\nuv = frag.xy / size;\n}\nvar t = thickness(dist, frag.z, textureLoad(under_depth, vec2i(uv * size), 0).x);\nif (textureLoad(under_depth, vec2i(uv * size), 0).x > frag.z) {\nuv = frag.xy / size;\nt = t0;\n}\nvar behind_light = textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z;\nlet down = max(t * v.y, 0.0);\nlet sun_in = sqrt(max(1.0 - (1.0 - l.y * l.y) / 1.7689, 0.04));\nlet above = (in.p - v * t).xz + vec2f(l.x, l.z) / sun_in * down * (1.0 / 1.33);\nvar lap = 0.0;\nlet cn = u32(sp.sea.y);\nlet c0 = select(0u, cn - 2u, cn >= 2u);\nfor (var c = c0; c < select(c0, select(1u, cn - 1u, cn >= 2u), sp.size.w > 0.5); c++) {\nlet cc = sp.cascade[c];\nlet e = 2.0 / (cc.z * sp.size.x);\nlet q = cc.xy + above * cc.z;\nlet ex = vec2f(cc.z * e, 0.0);\nlet ez = vec2f(0.0, cc.z * e);\nlet dsx = textureSampleLevel(slopes, wrap, q + ex, c, 0.0).x - textureSampleLevel(slopes, wrap, q - ex, c, 0.0).x;\nlet dsz = textureSampleLevel(slopes, wrap, q + ez, c, 0.0).y - textureSampleLevel(slopes, wrap, q - ez, c, 0.0).y;\nlap += (dsx + dsz) / (2.0 * e);\n}\nlet focus = 1.0 / max(abs(1.0 - down * 0.248 * lap), 0.25);\nlet caustic = mix(1.0, focus, saturate(down * 3.0) * exp(-down / 4.0) * saturate(l.y * 4.0));\nbehind_light *= mix(1.0, caustic, 0.65);\nlet trans = exp(-sp.optics.rgb * (t + down / sun_in));\nbelow = behind_light * trans + body * (vec3f(1.0) - exp(-sp.optics.rgb * t));\nlet vertical = t0 * max(v.y, 0.02);\nshore_foam = saturate(1.0 - vertical / sp.shore.x) * saturate(vertical * 40.0);\n}\nlet sigma = sqrt(lost);\nlet mean_f = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0 * exp(-2.69 * sigma)) / (1.0 + 22.7 * pow(sigma, 1.5));\nlet fr = min(fresnel, mean_f);\nlet water = sky * fr + (below + sss) * (1.0 - fr) + spec;\nlet foam_light = (sh_irradiance(n) + sun * (nl / PI)) * 0.85;\nvar fp = (sp.cascade[0].xy + in.rest * sp.cascade[0].z) / sp.cascade[0].z;\nif (sf.foam > 0.001 || sf.front > 0.001) {\nfp = sf.world;\n}\nlet flow = surf_flow(sf);\nlet cyc = 1.0;\nlet ph0 = fract(sp.surf3.x / cyc);\nlet ph1 = fract(sp.surf3.x / cyc + 0.5);\nlet fp0 = fp - flow * (ph0 * cyc) + vec2f(13.7, 5.1) * floor(sp.surf3.x / cyc);\nlet fp1 = fp - flow * (ph1 * cyc) + vec2f(7.3, 11.9) * floor(sp.surf3.x / cyc + 0.5);\nlet wflow = abs(2.0 * ph0 - 1.0);\nlet beach = smoothstep(0.0, 0.04, sf.ground);\nvar cover = saturate(fold * sp.sea.w + shore_foam * (1.0 - beach) + sf.foam + sf.front * 0.9);\nif (cover > 0.002) {\nlet spots = vnoise(fp * 0.22) * 0.65 + vnoise(fp * 0.61 + vec2f(9.0, 4.0)) * 0.35;\ncover *= mix(smoothstep(0.35, 0.75, spots), 1.0, smoothstep(0.35, 0.8, cover));\nlet clumps = vnoise(fp * 0.35 + vec2f(3.0, 7.0)) * 0.6 + vnoise(fp * 1.1 + vec2f(11.0, 2.0)) * 0.4;\ncover *= mix(1.0, 0.45 + 0.75 * clumps, smoothstep(0.3, 0.7, cover));\n}\nlet fw = length(fwidth(fp0));\nvar foam = 0.0;\nvar bubbles = 1.0;\nif (cover > 0.002) {\nvar net = foam_net(fp0, cover, fw);\nif (dot(flow, flow) > 1e-4) {\nnet = mix(net, foam_net(fp1, cover, fw), wflow);\n}\nfoam = net.x;\nbubbles = net.y;\n}\nlet aerated = saturate(sf.fresh * 1.6) * (1.0 - beach);\nlet milky = mix(sp.sss.rgb * 2.5, vec3f(0.85, 0.95, 0.95), 0.55) * (sh_irradiance(n) + sun * (nl / PI));\nvar foam_lit = foam_light;\nif (foam > 0.01 && sp.surf0.w > 0.5) {\nlet fuv = sp.surf0.xy + in.rest * sp.surf0.z;\nlet ft = 1.0 / vec2f(textureDimensions(surf_d));\nlet gx = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(ft.x, 0.0), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(ft.x, 0.0), 0.0).w;\nlet gz = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(0.0, ft.y), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(0.0, ft.y), 0.0).w;\nlet per_m = 0.1 / (2.0 * ft.x / sp.surf0.z);\nlet nf = normalize(n + vec3f(-gx, 0.0, -gz) * per_m * 0.5);\nfoam_lit = (sh_irradiance(nf) + sun * (max(dot(nf, l), 0.0) / PI)) * 0.85;\n}\nvar lit = mix(mix(water, milky, aerated * 0.65), foam_lit * bubbles, foam);\nif (sf.ground > 0.0 && sp.shore.y > 0.5) {\nlet sand = textureLoad(under, vec2i(frag.xy), 0).rgb * sp.shore.z;\nlet wet_rough = 0.12;\nlet sheen = textureSampleLevel(env_cube, wrap, r, clamp(sqrt(wet_rough) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0)).rgb * lighting.view.rgb;\nlet wet_sand = sand * mix(1.0, 0.5, sf.wet) + sheen * fresnel * sf.wet * 0.8;\nlit = mix(wet_sand, lit, max(sf.cover, foam));\n}\nlet fogged = apply_fog(lit, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(normalize(in.p)), sun, l);\nreturn vec4f(fogged * lighting.env.z, 1.0);\n}\nstruct Camera {\nview_proj: mat4x4f,\nfrustum: array<vec4f, 6>,\nlight_dir: vec4f,\norigin: vec4f,\n}\nstruct Lighting {\nsun_color: vec4f,\nenv: vec4f,\nsh: array<vec4f, 9>,\nscreen: vec4f,\nview: vec4f,\nao_reproject: mat4x4f,\nao: vec4f,\nfog: vec4f,\nfog2: vec4f,\nfog_air: vec4f,\ngi_grid: vec4f,\ngi_counts: vec4f,\nssr: vec4f,\ngi_cascades: array<vec4f, 3>,\n}\nfn apply_fog(color: vec3f, p: vec3f, fog: vec4f, fog2: vec4f, air: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet dist = length(p);\nif (dist <= 0.0 || (fog.x <= 0.0 && fog2.x <= 0.0)) {\nreturn color;\n}\nlet dir = p / dist;\nlet t = exp(-(air * (fog2.x * dist) + vec3f(height_fog_depth(fog, dir, dist))));\nreturn color * t + fog_inscatter(fog2, dir, ambient, sun, sun_dir) * (vec3f(1.0) - t);\n}\nfn height_fog_depth(fog: vec4f, dir: vec3f, dist: f32) -> f32 {\nif (fog.x <= 0.0) {\nreturn 0.0;\n}\nlet falloff = max(fog.y, 1e-5);\nlet len = max(dist - fog.w, 0.0);\nlet h0 = fog.z + dir.y * min(dist, fog.w);\nlet k = falloff * dir.y * len;\nlet shape = select((1.0 - exp(-k)) / k, 1.0 - 0.5 * k, abs(k) < 1e-3);\nreturn fog.x * exp(-falloff * h0) * len * shape;\n}\nfn fog_inscatter(fog2: vec4f, dir: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet g = fog2.z;\nlet c = dot(dir, sun_dir);\nlet phase = (1.0 - g * g) / (FOUR_PI * pow(max(1.0 + g * g - 2.0 * g * c, 1e-4), 1.5));\nreturn ambient + sun * (phase * fog2.y);\n}\nconst FOUR_PI = 12.5663706;",
10
+ hash: 'b6a83798dfc992f7',
11
+ wgsl: "const PI = 3.14159265;\nconst EARTH_RADIUS = 6371000.0;\nconst MAX_CASCADES = 4u;\nstruct SurfaceParams {\ncascade: array<vec4f, MAX_CASCADES>,\ngrid: vec4f,\nsea: vec4f,\nbody: vec4f,\nsss: vec4f,\nsize: vec4f,\noptics: vec4f,\nshore: vec4f,\nmirror: vec4f,\nsurf0: vec4f,\nsurf1: vec4f,\nsurf2: vec4f,\nsurf3: vec4f,\nglint: vec4f,\ncshadow: vec4f,\n}\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lighting: Lighting;\n@group(0) @binding(2) var<uniform> sp: SurfaceParams;\n@group(0) @binding(3) var displacement: texture_2d_array<f32>;\n@group(0) @binding(4) var slopes: texture_2d_array<f32>;\n@group(0) @binding(5) var wrap: sampler;\n@group(0) @binding(6) var env_cube: texture_cube<f32>;\n@group(0) @binding(7) var under: texture_2d<f32>;\n@group(0) @binding(8) var under_depth: texture_2d<f32>;\n@group(0) @binding(9) var clamp_smp: sampler;\n@group(0) @binding(10) var scene_depth: texture_depth_2d;\n@group(0) @binding(11) var depth_out: texture_storage_2d<r32float, write>;\nstruct WaterMotion {\nview_proj: mat4x4f,\nprev_view_proj: mat4x4f,\neye_move: vec4f,\nreactive: vec4f,\n}\n@group(0) @binding(12) var prev_displacement: texture_2d_array<f32>;\n@group(0) @binding(13) var<uniform> wm: WaterMotion;\n@group(0) @binding(14) var shore_map: texture_2d<f32>;\n@group(0) @binding(15) var spill_map: texture_2d<f32>;\n@group(0) @binding(16) var cloud_pano: texture_2d<f32>;\n@group(0) @binding(27) var cloud_shadow: texture_2d<f32>;\nfn cloud_light(p: vec3f, l: vec3f) -> f32 {\nif (sp.cshadow.w < 0.5) {\nreturn 1.0;\n}\nlet at = p - l * ((p.y - sp.sea.x) / max(l.y, 0.05));\nlet uv = (at.xz - sp.cshadow.xy) * sp.cshadow.z + 0.5;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nreturn mix(1.0, textureSampleLevel(cloud_shadow, clamp_smp, uv, 0.0).r, saturate(edge * 16.0));\n}\nstruct Surf {\nd: vec3f,\nslope: vec2f,\nbroken: f32,\nfoam: f32,\nfade: f32,\nground: f32,\nreach: f32,\ncover: f32,\nwet: f32,\nfilm: f32,\nfront: f32,\nface: f32,\namp: f32,\nworld: vec2f,\ndir: vec2f,\nphase: f32,\nonset: f32,\nfresh: f32,\nfront_h: f32,\nwet_h1: f32,\nwet_h2: f32,\nrun: f32,\nmark: f32,\n}\nfn pcg(v: u32) -> u32 {\nlet state = v * 747796405u + 2891336453u;\nlet word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;\nreturn (word >> 22u) ^ word;\n}\nfn hash1(n: f32) -> f32 {\nreturn f32(pcg(bitcast<u32>(i32(n)))) / 4294967296.0;\n}\nfn hash2(p: vec2f) -> f32 {\nlet q = vec2<i32>(p);\nreturn f32(pcg(bitcast<u32>(q.x) ^ pcg(bitcast<u32>(q.y) + 0x9e3779b9u))) / 4294967296.0;\n}\nfn vnoise(p: vec2f) -> f32 {\nlet i = floor(p);\nlet f = fract(p);\nlet u = f * f * (3.0 - 2.0 * f);\nreturn mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x), mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn worley(p: vec2f) -> vec2f {\nlet i = floor(p);\nlet f = fract(p);\nvar d1 = 8.0;\nvar d2 = 8.0;\nfor (var y = -1; y <= 1; y++) {\nfor (var x = -1; x <= 1; x++) {\nlet o = vec2f(f32(x), f32(y));\nlet c = i + o;\nlet j = vec2f(hash2(c), hash2(c + vec2f(1013.0, 7919.0)));\nlet d = length(o + j - f) / (0.55 + 0.9 * hash2(c + vec2f(4241.0, 557.0)));\nif (d < d1) {\nd2 = d1;\nd1 = d;\n} else if (d < d2) {\nd2 = d;\n}\n}\n}\nreturn vec2f(d1, d2);\n}\nfn foam_net(p: vec2f, amount: f32, fw: f32) -> vec2f {\nlet a = saturate(amount);\nlet q = p + vec2f(vnoise(p * 2.0), vnoise(p * 2.0 + vec2f(5.2, 1.3))) * 0.36;\nlet big = worley(q * 3.2);\nvar small = vec2f(0.5, 1.0);\nif (sp.size.w > 1.5) {\nsmall = worley(q * 10.0 + vec2f(3.7, 1.9));\n}\nlet r = mix(0.82, 0.12, pow(a, 1.1));\nlet eb = fw * 3.2;\nlet es = fw * 10.0;\nlet mean = saturate(1.0 - 2.6 * r * r);\nlet hb = mix(smoothstep(r - 0.05 - eb, r + 0.05 + eb, big.x), mean, smoothstep(0.15, 0.6, eb));\nlet rs = r * 0.8 + 0.1;\nlet hs = mix(smoothstep(rs - 0.06 - es, rs + 0.06 + es, small.x), saturate(1.0 - 2.6 * rs * rs), smoothstep(0.15, 0.6, es));\nlet net = hb * mix(1.0, hs, 0.55 * (1.0 - a));\nlet cover = net * smoothstep(0.0, 0.06, a);\nlet lumps = mix(0.8, 1.04, saturate(1.0 - small.x * 0.9)) * mix(0.9, 1.0, saturate(1.0 - big.x * 0.8));\nlet light = mix(lumps, 0.92, smoothstep(0.15, 0.6, es));\nreturn vec2f(cover, light);\n}\nstruct Train {\nth: f32,\nu: f32,\nnw: f32,\namp: f32,\nshoaled: f32,\nperiod: f32,\nblend: f32,\n}\nconst TRAINS = array<vec4f, 3>(vec4f(1.0, 1.0, 0.0, 0.0), vec4f(1.37, 0.45, 0.0, 0.31), vec4f(0.79, 0.3, 0.0, 0.67));\nfn wobble(n: f32, i: u32, world: vec2f) -> f32 {\nlet o = vec2f(n * 0.61 + f32(i) * 7.0, n * 0.37 + f32(i) * 3.0);\nreturn ((vnoise(world / 45.0 + o) - 0.5) * 1.2 + (vnoise(world / 14.0 + o * 1.7) - 0.5) * 0.35) * sp.surf3.y;\n}\nfn wave_amp(n: f32, world: vec2f) -> f32 {\nlet group = 1.0 + 0.3 * sin(2.0 * PI * n / 6.3 + 1.3) + 0.25 * (hash1(n) - 0.5);\nlet section = 0.6 + 0.8 * vnoise(world / 28.0 + vec2f(n * 7.13, n * 3.71));\nreturn mix(1.0, group * section, sp.surf3.y);\n}\nfn swash_front(u: f32, run: f32) -> f32 {\nlet rise = 0.18;\nlet up = 1.0 - (1.0 - saturate(u / rise)) * (1.0 - saturate(u / rise));\nlet down = pow(saturate(1.0 - (u - rise) / 0.57), 1.6);\nreturn run * select(down, up, u < rise);\n}\nfn swash_high(u: f32, run: f32, window: f32) -> f32 {\nlet rise = 0.18;\nlet u0 = u - window;\nif (u0 >= rise) {\nreturn swash_front(u0, run);\n}\nif (u >= rise) {\nreturn run;\n}\nreturn max(swash_front(u, run), select(0.0, swash_front(u0 + 1.0, run), u0 < 0.0));\n}\nfn swash_state(e: f32, front_h: f32, wet_h1: f32, wet_h2: f32, run: f32) -> vec4f {\nlet cover = saturate((front_h - e) / 0.03);\nlet r1 = saturate((wet_h1 - e) / 0.06 + 0.4);\nlet r2 = saturate((wet_h2 - e) / 0.12 + 0.4);\nlet damp = 0.3 * saturate(1.0 - e / max(run, 1e-3));\nlet wet = max(0.75 * (0.55 * r1 + 0.45 * r2), damp) * saturate((run - e) / 0.08 + 0.5);\nlet film = 0.02 + 0.04 * cover * saturate((front_h - e) / 0.15);\nlet front = cover * (1.0 - saturate((front_h - e) / 0.015)) * saturate(front_h * 6.0);\nreturn vec4f(cover, wet, film, front);\n}\nfn surf_at(rest: vec2f, time: f32) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet sp2 = textureSampleLevel(spill_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\nlet period = sp.surf1.y;\ns.world = uv / sp.surf0.z;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\nlet hs = max(depth, 0.15);\nlet start = sp.surf2.z;\nlet shoal = pow(start / hs, 0.25) * smoothstep(start, start * 0.6, depth);\nlet dir = vec2f(cos(f.w), sin(f.w));\ns.dir = dir;\nvar tr: array<Train, 3>;\nlet trains = select(1u, 3u, sp.size.w > 0.5);\nfor (var i = 0u; i < trains; i++) {\nlet ti = TRAINS[i];\nlet pi = period * ti.x;\nvar th: f32;\nvar u: f32;\nvar nw: f32;\nif (i == 0u) {\nth = 2.0 * PI * fract(time / period) - atan2(f.z, f.y);\nu = fract(th / (2.0 * PI));\nnw = round((time - sp2.y) / period + 0.5 - fract(u + 0.5));\n} else {\nlet cyc = (time - sp2.y) / pi + ti.w;\nu = fract(cyc);\nth = 2.0 * PI * u;\nnw = round(cyc + 0.5 - fract(u + 0.5));\n}\nlet ff = fract(u + 0.5);\nlet blend = smoothstep(0.82, 1.0, ff);\nvar amp = wave_amp(nw + f32(i) * 101.0, s.world);\nvar wob = wobble(nw, i, s.world);\nif (blend > 0.0) {\namp = mix(amp, wave_amp(nw + 1.0 + f32(i) * 101.0, s.world), blend);\nwob = mix(wob, wobble(nw + 1.0, i, s.world), blend);\n}\nth -= wob;\ntr[i].th = th;\ntr[i].u = fract(th / (2.0 * PI));\ntr[i].nw = nw;\ntr[i].amp = amp;\ntr[i].shoaled = sp.surf1.x * ti.y * amp * shoal;\ntr[i].blend = blend;\ntr[i].period = pi;\n}\nlet gnoise = mix(vnoise(s.world / 35.0 + vec2f(tr[0].nw * 2.3, 0.0)), vnoise(s.world / 35.0 + vec2f((tr[0].nw + 1.0) * 2.3, 0.0)), tr[0].blend);\nlet gamma = sp.surf1.z * (0.85 + 0.3 * gnoise * sp.surf3.y + 0.15 * (1.0 - sp.surf3.y));\nlet hb = gamma * hs;\nvar eta = 0.0;\nvar lean = vec2f(0.0);\nvar slope = 0.0;\nvar face_k = 0.0;\nvar foam = 0.0;\ns.broken = 0.0;\ns.onset = 0.0;\nfor (var i = 0u; i < trains; i++) {\nvar others = 0.0;\nfor (var j = 0u; j < trains; j++) {\nif (j != i) {\nothers += 0.4 * tr[j].shoaled * (0.5 + 0.5 * cos(tr[j].th));\n}\n}\nlet ratio = (tr[i].shoaled + others) / max(hb, 1e-3);\nlet broken = saturate((ratio - 1.0) * 3.0);\nlet share = tr[i].shoaled / max(tr[i].shoaled + others, 1e-4);\nlet H = min(tr[i].shoaled, hb * share + tr[i].shoaled * (1.0 - broken)) * smoothstep(-0.05, 0.25, depth);\nlet th = tr[i].th;\nlet u = tr[i].u;\nlet wn = mix(vnoise(s.world / 22.0 + vec2f(tr[i].nw * 5.1, f32(i) * 9.0)), vnoise(s.world / 22.0 + vec2f((tr[i].nw + 1.0) * 5.1, f32(i) * 9.0)), tr[i].blend);\nlet w = 0.12 * mix(1.0, 0.6 + 0.8 * wn, sp.surf3.y);\nlet stokes = 0.5 * (cos(th) + 0.3 * cos(2.0 * th));\nlet dstokes = 0.5 * (-sin(th) - 0.6 * sin(2.0 * th));\nlet bore = select(1.0 - (u - w) / (1.0 - w), u / w, u < w) - 0.5;\nlet dw = min(0.6 * w, 1.2 / (tr[i].period * sqrt(9.81 * hs)));\nlet rise = saturate(0.5 + u / dw) * saturate(0.5 - (u - w) / dw) + saturate(0.5 + (u - 1.0) / dw);\nlet dbore = (-1.0 / (1.0 - w) + (1.0 / w + 1.0 / (1.0 - w)) * rise) / (2.0 * PI);\nvar e = H * mix(stokes, bore, broken);\nlet de = H * mix(dstokes, dbore, broken);\nlet q = sp.surf1.w * (1.0 - 0.6 * broken);\nvar l = dir * (q * H * 0.5 * sin(th));\nlet onset = broken * (1.0 - broken) * 4.0 * saturate((ratio - 0.9) * 10.0);\nlet top = smoothstep(0.1, 0.5, e / max(H, 1e-3));\nl += dir * (sp.surf3.z * H * 0.55 * onset * top);\ne *= 1.0 + 0.25 * onset * top;\nlet k = 2.0 * PI / (tr[i].period * sqrt(9.81 * hs));\neta += e;\nlean += l;\nslope += -k * de;\nface_k += smoothstep(-0.2, 0.45, e / max(H, 1e-3)) * saturate(H * 1.2) * (1.0 - 0.65 * broken + 0.5 * onset) * TRAINS[i].y;\nlet fo = broken * smoothstep(0.0, w, u) * (exp(-(u - w) * 9.0) + 0.15 * exp(-(u - w) * 3.0)) * saturate(H * 3.0) * TRAINS[i].y;\nfoam = 1.0 - (1.0 - foam) * (1.0 - fo);\ns.broken = max(s.broken, broken);\ns.onset = max(s.onset, onset * TRAINS[i].y);\n}\ns.slope = slope * dir;\ns.d = vec3f(lean.x, eta, lean.y);\ns.face = saturate(-slope * 1.5) * saturate(face_k);\ns.foam = foam;\nlet u = tr[0].u;\ns.phase = u;\ns.amp = tr[0].amp;\ns.ground = -depth;\ns.reach = max(sp2.x, s.ground);\nif (s.ground > -0.05) {\nlet e = s.reach;\nlet rn = mix(vnoise(s.world / 9.0 + vec2f(tr[0].nw * 3.3, 1.0)), vnoise(s.world / 9.0 + vec2f((tr[0].nw + 1.0) * 3.3, 1.0)), tr[0].blend);\nlet run = sp.surf1.x * s.amp * 0.8 * mix(1.0, 0.7 + 0.6 * rn, sp.surf3.y);\ns.run = run;\ns.front_h = swash_front(u, run);\ns.wet_h1 = swash_high(u, run, 1.5 / sp.surf1.y);\ns.wet_h2 = swash_high(u, run, 4.0 / sp.surf1.y);\nlet w = swash_state(e, s.front_h, s.wet_h1, s.wet_h2, run);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\n}\nreturn s;\n}\nfn on_beach(d: vec3f, s: Surf, spacing: f32) -> vec3f {\nif (s.ground <= 0.0) {\nreturn d;\n}\nlet reach = sp.surf1.x * 0.8 * 2.0 + 0.05;\nlet y = select(s.ground - 1.0, s.ground + s.film + 0.03 + 0.03 * spacing, s.reach < reach);\nlet k = smoothstep(0.0, 0.04, s.ground);\nreturn vec3f(d.x * (1.0 - k), mix(d.y, y, k), d.z * (1.0 - k));\n}\n@group(0) @binding(17) var surf_a: texture_2d<f32>;\n@group(0) @binding(18) var surf_b: texture_2d<f32>;\n@group(0) @binding(19) var surf_c: texture_2d<f32>;\n@group(0) @binding(20) var surf_d: texture_2d<f32>;\n@group(0) @binding(21) var surf_a_prev: texture_2d<f32>;\n@group(0) @binding(22) var surf_d_prev: texture_2d<f32>;\n@group(0) @binding(23) var out_a: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(24) var out_b: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(25) var out_c: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(26) var out_d: texture_storage_2d<rgba16float, write>;\n@compute @workgroup_size(8, 8) fn surf_field(@builtin(global_invocation_id) id: vec3u) {\nlet n = textureDimensions(out_a);\nif (any(id.xy >= n)) {\nreturn;\n}\nlet uv = (vec2f(id.xy) + 0.5) / vec2f(n);\nlet rest = (uv - sp.surf0.xy) / sp.surf0.z;\nlet s = surf_at(rest, sp.surf3.x);\ntextureStore(out_a, vec2i(id.xy), vec4f(s.d, s.broken));\ntextureStore(out_b, vec2i(id.xy), vec4f(s.slope, s.face, s.onset));\ntextureStore(out_c, vec2i(id.xy), vec4f(s.foam, s.front_h, s.wet_h1, s.wet_h2));\nlet dt = clamp(sp.surf3.x - sp.surf3.w, 0.0, 0.1);\nlet v = surf_flow(s);\nlet extent = 1.0 / sp.surf0.z;\nlet back = uv - v * dt / extent;\nlet texel = 1.0 / vec2f(n);\nlet f0 = textureSampleLevel(surf_d_prev, clamp_smp, back, 0.0).w;\nlet fs = textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(texel.x, 0.0), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back + vec2f(0.0, texel.y), 0.0).w + textureSampleLevel(surf_d_prev, clamp_smp, back - vec2f(0.0, texel.y), 0.0).w;\nlet carried = mix(f0, fs * 0.25, 0.12 * saturate(dt * 60.0));\nlet life = mix(3.0, 1.2, saturate(carried));\nvar f = carried * exp(-dt / life) * select(1.0, 0.0, s.ground > 0.0 && s.cover < 0.01 && s.wet < 0.05) * select(0.0, 1.0, dt > 0.0);\nf = max(f, saturate(s.foam * 0.9 + s.front * 0.8));\ntextureStore(out_d, vec2i(id.xy), vec4f(s.run, s.phase, s.amp, f));\n}\nfn smooth_sample(t: texture_2d<f32>, uv: vec2f) -> vec4f {\nlet size = vec2f(textureDimensions(t));\nlet p = uv * size - 0.5;\nlet i = floor(p);\nlet f = p - i;\nlet w0 = (1.0 - f) * (1.0 - f) * (1.0 - f) / 6.0;\nlet w1 = (4.0 - 6.0 * f * f + 3.0 * f * f * f) / 6.0;\nlet w2 = (1.0 + 3.0 * f + 3.0 * f * f - 3.0 * f * f * f) / 6.0;\nlet w3 = f * f * f / 6.0;\nlet g0 = w0 + w1;\nlet g1 = w2 + w3;\nlet h0 = (i - 0.5 + w1 / g0) / size;\nlet h1 = (i + 1.5 + w3 / g1) / size;\nlet a = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h0.y), 0.0);\nlet b = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h0.y), 0.0);\nlet c = textureSampleLevel(t, clamp_smp, vec2f(h0.x, h1.y), 0.0);\nlet d = textureSampleLevel(t, clamp_smp, vec2f(h1.x, h1.y), 0.0);\nreturn mix(mix(a, b, g1.x), mix(c, d, g1.x), g1.y);\n}\nfn surf_tex(rest: vec2f, prev: bool) -> Surf {\nvar s: Surf;\ns.fade = 1.0;\ns.amp = 1.0;\nif (sp.surf0.w < 0.5) {\nreturn s;\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn s;\n}\nlet f = textureSampleLevel(shore_map, clamp_smp, uv, 0.0);\nlet depth = f.x;\ns.fade = smoothstep(0.2, sp.surf2.y, depth);\ns.dir = vec2f(cos(f.w), sin(f.w));\ns.world = uv / sp.surf0.z;\ns.ground = -depth;\ns.reach = max(textureSampleLevel(spill_map, clamp_smp, uv, 0.0).x, s.ground);\nlet a = select(textureSampleLevel(surf_a, clamp_smp, uv, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv, 0.0), prev);\ns.d = a.xyz;\ns.broken = a.w;\nlet b = textureSampleLevel(surf_b, clamp_smp, uv, 0.0);\ns.slope = b.xy;\ns.face = b.z;\ns.onset = b.w;\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nif (s.ground > -0.05) {\nlet e = max(smooth_sample(spill_map, uv).x, -smooth_sample(shore_map, uv).x);\nlet w = swash_state(e, c.y, c.z, c.w, dd.x);\ns.cover = w.x;\ns.wet = w.y;\ns.film = w.z;\ns.front = w.w;\nlet band = saturate(1.0 - abs(c.w - 0.008 - e) / 0.012);\nlet age = saturate(1.0 - (c.w - c.z) / max(dd.x * 0.6, 0.02));\ns.mark = band * (1.0 - w.x) * mix(0.35, 1.0, age) * saturate(c.w * 8.0);\n}\ns.front_h = c.y;\ns.run = dd.x;\ns.phase = dd.y;\ns.amp = dd.z;\ns.fresh = c.x;\ns.foam = max(c.x, dd.w);\nreturn s;\n}\nfn surf_disp(rest: vec2f, spacing: f32, prev: bool) -> vec3f {\nif (sp.surf0.w < 0.5) {\nreturn vec3f(0.0);\n}\nlet uv = sp.surf0.xy + rest * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec3f(0.0);\n}\nlet r = 0.35 * spacing * sp.surf0.z;\nvar d = vec3f(0.0);\nfor (var k = 0u; k < 5u; k++) {\nlet o = array<vec2f, 5>(vec2f(0.0), vec2f(r, 0.0), vec2f(-r, 0.0), vec2f(0.0, r), vec2f(0.0, -r))[k];\nlet w = select(0.125, 0.5, k == 0u);\nlet t = select(textureSampleLevel(surf_a, clamp_smp, uv + o, 0.0), textureSampleLevel(surf_a_prev, clamp_smp, uv + o, 0.0), prev);\nd += t.xyz * w;\n}\nreturn d;\n}\nfn surf_flow(s: Surf) -> vec2f {\nlet hs = max(-s.ground, 0.15);\nif (s.ground > -0.05) {\nreturn s.dir * select(-0.9, 1.6, s.phase < 0.18) * s.cover;\n}\nreturn s.dir * clamp(sqrt(9.81 * hs) * max(s.d.y, 0.0) / hs, 0.0, 3.0);\n}\nconst SPRAY_SIDE = 192u;\nconst SPRAY_SPACING = 0.75;\nstruct SprayOut {\n@builtin(position) clip: vec4f,\n@location(0) q: vec4f,\n@location(1) p: vec3f,\n}\n@vertex fn vs_spray(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> SprayOut {\nvar o: SprayOut;\no.clip = vec4f(0.0, 0.0, -1.0, 1.0);\nif (sp.surf0.w < 0.5 || sp.size.y <= 0.0) {\nreturn o;\n}\nlet extent = 1.0 / sp.surf0.z;\nlet eye = sp.surf0.xy * extent;\nlet gx = f32(ii % SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet gz = f32(ii / SPRAY_SIDE) - f32(SPRAY_SIDE / 2u);\nlet cell = floor(eye / SPRAY_SPACING) + vec2f(gx, gz);\nlet j = vec2f(hash2(cell), hash2(cell + vec2f(91.0, 37.0)));\nlet rest = (cell + j) * SPRAY_SPACING - eye;\nvar s = surf_tex(rest, false);\nlet tuv = sp.surf0.xy + rest * sp.surf0.z;\ns.phase = textureLoad(surf_d, vec2i(clamp(tuv, vec2f(0.0), vec2f(0.9999)) * vec2f(textureDimensions(surf_d))), 0).y;\nlet age = (s.phase - 0.12) * sp.surf1.y;\nlet life = 0.6 + 0.6 * hash2(cell + vec2f(13.0, 71.0));\nif (s.broken < 0.05 || age < 0.0 || age > life || s.ground > 0.3) {\nreturn o;\n}\nlet H = sp.surf1.x * s.amp;\nlet strength = (0.05 * s.broken + s.onset) * saturate(H * 1.2) * (0.4 + 1.2 * hash2(cell + vec2f(5.0, 3.0)));\nlet v0 = (2.0 + 3.0 * hash2(cell + vec2f(2.0, 9.0))) * saturate(H);\nlet k = 1.8;\nlet rise = v0 / k * (1.0 - exp(-k * age)) - 4.0 * age * age * 0.5;\nlet fwd = s.dir * (1.2 * (1.0 - exp(-1.5 * age)));\nlet base = s.d.y + 0.15;\nlet centre = vec3f(rest.x + fwd.x, sp.sea.x + base + max(rise, 0.0), rest.y + fwd.y);\nlet t = age / life;\nlet size = (0.12 + 0.5 * t) * (0.7 + 0.6 * hash2(cell + vec2f(17.0, 23.0))) * (0.6 + 0.6 * saturate(H));\nlet corner = array<vec2f, 6>(vec2f(-1.0, -1.0), vec2f(1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, -1.0), vec2f(1.0, 1.0), vec2f(-1.0, 1.0))[vi];\nlet fwdv = normalize(centre);\nlet right = normalize(cross(vec3f(0.0, 1.0, 0.0), fwdv));\nlet up = cross(fwdv, right);\nlet pos = centre + (right * corner.x + up * corner.y) * size;\no.clip = camera.view_proj * vec4f(pos, 1.0);\nlet alpha = strength * smoothstep(0.0, 0.1, t) * (1.0 - smoothstep(0.4, 1.0, t)) * sp.size.y * 0.32;\no.q = vec4f(corner, alpha, length(centre));\no.p = centre;\nreturn o;\n}\nfn spray_alpha(in: SprayOut) -> f32 {\nlet r2 = dot(in.q.xy, in.q.xy);\nif (r2 > 1.0) {\nreturn 0.0;\n}\nlet wisp = vnoise(in.q.xy * 1.8 + in.p.xz * 3.1) * 0.6 + vnoise(in.q.xy * 4.3 + in.p.xz * 1.7) * 0.4;\nreturn in.q.z * (1.0 - r2) * (1.0 - r2) * smoothstep(0.38, 0.62, wisp) * 1.6;\n}\n@fragment fn fs_spray_reactive(in: SprayOut) -> @location(0) vec4f {\nlet a = spray_alpha(in);\nif (a <= 0.002) {\ndiscard;\n}\nreturn vec4f(saturate(a * 2.0) * wm.reactive.x);\n}\n@fragment fn fs_spray(in: SprayOut) -> @location(0) vec4f {\nvar a = spray_alpha(in);\nif (a <= 0.0) {\ndiscard;\n}\nlet d = textureLoad(under_depth, vec2i(in.clip.xy), 0).x;\nif (d > 0.0) {\nlet gap = in.q.w * (in.clip.z / d - 1.0);\na *= saturate(gap / 0.5);\n}\nlet v = normalize(in.p);\nlet l = camera.light_dir.xyz;\nlet g = 0.75;\nlet cosv = dot(v, l);\nlet hg = (1.0 - g * g) / (4.0 * PI * pow(1.0 + g * g - 2.0 * g * cosv, 1.5));\nlet light = sh_irradiance(vec3f(0.0, 1.0, 0.0)) * 0.6 + lighting.sun_color.rgb * cloud_light(in.p, l) * (hg * 3.0 + 0.05);\nlet fogged = apply_fog(light, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(v), lighting.sun_color.rgb, l);\nreturn vec4f(fogged * lighting.env.z * a, a);\n}\nstruct VsOut {\n@builtin(position) clip: vec4f,\n@location(0) p: vec3f,\n@location(1) rest: vec2f,\n@location(2) height: f32,\n}\nfn ring_radius(i: f32) -> f32 {\nlet k = sp.grid.y;\nreturn sp.grid.x * (pow(1.0 + k, i) - 1.0) / k;\n}\nfn grid_point(vi: u32) -> vec3f {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nreturn vec3f(vec2f(cos(a), sin(a)) * r, max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs)));\n}\nfn calm(c: u32, fade: f32) -> f32 {\nreturn mix(1.0, fade, saturate(1.0 / (sp.cascade[c].z * 150.0)));\n}\nfn displaced(field: texture_2d_array<f32>, rest: vec2f, spacing: f32, fade: f32) -> vec3f {\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(field, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nreturn d;\n}\nstruct MotionOut {\n@builtin(position) clip: vec4f,\n@location(0) now: vec4f,\n@location(1) then: vec4f,\n@location(2) rest: vec2f,\n}\n@vertex fn vs_motion(@builtin(vertex_index) vi: u32) -> MotionOut {\nlet g = grid_point(vi);\nlet rest = g.xy;\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet sn = surf_tex(rest, false);\nlet sq = surf_tex(rest, wm.eye_move.w > 0.5);\nlet dn = on_beach(displaced(displacement, rest, g.z, sn.fade) + surf_disp(rest, g.z, false), sn, g.z);\nlet dp = select(dn, on_beach(displaced(prev_displacement, rest, g.z, sq.fade) + surf_disp(rest, g.z, true), sq, g.z), wm.eye_move.w > 0.5);\nlet p = vec3f(rest.x + dn.x, sp.sea.x + dn.y - drop, rest.y + dn.z);\nlet q = vec3f(rest.x + dp.x, sp.sea.x + dp.y - drop, rest.y + dp.z) + wm.eye_move.xyz;\nvar o: MotionOut;\no.now = wm.view_proj * vec4f(p, 1.0);\no.clip = camera.view_proj * vec4f(p, 1.0);\no.then = wm.prev_view_proj * vec4f(q, 1.0);\no.rest = rest;\nreturn o;\n}\nfn motion_of(in: MotionOut) -> vec4f {\nlet now = in.now.xy / in.now.w;\nlet then = in.then.xy / max(in.then.w, 1e-6);\nreturn vec4f((now - then) * vec2f(0.5, -0.5), in.then.w, 1.0);\n}\n@fragment fn fs_motion(in: MotionOut) -> @location(0) vec4f {\nreturn motion_of(in);\n}\nstruct MotionReactive {\n@location(0) motion: vec4f,\n@location(1) reactive: vec4f,\n}\n@fragment fn fs_motion_reactive(in: MotionOut) -> MotionReactive {\nvar o: MotionReactive;\no.motion = motion_of(in);\nlet s = surf_tex(in.rest, false);\no.reactive = vec4f(saturate(s.fresh * 0.9 + s.front * 0.7 + s.onset * 0.6) * wm.reactive.x);\nreturn o;\n}\n@vertex fn vs(@builtin(vertex_index) vi: u32) -> VsOut {\nlet segs = u32(sp.grid.w);\nlet ring = f32(vi / (segs + 1u));\nlet seg = f32(vi % (segs + 1u));\nlet r = ring_radius(ring);\nlet a = 2.0 * PI * seg / f32(segs);\nlet rest = vec2f(cos(a), sin(a)) * r;\nlet spacing = max(ring_radius(ring + 1.0) - r, 2.0 * PI * r / f32(segs));\nlet sf = surf_tex(rest, false);\nvar d = vec3f(0.0);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet texel = 1.0 / (cc.z * sp.size.x);\nlet w = (1.0 - smoothstep(1.0, 4.0, spacing / texel)) * calm(c, sf.fade);\nif (w <= 0.0) {\ncontinue;\n}\nd += textureSampleLevel(displacement, wrap, cc.xy + rest * cc.z, c, 0.0).xyz * w;\n}\nd = on_beach(d + surf_disp(rest, spacing, false), sf, spacing);\nlet drop = dot(rest, rest) / (2.0 * EARTH_RADIUS);\nlet p = vec3f(rest.x + d.x, sp.sea.x + d.y - drop, rest.y + d.z);\nvar o: VsOut;\no.clip = camera.view_proj * vec4f(p, 1.0);\no.p = p;\no.rest = rest;\no.height = d.y;\nreturn o;\n}\nfn sh_irradiance(n: vec3f) -> vec3f {\nreturn max(lighting.sh[0].rgb * 0.282095 + lighting.sh[1].rgb * (0.488603 * n.y) + lighting.sh[2].rgb * (0.488603 * n.z) + lighting.sh[3].rgb * (0.488603 * n.x) + lighting.sh[4].rgb * (1.092548 * n.x * n.y) + lighting.sh[5].rgb * (1.092548 * n.y * n.z) + lighting.sh[6].rgb * (0.315392 * (3.0 * n.z * n.z - 1.0)) + lighting.sh[7].rgb * (1.092548 * n.x * n.z) + lighting.sh[8].rgb * (0.546274 * (n.x * n.x - n.y * n.y)), vec3f(0.0));\n}\n@compute @workgroup_size(8, 8) fn copy_depth(@builtin(global_invocation_id) id: vec3u) {\nlet size = textureDimensions(scene_depth);\nif (id.x >= size.x || id.y >= size.y) {\nreturn;\n}\ntextureStore(depth_out, vec2i(id.xy), vec4f(textureLoad(scene_depth, vec2i(id.xy), 0), 0.0, 0.0, 0.0));\n}\nfn thickness(dist: f32, ds: f32, dop: f32) -> f32 {\nreturn select(1.0e9, dist * max(ds / dop - 1.0, 0.0), dop > 0.0);\n}\nfn mirror_probe(p: vec3f, r: vec3f, t: f32, size: vec2f) -> vec4f {\nlet c = camera.view_proj * vec4f(p + r * t, 1.0);\nif (c.w <= 0.0) {\nreturn vec4f(0.0);\n}\nlet ndc = c.xyz / c.w;\nlet uv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\nreturn vec4f(0.0);\n}\nlet d = textureLoad(under_depth, vec2i(uv * size), 0).x;\nlet gap = select(-1.0e9, c.w * (1.0 - ndc.z / d), d > 0.0);\nreturn vec4f(uv, gap, 1.0);\n}\nfn mirror_scene(p: vec3f, r: vec3f, size: vec2f, jitter: f32) -> vec4f {\nlet len = sp.mirror.x;\nlet steps = u32(sp.mirror.y);\nif (len <= 0.0 || steps == 0u || sp.shore.y < 0.5 || r.y <= 0.0) {\nreturn vec4f(0.0);\n}\nvar prev = 0.0;\nvar was_behind = false;\nfor (var i = 1u; i <= steps; i++) {\nlet f = (f32(i) - jitter) / f32(steps);\nlet t = len * f * f;\nlet s = mirror_probe(p, r, t, size);\nif (s.w < 0.5) {\nbreak;\n}\nlet behind = s.z > 0.0;\nif (behind && !was_behind) {\nvar a = prev;\nvar b = t;\nvar hit = s;\nfor (var k = 0u; k < 6u; k++) {\nlet m = 0.5 * (a + b);\nlet sm = mirror_probe(p, r, m, size);\nif (sm.w > 0.5 && sm.z > 0.0) {\nb = m;\nhit = sm;\n} else {\na = m;\n}\n}\nif (hit.z < sp.mirror.z + 0.03 * b) {\nlet uv = hit.xy;\nlet edge = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\nlet fade = saturate(edge * 12.0) * (1.0 - smoothstep(0.7, 1.0, b / len));\nreturn vec4f(textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z, fade);\n}\n}\nwas_behind = behind;\nprev = t;\n}\nreturn vec4f(0.0);\n}\nstruct WetParams { inv_view_proj: mat4x4f }\n@group(0) @binding(28) var<uniform> wp: WetParams;\nstruct WetOut { @builtin(position) clip: vec4f }\n@vertex fn vs_wet(@builtin(vertex_index) i: u32) -> WetOut {\nlet p = vec2f(f32((i << 1u) & 2u), f32(i & 2u)) * 2.0 - 1.0;\nvar o: WetOut;\no.clip = vec4f(p, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs_wet(in: WetOut) -> @location(0) vec4f {\nlet px = vec2i(in.clip.xy);\nlet d = textureLoad(scene_depth, px, 0);\nif (d <= 0.0 || sp.surf0.w < 0.5) {\ndiscard;\n}\nlet size = vec2f(textureDimensions(scene_depth));\nlet ndc = vec2f(in.clip.x / size.x * 2.0 - 1.0, 1.0 - in.clip.y / size.y * 2.0);\nlet w4 = wp.inv_view_proj * vec4f(ndc, d, 1.0);\nlet p = w4.xyz / w4.w;\nlet uv = sp.surf0.xy + p.xz * sp.surf0.z;\nif (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\ndiscard;\n}\nlet h = p.y - sp.sea.x;\nlet ground = -smooth_sample(shore_map, uv).x;\nif (h < ground + 0.05) {\ndiscard;\n}\nlet c = textureSampleLevel(surf_c, clamp_smp, uv, 0.0);\nlet dd = textureSampleLevel(surf_d, clamp_smp, uv, 0.0);\nlet wash = select(sp.surf1.x * 0.6 * dd.z, 0.0, ground > 0.0);\nlet world = uv / sp.surf0.z;\nlet ragged = (vnoise(world * 3.0) - 0.5) * 0.12 + (vnoise(vec2f(world.x * 9.0, world.y * 9.0) + vec2f(5.0, 1.0)) - 0.5) * 0.05;\nlet top = max(c.w, wash) + ragged;\nlet drip = smoothstep(0.55, 0.9, vnoise(vec2f(world.x * 14.0 + world.y * 14.0, 0.5))) * 0.08;\nlet wet = (1.0 - smoothstep(top - 0.02, top + 0.04 + drip, h)) * saturate(top * 6.0);\nif (wet <= 0.001) {\ndiscard;\n}\nreturn vec4f(vec3f(mix(1.0, 0.58, wet)), 1.0);\n}\nfn ign(px: vec2f) -> f32 {\nlet frame = floor(camera.light_dir.w * 60.0) % 64.0;\nlet q = px + 5.588238 * frame;\nreturn fract(52.9829189 * fract(dot(q, vec2f(0.06711056, 0.00583715))));\n}\nfn glint_hash(c: vec2i, lod: i32, bucket: i32, s: u32) -> f32 {\nlet h = pcg(bitcast<u32>(c.x) ^ pcg(bitcast<u32>(c.y) ^ pcg(bitcast<u32>(lod * 7919 + bucket) + s * 0x9e3779b9u)));\nreturn f32(h) / 4294967296.0;\n}\nfn poisson(mu: f32, u: f32, g: vec3f) -> f32 {\nif (mu > 12.0) {\nreturn max(0.0, round(mu + sqrt(mu) * (g.x + g.y + g.z - 1.5) * 2.0));\n}\nvar k = 0.0;\nvar pk = exp(-mu);\nvar cdf = pk;\nfor (var i = 0u; i < 32u; i++) {\nif (u <= cdf) {\nbreak;\n}\nk += 1.0;\npk *= mu / k;\ncdf += pk;\n}\nreturn k;\n}\nfn glint_level(w: vec2f, size: vec2f, lod: i32, mu: f32) -> f32 {\nlet c = vec2i(floor(w / size));\nlet t = sp.surf3.x / sp.glint.w;\nvar sum = 0.0;\nfor (var j = 0; j < 2; j++) {\nlet phase = t + 0.5 * f32(j);\nlet bucket = i32(floor(phase)) * 2 + j;\nlet wt = 1.0 - abs(2.0 * fract(phase) - 1.0);\nlet k = poisson(mu, glint_hash(c, lod, bucket, 0u), vec3f(glint_hash(c, lod, bucket, 1u), glint_hash(c, lod, bucket, 2u), glint_hash(c, lod, bucket, 3u)));\nsum += wt * k / max(mu, 1e-12);\n}\nreturn sum;\n}\nconst GLINT_ANGLE = 1.0e-5;\nfn glint_ratio(w: vec2f, ext: vec2f, p: f32) -> f32 {\nif (sp.glint.x <= 0.0 || p <= 0.0) {\nreturn 1.0;\n}\nlet facet = sp.glint.y;\nlet r = max(w.y, 1e-3);\nlet facets = ext.x * ext.y / (facet * facet);\nlet level = vec2f(log2(max(ext.x / (r * GLINT_ANGLE), 1.0)), log2(max(ext.y / facet, 1.0)));\nlet l0 = floor(level);\nlet f = level - l0;\nlet s0 = vec2f(GLINT_ANGLE, facet) * exp2(l0);\nlet mu = s0.x * r * s0.y / (facet * facet) * p;\nlet id = i32(l0.x) * 64 + i32(l0.y);\nlet r0 = mix(glint_level(w, s0, id, mu), glint_level(w, s0 * vec2f(2.0, 1.0), id + 64, mu * 2.0), f.x);\nlet r1 = mix(glint_level(w, s0 * vec2f(1.0, 2.0), id + 1, mu * 2.0), glint_level(w, s0 * 2.0, id + 65, mu * 4.0), f.x);\nreturn mix(1.0, mix(r0, r1, f.y), sp.glint.x * smoothstep(1.0, 16.0, facets));\n}\n@fragment fn fs(in: VsOut) -> @location(0) vec4f {\nlet frag = in.clip;\nvar sx = 0.0;\nvar sz = 0.0;\nvar lost = 0.0;\nvar fold = 0.0;\nlet sf = surf_tex(in.rest, false);\nfor (var c = 0u; c < u32(sp.sea.y); c++) {\nlet cc = sp.cascade[c];\nlet uv = cc.xy + in.rest * cc.z;\nlet texels = length(fwidth(uv)) * sp.size.x;\nlet resolved = 1.0 - smoothstep(0.5, 2.0, texels);\nlet w = resolved * calm(c, sf.fade);\nlet s = textureSampleLevel(slopes, wrap, uv, c, 0.0);\nsx += s.x * w;\nsz += s.y * w;\nlost += cc.w * (1.0 - resolved) * calm(c, sf.fade);\nfold = max(fold, max(saturate((sp.sea.z - s.z) * 2.0), s.w) * w);\n}\nlet fine = u32(sp.sea.y) - 1u;\nfor (var k = 0u; k < 2u; k++) {\nlet scale = select(8.3, 3.1, k == 0u);\nlet amp = select(0.5, 0.7, k == 0u) * sp.shore.w;\nlet ang = select(1.24, 0.65, k == 0u);\nlet rot = mat2x2f(cos(ang), sin(ang), -sin(ang), cos(ang));\nlet q = rot * (sp.cascade[fine].xy + in.rest * sp.cascade[fine].z) * scale + vec2f(0.37, 0.71) * f32(k + 1u);\nlet resolved = 1.0 - smoothstep(0.5, 2.0, length(fwidth(q)) * sp.size.x);\nlet t = textureSampleLevel(slopes, wrap, q, fine, 0.0).xy * amp;\nlet back = transpose(rot) * t;\nsx += back.x * resolved;\nsz += back.y * resolved;\nlost += sp.cascade[fine].w * amp * amp * (1.0 - resolved);\n}\nsx += sf.slope.x;\nsz += sf.slope.y;\nfold *= sf.fade;\nlet n = normalize(vec3f(-sx, 1.0, -sz));\nlet v = normalize(-in.p);\nlet l = camera.light_dir.xyz;\nlet nv = max(dot(n, v), 1e-3);\nlet nl = max(dot(n, l), 0.0);\nlet dnx = dpdx(n);\nlet dny = dpdy(n);\nlet kernel = min(0.25 * (dot(dnx, dnx) + dot(dny, dny)), 0.18);\nlet a2 = max(sp.body.w * sp.body.w + 2.0 * lost + kernel, 1e-4);\nlet rdx = dpdx(in.rest);\nlet rdy = dpdy(in.rest);\nlet gr = length(in.rest);\nlet ahead = select(vec2f(0.0, 1.0), in.rest / gr, gr > 1e-4);\nlet across = vec2f(-ahead.y, ahead.x);\nlet gpos = vec2f(atan2(in.rest.y, in.rest.x), gr);\nlet gext = vec2f(length(vec2f(dot(rdx, across), dot(rdy, across))), length(vec2f(dot(rdx, ahead), dot(rdy, ahead))));\nlet f0 = 0.02;\nlet fresnel = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0);\nvar r = reflect(-v, n);\nr.y = abs(r.y);\nlet lod = clamp(sqrt(sqrt(a2)) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0);\nvar sky = textureSampleLevel(env_cube, wrap, r, lod).rgb * lighting.view.rgb;\nif (sp.size.z > 0.5) {\nlet pn = vec2f(textureDimensions(cloud_pano));\nlet pv = clamp(sqrt(max(r.y, 0.0)), 0.5 / pn.y, 1.0 - 0.5 / pn.y);\nlet cl = textureSampleLevel(cloud_pano, wrap, vec2f(fract(atan2(r.z, r.x) / (2.0 * PI)), pv), 0.0);\nsky = sky * cl.a + cl.rgb;\n}\nlet seen = mirror_scene(in.p, reflect(-v, n), vec2f(textureDimensions(under)), ign(frag.xy));\nsky = mix(sky, seen.rgb, seen.a);\nif (sp.mirror.w > 0.5) {\nreturn vec4f(select(vec3f(seen.a * 0.2, 0.0, 0.0) + seen.rgb * seen.a, vec3f(0.3, 0.0, 0.0), seen.a <= 0.0) * lighting.env.z, 1.0);\n}\nlet h = normalize(v + l);\nlet nh = max(dot(n, h), 0.0);\nlet dd = nh * nh * (a2 - 1.0) + 1.0;\nlet ggx = a2 / (PI * dd * dd);\nlet vis = 0.5 / (nl * sqrt(nv * nv * (1.0 - a2) + a2) + nv * sqrt(nl * nl * (1.0 - a2) + a2) + 1e-5);\nlet fh = f0 + (1.0 - f0) * pow(1.0 - max(dot(v, h), 0.0), 5.0);\nlet shade = cloud_light(in.p, l);\nlet sun = lighting.sun_color.rgb * shade;\nlet vh = max(dot(v, h), 1e-3);\nlet p_facet = min(ggx * nh * sp.glint.z / (4.0 * vh), 1.0);\nlet spec = sun * (ggx * vis * fh * nl * glint_ratio(gpos, gext, p_facet));\nlet up = sh_irradiance(vec3f(0.0, 1.0, 0.0));\nlet body = sp.body.rgb * (up + sun * (max(l.y, 0.0) / PI) * 0.5);\nlet behind = pow(saturate(dot(-v, l)), 8.0);\nlet crest = saturate(in.height * 0.5) * saturate(1.0 - n.y * 0.9 + 0.2);\nvar sss = sp.sss.rgb * sun * (behind * crest * sp.sss.w);\nlet wide = 0.35 + 0.65 * pow(saturate(dot(-v, l) * 0.5 + 0.5), 3.0);\nlet thin = sf.face * (0.6 + 0.4 * saturate(1.0 - abs(n.y) * 1.2));\nsss += sp.sss.rgb * (up * 4.5 + sun * (0.8 * wide)) * (thin * sp.sss.w * 2.5);\nvar below = body;\nvar shore_foam = 0.0;\nif (sp.shore.y > 0.5) {\nlet px = vec2i(frag.xy);\nlet size = vec2f(textureDimensions(under));\nlet dist = length(in.p);\nlet t0 = thickness(dist, frag.z, textureLoad(under_depth, px, 0).x);\nlet bend = n.xz * sp.optics.w * min(t0, 1.0);\nvar uv = (frag.xy + bend) / size;\nif (any(uv < vec2f(0.0)) || any(uv >= vec2f(1.0))) {\nuv = frag.xy / size;\n}\nvar t = thickness(dist, frag.z, textureLoad(under_depth, vec2i(uv * size), 0).x);\nif (textureLoad(under_depth, vec2i(uv * size), 0).x > frag.z) {\nuv = frag.xy / size;\nt = t0;\n}\nvar behind_light = textureSampleLevel(under, clamp_smp, uv, 0.0).rgb * sp.shore.z;\nlet down = max(t * v.y, 0.0);\nlet sun_in = sqrt(max(1.0 - (1.0 - l.y * l.y) / 1.7689, 0.04));\nlet above = (in.p - v * t).xz + vec2f(l.x, l.z) / sun_in * down * (1.0 / 1.33);\nvar lap = 0.0;\nlet cn = u32(sp.sea.y);\nlet c0 = select(0u, cn - 2u, cn >= 2u);\nfor (var c = c0; c < select(c0, select(1u, cn - 1u, cn >= 2u), sp.size.w > 0.5); c++) {\nlet cc = sp.cascade[c];\nlet e = 2.0 / (cc.z * sp.size.x);\nlet q = cc.xy + above * cc.z;\nlet ex = vec2f(cc.z * e, 0.0);\nlet ez = vec2f(0.0, cc.z * e);\nlet dsx = textureSampleLevel(slopes, wrap, q + ex, c, 0.0).x - textureSampleLevel(slopes, wrap, q - ex, c, 0.0).x;\nlet dsz = textureSampleLevel(slopes, wrap, q + ez, c, 0.0).y - textureSampleLevel(slopes, wrap, q - ez, c, 0.0).y;\nlap += (dsx + dsz) / (2.0 * e);\n}\nlet focus = 1.0 / max(abs(1.0 - down * 0.248 * lap), 0.25);\nlet caustic = mix(1.0, focus, saturate(down * 3.0) * exp(-down / 4.0) * saturate(l.y * 4.0) * shade);\nbehind_light *= mix(1.0, caustic, 0.65);\nlet trans = exp(-sp.optics.rgb * (t + down / sun_in));\nbelow = behind_light * trans + body * (vec3f(1.0) - exp(-sp.optics.rgb * t));\nlet vertical = t0 * max(v.y, 0.02);\nshore_foam = saturate(1.0 - vertical / sp.shore.x) * saturate(vertical * 40.0);\nif (sp.surf0.w > 0.5) {\nlet object = saturate((-sf.ground - vertical - 0.15) / 0.3);\nshore_foam = mix(shore_foam, saturate(1.0 - vertical / 0.035) * saturate(vertical * 60.0) * 0.8, object);\n}\n}\nlet sigma = sqrt(lost);\nlet mean_f = f0 + (1.0 - f0) * pow(1.0 - nv, 5.0 * exp(-2.69 * sigma)) / (1.0 + 22.7 * pow(sigma, 1.5));\nlet fr = min(fresnel, mean_f);\nlet water = sky * fr + (below + sss) * (1.0 - fr) + spec;\nlet foam_light = (sh_irradiance(n) + sun * (nl / PI)) * 0.85;\nvar fp = (sp.cascade[0].xy + in.rest * sp.cascade[0].z) / sp.cascade[0].z;\nif (sf.foam > 0.001 || sf.front > 0.001) {\nfp = sf.world;\n}\nlet flow = surf_flow(sf);\nlet cyc = 1.0;\nlet ph0 = fract(sp.surf3.x / cyc);\nlet ph1 = fract(sp.surf3.x / cyc + 0.5);\nlet fp0 = fp - flow * (ph0 * cyc) + vec2f(13.7, 5.1) * floor(sp.surf3.x / cyc);\nlet fp1 = fp - flow * (ph1 * cyc) + vec2f(7.3, 11.9) * floor(sp.surf3.x / cyc + 0.5);\nlet wflow = abs(2.0 * ph0 - 1.0);\nlet beach = smoothstep(0.0, 0.04, sf.ground);\nvar drain = 1.0;\nif (beach > 0.0 && sf.cover > 0.0 && sf.phase > 0.18) {\nlet along = dot(sf.world, sf.dir);\nlet across = dot(sf.world, vec2f(-sf.dir.y, sf.dir.x)) + (vnoise(vec2f(along * 0.6, 0.0)) - 0.5) * 1.4 + (vnoise(vec2f(along * 1.7, 5.0)) - 0.5) * 0.5;\nlet rill = vnoise(vec2f(across * 1.5, along * 0.12)) * 0.6 + vnoise(vec2f(across * 4.3, along * 0.3) + vec2f(17.0, 3.0)) * 0.4;\nlet k = smoothstep(0.2, 0.5, sf.phase) * beach * smoothstep(0.35, 0.65, vnoise(sf.world / 7.0 + vec2f(3.0, 9.0)));\ndrain = mix(1.0, smoothstep(0.38, 0.62, rill), k);\n}\nvar cover = saturate(fold * sp.sea.w + shore_foam * (1.0 - beach) + (sf.foam + sf.front * 0.9) * mix(1.0, drain, beach) + sf.mark * 0.55);\nif (cover > 0.002) {\nlet spots = vnoise(fp * 0.22) * 0.65 + vnoise(fp * 0.61 + vec2f(9.0, 4.0)) * 0.35;\ncover *= mix(smoothstep(0.35, 0.75, spots), 1.0, smoothstep(0.35, 0.8, cover));\nlet clumps = vnoise(fp * 0.35 + vec2f(3.0, 7.0)) * 0.6 + vnoise(fp * 1.1 + vec2f(11.0, 2.0)) * 0.4;\ncover *= mix(1.0, 0.45 + 0.75 * clumps, smoothstep(0.3, 0.7, cover));\n}\nlet fw = length(fwidth(fp0));\nvar foam = 0.0;\nvar bubbles = 1.0;\nif (cover > 0.002) {\nvar net = foam_net(fp0, cover, fw);\nif (dot(flow, flow) > 1e-4) {\nnet = mix(net, foam_net(fp1, cover, fw), wflow);\n}\nfoam = net.x;\nbubbles = net.y;\n}\nlet aerated = saturate(sf.fresh * 1.6) * (1.0 - beach);\nlet milky = mix(sp.sss.rgb * 2.5, vec3f(0.85, 0.95, 0.95), 0.55) * (sh_irradiance(n) + sun * (nl / PI));\nvar foam_lit = foam_light;\nif (foam > 0.01 && sp.surf0.w > 0.5) {\nlet fuv = sp.surf0.xy + in.rest * sp.surf0.z;\nlet ft = 1.0 / vec2f(textureDimensions(surf_d));\nlet gx = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(ft.x, 0.0), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(ft.x, 0.0), 0.0).w;\nlet gz = textureSampleLevel(surf_d, clamp_smp, fuv + vec2f(0.0, ft.y), 0.0).w - textureSampleLevel(surf_d, clamp_smp, fuv - vec2f(0.0, ft.y), 0.0).w;\nlet per_m = 0.1 / (2.0 * ft.x / sp.surf0.z);\nlet nf = normalize(n + vec3f(-gx, 0.0, -gz) * per_m * 0.5);\nfoam_lit = (sh_irradiance(nf) + sun * (max(dot(nf, l), 0.0) / PI)) * 0.85;\n}\nvar lit = mix(mix(water, milky, aerated * 0.65), foam_lit * bubbles, foam);\nif (sf.ground > 0.0 && sp.shore.y > 0.5) {\nlet sand = textureLoad(under, vec2i(frag.xy), 0).rgb * sp.shore.z;\nlet wet_rough = 0.12;\nlet sheen = textureSampleLevel(env_cube, wrap, r, clamp(sqrt(wet_rough) * (lighting.env.x - 1.0), 0.0, lighting.env.x - 1.0)).rgb * lighting.view.rgb;\nlet wet_sand = sand * mix(1.0, 0.5, sf.wet) + sheen * fresnel * sf.wet * 0.8;\nlit = mix(wet_sand, lit, max(sf.cover * drain, foam));\n}\nlet fogged = apply_fog(lit, in.p, lighting.fog, lighting.fog2, lighting.fog_air.rgb, sh_irradiance(normalize(in.p)), sun, l);\nreturn vec4f(fogged * lighting.env.z, 1.0);\n}\nstruct Camera {\nview_proj: mat4x4f,\nfrustum: array<vec4f, 6>,\nlight_dir: vec4f,\norigin: vec4f,\n}\nstruct Lighting {\nsun_color: vec4f,\nenv: vec4f,\nsh: array<vec4f, 9>,\nscreen: vec4f,\nview: vec4f,\nao_reproject: mat4x4f,\nao: vec4f,\nfog: vec4f,\nfog2: vec4f,\nfog_air: vec4f,\ngi_grid: vec4f,\ngi_counts: vec4f,\nssr: vec4f,\ngi_cascades: array<vec4f, 3>,\nclouds: vec4f,\n}\nfn apply_fog(color: vec3f, p: vec3f, fog: vec4f, fog2: vec4f, air: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet dist = length(p);\nif (dist <= 0.0 || (fog.x <= 0.0 && fog2.x <= 0.0)) {\nreturn color;\n}\nlet dir = p / dist;\nlet t = exp(-(air * (fog2.x * dist) + vec3f(height_fog_depth(fog, dir, dist))));\nreturn color * t + fog_inscatter(fog2, dir, ambient, sun, sun_dir) * (vec3f(1.0) - t);\n}\nfn height_fog_depth(fog: vec4f, dir: vec3f, dist: f32) -> f32 {\nif (fog.x <= 0.0) {\nreturn 0.0;\n}\nlet falloff = max(fog.y, 1e-5);\nlet len = max(dist - fog.w, 0.0);\nlet h0 = fog.z + dir.y * min(dist, fog.w);\nlet k = falloff * dir.y * len;\nlet shape = select((1.0 - exp(-k)) / k, 1.0 - 0.5 * k, abs(k) < 1e-3);\nreturn fog.x * exp(-falloff * h0) * len * shape;\n}\nfn fog_inscatter(fog2: vec4f, dir: vec3f, ambient: vec3f, sun: vec3f, sun_dir: vec3f) -> vec3f {\nlet g = fog2.z;\nlet c = dot(dir, sun_dir);\nlet phase = (1.0 - g * g) / (FOUR_PI * pow(max(1.0 + g * g - 2.0 * g * c, 1e-4), 1.5));\nreturn ambient + sun * (phase * fog2.y);\n}\nconst FOUR_PI = 12.5663706;",
12
12
  };
13
13
  //# sourceMappingURL=water-shaders.gen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"water-shaders.gen.js","sourceRoot":"","sources":["../src/water-shaders.gen.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AAEzE,4CAA4C;AAC5C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,8+GAA8+G;CAC5+G,CAAC;AAEX,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,myiCAAmyiC;CACjyiC,CAAC"}
1
+ {"version":3,"file":"water-shaders.gen.js","sourceRoot":"","sources":["../src/water-shaders.gen.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AAEzE,4CAA4C;AAC5C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,8+GAA8+G;CAC5+G,CAAC;AAEX,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,0+uCAA0+uC;CACx+uC,CAAC"}
package/dist/water.d.ts CHANGED
@@ -104,9 +104,27 @@ export declare class Water implements RenderFeature {
104
104
  spray: number;
105
105
  /** The ripples finer than the cascades (ADR-0223; live, 0 none, 1 Cox & Munk's slope for the wind). */
106
106
  ripples: number;
107
+ /** Rocks the swash and the surf reach are wet: darker below the water's line (ADR-0228; live). */
108
+ wetRocks: boolean;
109
+ /**
110
+ * How strongly fresh whitewater, the swash's front, the lip and spray mark TAA's reactive mask (ADR-0229; live, 0–1,
111
+ * default 0.6), where TAA runs with `taa: { reactive: true }`: their shading moves unlike the surface's points, so TAA
112
+ * leans on this frame there instead of smearing them.
113
+ */
114
+ reactive: number;
115
+ /**
116
+ * Sun glints (ADR-0226; live, 0 = the smooth highlight only, 1 = default): far water mirrors the sun from a few ripples
117
+ * at a time, so the glitter path is sparkles that rise and fade, keeping the smooth highlight's mean.
118
+ */
119
+ glints: number;
120
+ /** A glinting facet's size, metres (ADR-0226; live, default 0.02: the capillary ripples). Smaller = more, finer sparkles. */
121
+ glintSize: number;
122
+ /** How long a glint lives, seconds (ADR-0226; live, default 0.3). */
123
+ glintLife: number;
107
124
  /**
108
125
  * The quality tier (ADR-0220; live): `high` everything; `medium` the coarse foam pattern only, 16 reflection steps, half
109
- * the spray; `low` no caustics, no scene reflections, no spray. Setting it sets those knobs (they stay live after).
126
+ * the spray; `low` no caustics, no scene reflections, no spray, and a 256² surf field (1 m texels, ADR-0232). Setting it
127
+ * sets those knobs (they stay live after).
110
128
  */
111
129
  get quality(): WaterQuality;
112
130
  set quality(q: WaterQuality);
@@ -135,7 +153,7 @@ export declare class Water implements RenderFeature {
135
153
  setSeabed(seabed: Seabed): ShoreField;
136
154
  /** The baked shore field, or null before `setSeabed`. */
137
155
  get shoreField(): ShoreField | null;
138
- addMotionPasses(graph: FrameGraph, motion: string, depth: string): void;
156
+ addMotionPasses(graph: FrameGraph, motion: string, depth: string, reactive?: string | null): void;
139
157
  addPasses(graph: FrameGraph, color: string, depth: string, scene: SceneRenderer): void;
140
158
  /**
141
159
  * Its agent tools (ADR-0204): `water.state` reads the sea, `water.set` turns its knobs, `water.sea` makes a new sea.
package/dist/water.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { mat4 } from '@yali-engine/math';
1
2
  import { bakeShore, toHalf } from "./shore.js";
2
3
  import { waterSurface } from "./water-shaders.gen.js";
3
4
  import { WaterWaves } from "./waves.js";
@@ -26,13 +27,16 @@ function gridIndices(device, rings, segments) {
26
27
  return buf;
27
28
  }
28
29
  const TIERS = { high: 2, medium: 1, low: 0 };
29
- /** Bytes of `SurfaceParams` (`shaders/water/surface.wesl`): 4 cascades + 8 vectors. */
30
- const PARAMS_BYTES = (4 + 8 + 4) * 16;
31
- /** The motion uniform (ADR-0210): this frame's and last frame's view-projections (unjittered), the eye's move, a flag. */
32
- const MOTION_BYTES = 16 * 4 * 2 + 16;
30
+ /** Bytes of `SurfaceParams` (`shaders/water/surface.wesl`): 4 cascades + 8 vectors + 4 of the surf + the glints + the clouds' shadow. */
31
+ const PARAMS_BYTES = (4 + 8 + 4 + 2) * 16;
32
+ /** The sun's solid angle, steradians: a disc 0.5357° across (`SUN_ANGLE` in the render package's shadows). */
33
+ const SUN_SOLID_ANGLE = Math.PI * ((0.5357 * Math.PI) / 360) ** 2;
34
+ /** The motion uniform (ADR-0210): this frame's and last frame's view-projections (unjittered), the eye's move, a flag; the reactive mask's strength (ADR-0229). */
35
+ const MOTION_BYTES = 16 * 4 * 2 + 16 + 16;
33
36
  /** The first ring's spacing (m) and how much wider each next ring is. */
34
- /** The surf field's texels a side (ADR-0223): 0.5 m over the demo's 256 m shore field. */
37
+ /** The surf field's texels a side (ADR-0223): 0.5 m over the demo's 256 m shore field; the low tier's 256 (ADR-0232). */
35
38
  const SURF_TEXELS = 512;
39
+ const SURF_TEXELS_LOW = 256;
36
40
  /** Spray sprites (`SPRAY_SIDE`² in surface.wesl, ADR-0218). */
37
41
  const SPRAY_SPRITES = 192 * 192;
38
42
  const FIRST_RING = 0.12;
@@ -95,10 +99,28 @@ export class Water {
95
99
  spray;
96
100
  /** The ripples finer than the cascades (ADR-0223; live, 0 none, 1 Cox & Munk's slope for the wind). */
97
101
  ripples = 1;
102
+ /** Rocks the swash and the surf reach are wet: darker below the water's line (ADR-0228; live). */
103
+ wetRocks = true;
104
+ /**
105
+ * How strongly fresh whitewater, the swash's front, the lip and spray mark TAA's reactive mask (ADR-0229; live, 0–1,
106
+ * default 0.6), where TAA runs with `taa: { reactive: true }`: their shading moves unlike the surface's points, so TAA
107
+ * leans on this frame there instead of smearing them.
108
+ */
109
+ reactive = 0.6;
110
+ /**
111
+ * Sun glints (ADR-0226; live, 0 = the smooth highlight only, 1 = default): far water mirrors the sun from a few ripples
112
+ * at a time, so the glitter path is sparkles that rise and fade, keeping the smooth highlight's mean.
113
+ */
114
+ glints = 1;
115
+ /** A glinting facet's size, metres (ADR-0226; live, default 0.02: the capillary ripples). Smaller = more, finer sparkles. */
116
+ glintSize = 0.02;
117
+ /** How long a glint lives, seconds (ADR-0226; live, default 0.3). */
118
+ glintLife = 0.3;
98
119
  #quality = 'high';
99
120
  /**
100
121
  * The quality tier (ADR-0220; live): `high` everything; `medium` the coarse foam pattern only, 16 reflection steps, half
101
- * the spray; `low` no caustics, no scene reflections, no spray. Setting it sets those knobs (they stay live after).
122
+ * the spray; `low` no caustics, no scene reflections, no spray, and a 256² surf field (1 m texels, ADR-0232). Setting it
123
+ * sets those knobs (they stay live after).
102
124
  */
103
125
  get quality() {
104
126
  return this.#quality;
@@ -110,8 +132,30 @@ export class Water {
110
132
  this.reflectionSteps = q === 'high' ? 24 : 16;
111
133
  this.reflections = q === 'low' ? 0 : 40;
112
134
  this.spray = q === 'high' ? 1 : q === 'medium' ? 0.5 : 0;
135
+ // The surf field's resolution follows the tier (ADR-0232): remade, and every group naming it with it.
136
+ if (this.#shoreField && this.#surfN !== this.#surfTexels()) {
137
+ this.#makeSurfField(this.#surfTexels());
138
+ this.#resetGroups();
139
+ }
140
+ }
141
+ /** The surf field's texels a side at this tier (ADR-0232). */
142
+ #surfTexels() {
143
+ return this.#quality === 'low' ? SURF_TEXELS_LOW : SURF_TEXELS;
144
+ }
145
+ /** The surf field's texels a side now. */
146
+ #surfN = 1;
147
+ #resetGroups() {
148
+ this.#groups = [null, null];
149
+ this.#groupKey = '';
150
+ this.#motionGroups = [null, null];
151
+ this.#sprayGroups = [null, null];
152
+ this.#surfGroups = [null, null];
153
+ this.#wetGroups = [null, null];
154
+ this.#sprayReactiveGroups = [null, null];
113
155
  }
114
156
  #prevSurfTime = 0;
157
+ /** The waves' time at the last motion upload: unchanged, they count as still (ADR-0228). */
158
+ #motionSeconds = Number.NaN;
115
159
  #shoreField = null;
116
160
  #shoreTexture;
117
161
  #spillTexture;
@@ -135,6 +179,17 @@ export class Water {
135
179
  /** Which half of each pair this frame's surf field wrote. */
136
180
  #surfParity = 0;
137
181
  #motionPipeline = null;
182
+ /** With TAA's reactive mask (ADR-0229): the motion pass with the mask as a second target, and spray into the mask. */
183
+ #motionReactivePipeline = null;
184
+ #sprayReactivePipeline = null;
185
+ #sprayReactiveGroups = [null, null];
186
+ #sprayReactiveKey = -1;
187
+ /** Wet rocks (ADR-0228): the fullscreen multiply, its inverse view-projection and bind group. */
188
+ #wetPipeline = null;
189
+ #wetParams;
190
+ #wetData = new Float32Array(16);
191
+ #wetGroups = [null, null];
192
+ #wetKey = -1;
138
193
  #motionGroups = [null, null];
139
194
  #motionParams;
140
195
  #motionData = new Float32Array(MOTION_BYTES / 4);
@@ -195,6 +250,7 @@ export class Water {
195
250
  // Stand-ins until a seabed brings the surf (the shaders name the field's bindings either way).
196
251
  this.#makeSurfField(1);
197
252
  this.#motionParams = device.createBuffer({ label: 'yali:water:motion', size: MOTION_BYTES, usage: 0x40 | 0x08 });
253
+ this.#wetParams = device.createBuffer({ label: 'yali:water:wet', size: 64, usage: 0x40 | 0x08 });
198
254
  this.#clamp = device.createSampler({ label: 'yali:water:clamp', magFilter: 'linear', minFilter: 'linear' });
199
255
  this.#sampler = device.createSampler({ label: 'yali:water:wrap', addressModeU: 'repeat', addressModeV: 'repeat', magFilter: 'linear', minFilter: 'linear', mipmapFilter: 'linear' });
200
256
  }
@@ -222,6 +278,15 @@ export class Water {
222
278
  depthStencil: { format: 'depth32float', depthWriteEnabled: false, depthCompare: 'greater' },
223
279
  })
224
280
  .then((p) => (this.#sprayPipeline = p)),
281
+ // Wet rocks (ADR-0228): a fullscreen multiply over the opaque scene.
282
+ cache
283
+ .render({
284
+ label: 'yali:water:wet',
285
+ vertex: { shader: waterSurface, entryPoint: 'vs_wet' },
286
+ fragment: { shader: waterSurface, entryPoint: 'fs_wet', targets: [{ format, blend: { color: { srcFactor: 'dst', dstFactor: 'zero' }, alpha: { srcFactor: 'zero', dstFactor: 'one' } } }] },
287
+ primitive: { topology: 'triangle-list' },
288
+ })
289
+ .then((p) => (this.#wetPipeline = p)),
225
290
  // The waves' motion for TAA (ADR-0210): the same grid drawn into the motion target.
226
291
  cache
227
292
  .render({
@@ -232,6 +297,25 @@ export class Water {
232
297
  depthStencil: { format: 'depth32float', depthWriteEnabled: true, depthCompare: 'greater' },
233
298
  })
234
299
  .then((p) => (this.#motionPipeline = p)),
300
+ // With TAA's reactive mask (ADR-0229): the same motion with the mask beside it, and the spray's sprites into it.
301
+ cache
302
+ .render({
303
+ label: 'yali:water:motion-reactive',
304
+ vertex: { shader: waterSurface, entryPoint: 'vs_motion' },
305
+ fragment: { shader: waterSurface, entryPoint: 'fs_motion_reactive', targets: [{ format: 'rgba16float' }, { format: 'r8unorm' }] },
306
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
307
+ depthStencil: { format: 'depth32float', depthWriteEnabled: true, depthCompare: 'greater' },
308
+ })
309
+ .then((p) => (this.#motionReactivePipeline = p)),
310
+ cache
311
+ .render({
312
+ label: 'yali:water:spray-reactive',
313
+ vertex: { shader: waterSurface, entryPoint: 'vs_spray' },
314
+ fragment: { shader: waterSurface, entryPoint: 'fs_spray_reactive', targets: [{ format: 'r8unorm', blend: { color: { operation: 'max', srcFactor: 'one', dstFactor: 'one' }, alpha: { operation: 'max', srcFactor: 'one', dstFactor: 'one' } } }] },
315
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
316
+ depthStencil: { format: 'depth32float', depthWriteEnabled: false, depthCompare: 'greater' },
317
+ })
318
+ .then((p) => (this.#sprayReactivePipeline = p)),
235
319
  ]);
236
320
  this.#pipeline = pipeline;
237
321
  }
@@ -266,7 +350,10 @@ export class Water {
266
350
  const have = sv.reduce((a, b) => a + b, 0);
267
351
  const missing = Math.max(0, (0.003 + 0.00512 * this.waves.wind) / 2 - have);
268
352
  const ripples = this.ripples * Math.min(8, Math.sqrt(missing / Math.max(1e-9, sv[sv.length - 1] * 0.74)));
269
- d.set([this.shoreFoam, this.#under ? 1 : 0, this.#inv, ripples], 40);
353
+ // Shore foam is churned by waves (ADR-0230): a calm sea's thin water over sand or a rock's top does not foam. Its band
354
+ // grows from nothing at 2.5 m/s of wind to the full depth from 6.5 (whitecaps begin about there).
355
+ const sea = Math.max(0, Math.min(1, (this.waves.wind - 2.5) / 4));
356
+ d.set([Math.max(1e-4, this.shoreFoam * sea), this.#under ? 1 : 0, this.#inv, ripples], 40);
270
357
  d.set([this.reflections, this.reflectionSteps, 0.6, this.debugMirror ? 1 : 0], 44);
271
358
  // The surf (ADR-0213): the eye on the shore field (f64 here, small after), the crest clock now and last frame.
272
359
  const sf = this.#shoreField;
@@ -286,9 +373,19 @@ export class Water {
286
373
  const surfTime = ((this.#seconds % span) + span) % span;
287
374
  d.set([surfTime, this.surfVariety, this.surfLip, this.#prevSurfTime], 60);
288
375
  this.#prevSurfTime = surfTime;
376
+ d.set([this.glints, Math.max(1e-3, this.glintSize), SUN_SOLID_ANGLE, Math.max(1 / 60, this.glintLife)], 64);
377
+ // The clouds' shadow (ADR-0227): the map's centre less the eye in f64, then small.
378
+ const cs = f.environment.cloudShadow;
379
+ if (cs)
380
+ d.set([cs.centre[0] - eye[0], cs.centre[1] - eye[2], 1 / cs.size, 1], 68);
381
+ else
382
+ d.set([0, 0, 0, 0], 68);
289
383
  this.device.queue.writeBuffer(this.#params, 0, d);
290
384
  if (this.enabled)
291
385
  this.#runSurfField();
386
+ // Wet rocks (ADR-0228): the scene's points from its depth, through this frame's inverse view-projection.
387
+ if (this.wetRocks && mat4.invert(this.#wetData, f.camera.uniform))
388
+ this.device.queue.writeBuffer(this.#wetParams, 0, this.#wetData);
292
389
  if (this.#prevDisplacement) {
293
390
  // Motion: this frame's view-projection (camera-relative, unjittered: `camera.uniform`), last frame's, and how far
294
391
  // the eye moved (last frame's camera-relative points are this frame's plus it).
@@ -297,10 +394,13 @@ export class Water {
297
394
  for (let i = 0; i < 16; i++)
298
395
  m[i] = vp[i];
299
396
  m.set(this.#prevVP, 16);
397
+ m[36] = Math.max(0, Math.min(1, this.reactive));
300
398
  for (let i = 0; i < 3; i++)
301
399
  m[32 + i] = eye[i] - this.#prevEye[i];
302
- // Until last frame's waves exist (two frames), the waves count as still: the camera's motion only.
303
- m[35] = this.motion && this.#motionFrames >= 2 && this.frozenAt === null ? 1 : 0;
400
+ // Until last frame's waves exist (two frames), the waves count as still: the camera's motion only. Held waves move
401
+ // when their time changes (a probe stepping them frame by frame, ADR-0228), and are still while it stands.
402
+ m[35] = this.motion && this.#motionFrames >= 2 && this.#seconds !== this.#motionSeconds ? 1 : 0;
403
+ this.#motionSeconds = this.#seconds;
304
404
  this.device.queue.writeBuffer(this.#motionParams, 0, m);
305
405
  for (let i = 0; i < 16; i++)
306
406
  this.#prevVP[i] = vp[i];
@@ -310,6 +410,7 @@ export class Water {
310
410
  }
311
411
  /** The surf field's textures (ADR-0223), made with the seabed: four rgba16float targets, A and D in pairs. */
312
412
  #makeSurfField(texels) {
413
+ this.#surfN = texels;
313
414
  for (const t of [...this.#surfA, ...this.#surfD, this.#surfB, this.#surfC])
314
415
  t?.destroy();
315
416
  const make = (label) => this.device.createTexture({ label, size: [texels, texels], format: 'rgba16float', usage: 0x08 | 0x04 });
@@ -360,7 +461,7 @@ export class Water {
360
461
  const pass = enc.beginComputePass({ label: 'yali:water:surf-field' });
361
462
  pass.setPipeline(this.#surfPipeline);
362
463
  pass.setBindGroup(0, this.#surfGroups[p]);
363
- pass.dispatchWorkgroups(SURF_TEXELS / 8, SURF_TEXELS / 8);
464
+ pass.dispatchWorkgroups(this.#surfN / 8, this.#surfN / 8);
364
465
  pass.end();
365
466
  this.device.queue.submit([enc.finish()]);
366
467
  }
@@ -383,7 +484,7 @@ export class Water {
383
484
  pass.setPipeline(this.#surfPipeline);
384
485
  pass.setBindGroup(0, group);
385
486
  for (let i = 0; i < n; i++)
386
- pass.dispatchWorkgroups(SURF_TEXELS / 8, SURF_TEXELS / 8);
487
+ pass.dispatchWorkgroups(this.#surfN / 8, this.#surfN / 8);
387
488
  pass.end();
388
489
  await this.device.queue.onSubmittedWorkDone();
389
490
  const t0 = performance.now();
@@ -423,35 +524,34 @@ export class Water {
423
524
  this.#spillTexture = this.device.createTexture({ label: 'yali:water:spill', size: [field.size, field.size], format: 'rg16float', usage: 0x04 | 0x02 });
424
525
  this.device.queue.writeTexture({ texture: this.#spillTexture }, spill, { bytesPerRow: field.size * 4 }, [field.size, field.size]);
425
526
  this.#shoreField = field;
426
- this.#groups = [null, null];
427
- this.#groupKey = '';
428
- this.#motionGroups = [null, null];
429
- this.#sprayGroups = [null, null];
430
- this.#surfGroups = [null, null];
431
- this.#makeSurfField(SURF_TEXELS);
527
+ this.#resetGroups();
528
+ this.#makeSurfField(this.#surfTexels());
432
529
  return field;
433
530
  }
434
531
  /** The baked shore field, or null before `setSeabed`. */
435
532
  get shoreField() {
436
533
  return this.#shoreField;
437
534
  }
438
- addMotionPasses(graph, motion, depth) {
535
+ addMotionPasses(graph, motion, depth, reactive = null) {
439
536
  const disp = this.waves.displacement;
440
537
  this.#prevDisplacement ??= this.device.createTexture({ label: 'yali:water:displacement-prev', size: [disp.width, disp.height, disp.depthOrArrayLayers], format: disp.format, usage: 0x04 | 0x02 });
441
538
  this.#motionGroups = [null, null];
442
539
  graph.addPass({
443
540
  name: 'water.motion',
444
541
  kind: 'render',
445
- reads: ['water.waves'],
542
+ // With TAA's reactive mask (ADR-0229) the mask is a second target, written after its clear.
543
+ reads: ['water.waves', ...(reactive ? ['post.reactiveClear'] : [])],
446
544
  color: { target: motion, clear: { r: 0, g: 0, b: 0, a: 0 }, load: true },
545
+ ...(reactive ? { extraColor: [{ target: reactive, clear: { r: 0, g: 0, b: 0, a: 0 }, load: true }] } : {}),
447
546
  depth: { target: depth, clear: 0, load: true, store: true },
448
547
  execute: (pass) => {
449
- if (!this.enabled || !this.#motionPipeline || !this.#scene)
548
+ const pipeline = reactive ? this.#motionReactivePipeline : this.#motionPipeline;
549
+ if (!this.enabled || !pipeline || !this.#scene)
450
550
  return;
451
551
  const mp = this.#surfParity;
452
552
  this.#motionGroups[mp] ??= this.device.createBindGroup({
453
553
  label: 'yali:water:motion',
454
- layout: this.#motionPipeline.getBindGroupLayout(0),
554
+ layout: pipeline.getBindGroupLayout(0),
455
555
  entries: [
456
556
  { binding: 0, resource: { buffer: this.#scene.cameraBuffer } },
457
557
  { binding: 2, resource: { buffer: this.#params } },
@@ -465,12 +565,47 @@ export class Water {
465
565
  ...this.#surfEntries(mp),
466
566
  ],
467
567
  });
468
- pass.setPipeline(this.#motionPipeline);
568
+ pass.setPipeline(pipeline);
469
569
  pass.setBindGroup(0, this.#motionGroups[mp]);
470
570
  pass.setIndexBuffer(this.#indices, 'uint32');
471
571
  pass.drawIndexed(this.rings * this.segments * 6);
472
572
  },
473
573
  });
574
+ // The spray's sprites into the reactive mask (ADR-0229), depth-tested against the motion pass's depth.
575
+ if (reactive) {
576
+ graph.addPass({
577
+ name: 'water.sprayReactive',
578
+ kind: 'render',
579
+ reads: ['water.motion', 'water.depth'],
580
+ color: { target: reactive, clear: { r: 0, g: 0, b: 0, a: 0 }, load: true },
581
+ depth: { target: depth, clear: 0, load: true, store: true },
582
+ execute: (pass, ctx) => {
583
+ if (!this.enabled || this.spray <= 0 || this.reactive <= 0 || !this.#shoreField || !this.#sprayReactivePipeline || !this.#scene)
584
+ return;
585
+ const sq = this.#surfParity;
586
+ if (this.#sprayReactiveKey !== ctx.generation) {
587
+ this.#sprayReactiveKey = ctx.generation;
588
+ this.#sprayReactiveGroups = [null, null];
589
+ }
590
+ this.#sprayReactiveGroups[sq] ??= this.device.createBindGroup({
591
+ label: 'yali:water:spray-reactive',
592
+ layout: this.#sprayReactivePipeline.getBindGroupLayout(0),
593
+ entries: [
594
+ { binding: 0, resource: { buffer: this.#scene.cameraBuffer } },
595
+ { binding: 2, resource: { buffer: this.#params } },
596
+ { binding: 9, resource: this.#clamp },
597
+ { binding: 13, resource: { buffer: this.#motionParams } },
598
+ { binding: 14, resource: this.#shoreTexture.createView() },
599
+ { binding: 15, resource: this.#spillTexture.createView() },
600
+ ...this.#surfEntries(sq),
601
+ ],
602
+ });
603
+ pass.setPipeline(this.#sprayReactivePipeline);
604
+ pass.setBindGroup(0, this.#sprayReactiveGroups[sq]);
605
+ pass.draw(6, SPRAY_SPRITES);
606
+ },
607
+ });
608
+ }
474
609
  // After TAA has read this frame's motion, keep this frame's waves for the next frame's.
475
610
  graph.addPass({
476
611
  name: 'water.keepWaves',
@@ -491,10 +626,42 @@ export class Water {
491
626
  this.#scene = scene;
492
627
  graph.transientTexture('water.under', { format: 'rgba16float', usage: 0x02 | 0x04 });
493
628
  graph.transientTexture('water.depth', { format: 'r32float', usage: 0x08 | 0x04 });
629
+ // Wet rocks (ADR-0228): before the copy, so the water sees them wet through itself too.
630
+ graph.addPass({
631
+ name: 'water.wet',
632
+ kind: 'render',
633
+ reads: [depth],
634
+ writes: ['water.wet'],
635
+ color: { target: color, clear: { r: 0, g: 0, b: 0, a: 0 }, load: true },
636
+ execute: (pass, ctx) => {
637
+ if (!this.enabled || !this.wetRocks || !this.#wetPipeline || !this.#shoreField)
638
+ return;
639
+ const wp = this.#surfParity;
640
+ if (this.#wetKey !== ctx.generation) {
641
+ this.#wetKey = ctx.generation;
642
+ this.#wetGroups = [null, null];
643
+ }
644
+ this.#wetGroups[wp] ??= this.device.createBindGroup({
645
+ label: 'yali:water:wet',
646
+ layout: this.#wetPipeline.getBindGroupLayout(0),
647
+ entries: [
648
+ { binding: 2, resource: { buffer: this.#params } },
649
+ { binding: 9, resource: this.#clamp },
650
+ { binding: 10, resource: ctx.view(depth) },
651
+ { binding: 14, resource: this.#shoreTexture.createView() },
652
+ { binding: 28, resource: { buffer: this.#wetParams } },
653
+ ...this.#surfEntries(wp).filter((e) => e.binding === 19 || e.binding === 20),
654
+ ],
655
+ });
656
+ pass.setPipeline(this.#wetPipeline);
657
+ pass.setBindGroup(0, this.#wetGroups[wp]);
658
+ pass.draw(3);
659
+ },
660
+ });
494
661
  graph.addPass({
495
662
  name: 'water.under',
496
663
  kind: 'encoder',
497
- reads: [],
664
+ reads: ['water.wet'],
498
665
  writes: ['water.under'],
499
666
  execute: (encoder, ctx) => {
500
667
  if (this.enabled)
@@ -539,7 +706,8 @@ export class Water {
539
706
  if (!this.enabled || !env)
540
707
  return;
541
708
  const pano = env.cloudPanorama;
542
- const key = `${env.version}:${ctx.generation}:${pano ? pano.label : '-'}`;
709
+ const shadow = env.cloudShadow?.texture ?? null;
710
+ const key = `${env.version}:${ctx.generation}:${pano ? pano.label : '-'}:${shadow ? shadow.label : '-'}`;
543
711
  const gp = this.#surfParity;
544
712
  if (key !== this.#groupKey) {
545
713
  this.#groupKey = key;
@@ -564,6 +732,8 @@ export class Water {
564
732
  { binding: 15, resource: this.#spillTexture.createView() },
565
733
  // The clouds' panorama (ADR-0219), or a stand-in the shader never reads (size.z = 0).
566
734
  { binding: 16, resource: (pano ?? this.#spillTexture).createView() },
735
+ // The clouds' shadow (ADR-0227), or a stand-in the shader never reads (cshadow.w = 0).
736
+ { binding: 27, resource: (shadow ?? this.#spillTexture).createView() },
567
737
  ...this.#surfEntries(gp),
568
738
  ],
569
739
  });
@@ -584,7 +754,9 @@ export class Water {
584
754
  execute: (pass, ctx) => {
585
755
  if (!this.enabled || this.spray <= 0 || !this.#shoreField || !this.#sprayPipeline)
586
756
  return;
587
- const key = `${ctx.generation}`;
757
+ // The clouds' shadow dims the sprites' sun too (ADR-0227).
758
+ const shadow = this.#env?.cloudShadow?.texture ?? null;
759
+ const key = `${ctx.generation}:${shadow ? shadow.label : '-'}`;
588
760
  const sq = this.#surfParity;
589
761
  if (key !== this.#sprayKey) {
590
762
  this.#sprayKey = key;
@@ -602,6 +774,7 @@ export class Water {
602
774
  { binding: 9, resource: this.#clamp },
603
775
  { binding: 14, resource: this.#shoreTexture.createView() },
604
776
  { binding: 15, resource: this.#spillTexture.createView() },
777
+ { binding: 27, resource: (shadow ?? this.#spillTexture).createView() },
605
778
  ...this.#surfEntries(sq),
606
779
  ],
607
780
  });
@@ -641,6 +814,9 @@ export class Water {
641
814
  tiles: [...this.waves.tiles],
642
815
  size: this.waves.size,
643
816
  gpuBytes: this.gpuBytes,
817
+ glints: { strength: this.glints, size: this.glintSize, life: this.glintLife },
818
+ wetRocks: this.wetRocks,
819
+ reactive: this.reactive,
644
820
  surf: { seabed: !!this.#shoreField, height: this.surfHeight, period: this.surfPeriod, breaking: this.surfBreaking, lean: this.surfLean, start: this.surfStart, calm: this.surfCalm, variety: this.surfVariety, lip: this.surfLip, spray: this.spray },
645
821
  });
646
822
  return [
@@ -665,12 +841,22 @@ export class Water {
665
841
  surfVariety: { type: 'number', description: 'How much waves differ: sets and sections along the shore, 0 (all alike) to 1.' },
666
842
  surfLip: { type: 'number', description: 'How far a breaking crest throws its lip forward, 0 to 1.' },
667
843
  spray: { type: 'number', description: 'Spray thrown up by breaking waves, 0 (none) to 4; 1 is the default.' },
844
+ glints: { type: 'number', description: 'Sun glints on far water, 0 (the smooth highlight only) to 1 (default).' },
845
+ glintSize: { type: 'number', description: 'The size of a glinting ripple, metres, 0.002 to 0.5 (default 0.02): smaller gives more, finer sparkles.' },
846
+ glintLife: { type: 'number', description: 'How long a glint lives, seconds, 0.05 to 3 (default 0.3).' },
847
+ reactive: { type: 'number', description: 'How strongly whitewater and spray mark TAA’s reactive mask, 0 to 1 (default 0.6; needs taa: { reactive: true }).' },
848
+ wetRocks: { type: 'boolean', description: 'Rocks the swash and the surf reach look wet: darker below the water line.' },
668
849
  follow: { type: 'boolean', description: 'true: the waves follow the app clock again.' },
669
850
  },
670
851
  },
671
852
  run: (args) => {
672
853
  if (args.enabled !== undefined)
673
854
  this.enabled = !!args.enabled;
855
+ if (args.wetRocks !== undefined)
856
+ this.wetRocks = !!args.wetRocks;
857
+ const rx = num(args, 'reactive', 0, 1);
858
+ if (rx !== undefined)
859
+ this.reactive = rx;
674
860
  if (args.quality !== undefined) {
675
861
  if (args.quality !== 'high' && args.quality !== 'medium' && args.quality !== 'low')
676
862
  throw bad('quality', 'must be high, medium or low');
@@ -714,6 +900,15 @@ export class Water {
714
900
  const sr = num(args, 'spray', 0, 4);
715
901
  if (sr !== undefined)
716
902
  this.spray = sr;
903
+ const gl = num(args, 'glints', 0, 1);
904
+ if (gl !== undefined)
905
+ this.glints = gl;
906
+ const gs = num(args, 'glintSize', 0.002, 0.5);
907
+ if (gs !== undefined)
908
+ this.glintSize = gs;
909
+ const gt = num(args, 'glintLife', 0.05, 3);
910
+ if (gt !== undefined)
911
+ this.glintLife = gt;
717
912
  return state();
718
913
  },
719
914
  },
package/dist/water.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"water.js","sourceRoot":"","sources":["../src/water.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"water.js","sourceRoot":"","sources":["../src/water.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yali-engine/water",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Yali water: an ocean's FFT cascades (JONSWAP, Donelan–Banner) and its surface, a render feature (ADR-0198).",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "dist"
19
19
  ],
20
20
  "dependencies": {
21
- "@yali-engine/render": "0.13.0"
21
+ "@yali-engine/math": "0.14.0",
22
+ "@yali-engine/render": "0.14.0"
22
23
  },
23
24
  "scripts": {
24
25
  "typecheck": "tsc -p tsconfig.json",