Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1// Reimplementation of the approach in Crest Shaders/Resources/ShapeCombine.compute.
3const LOD_COUNT: u32 = 5u;
4const CASCADE_COUNT: u32 = LOD_COUNT + 1u;
5const WAVE_COUNT: u32 = 40u;
7struct CascadeParams {
8 center: vec2<f32>,
9 scale: f32,
10 texture_res: f32,
11 inv_texture_res: f32,
12 texel_width: f32,
13 weight: f32,
14 max_wavelength: f32,
16struct CascadeLayout {
17 cascades: array<CascadeParams, CASCADE_COUNT>,
18 center: vec4<f32>,
19 // XY bed-map first-texel world origin, ZW inverse world extent.
20 bed_transform: vec4<f32>,
21 // X height minimum, Y height span (negative = no bed map), Z sea level.
22 bed_range: vec4<f32>,
24struct GerstnerWave {
25 direction: vec2<f32>,
26 amplitude: f32,
27 wave_number: f32,
28 angular_frequency: f32,
29 phase: f32,
30 chop_amplitude: f32,
32struct AnimWavesUniform {
33 cascade_layout: CascadeLayout,
34 waves: array<GerstnerWave, WAVE_COUNT>,
35 ranges: array<vec4<u32>, LOD_COUNT>,
36 time: vec4<f32>,
37 // xy: world-space current in m/s; kept identical to the other
38 // AnimWavesUniform declarations so one upload serves every consumer.
39 flow: vec4<f32>,
42@group(0) @binding(0) var raw_waves: texture_2d_array<f32>;
43@group(0) @binding(1) var previous: texture_2d_array<f32>;
44@group(0) @binding(2) var linear_sampler: sampler;
45@group(0) @binding(3) var output: texture_storage_2d_array<rgba16float, write>;
46@group(0) @binding(4) var<uniform> params: AnimWavesUniform;
48fn combine_lod(id: vec3<u32>, slice: u32) {
49 let cascade = params.cascade_layout.cascades[slice];
50 if id.x >= u32(cascade.texture_res) || id.y >= u32(cascade.texture_res) {
51 return;
52 }
53 var displacement = textureLoad(raw_waves, vec2<i32>(id.xy), i32(slice), 0).xyz;
54 if slice + 1u < LOD_COUNT {
55 let uv = (vec2<f32>(id.xy) + vec2(0.5)) * cascade.inv_texture_res;
56 let coverage = cascade.texel_width * cascade.texture_res;
57 let world_xz = coverage * (uv - vec2(0.5)) + cascade.center;
58 let next = params.cascade_layout.cascades[slice + 1u];
59 let next_coverage = next.texel_width * next.texture_res;
60 let next_uv = (world_xz - next.center) / next_coverage + vec2(0.5);
61 displacement += textureSampleLevel(
62 previous,
63 linear_sampler,
64 next_uv,
65 i32(slice + 1u),
66 0.0,
67 ).xyz;
68 }
69 textureStore(output, vec2<i32>(id.xy), i32(slice), vec4(displacement, 0.0));
72#ifdef COMBINE_1
73@compute @workgroup_size(8, 8, 1)
74fn main(@builtin(global_invocation_id) id: vec3<u32>) { combine_lod(id, 1u); }
75#endif
76#ifdef COMBINE_2
77@compute @workgroup_size(8, 8, 1)
78fn main(@builtin(global_invocation_id) id: vec3<u32>) { combine_lod(id, 2u); }
79#endif
80#ifdef COMBINE_3
81@compute @workgroup_size(8, 8, 1)
82fn main(@builtin(global_invocation_id) id: vec3<u32>) { combine_lod(id, 3u); }
83#endif
84#ifdef COMBINE_4
85@compute @workgroup_size(8, 8, 1)
86fn main(@builtin(global_invocation_id) id: vec3<u32>) { combine_lod(id, 4u); }
87#endif
88#ifdef COMBINE_0
89@compute @workgroup_size(8, 8, 1)
90fn main(@builtin(global_invocation_id) id: vec3<u32>) { combine_lod(id, 0u); }
91#endif
Contents