test(webgpu): HDRBloom example exercising the HDR post-process primitives (#27)
RT→rgba16float→threshold→blur→composite, end-to-end proof of the three primitives. threshold/blur run from onBeforeUpdate (one submit each) so the storage-write→sampled-read dependency gets WebGPU's per-submit barrier (there is none between dispatches within a compute pass); the composite is a UI custom shader so it owns the canvas ping-pong. Documents the Vulkan symmetry (gap 4): the native present path records passes generically and barriers between them, so the same chain is wireable today. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
097cc37347
commit
bbe1b21c22
10 changed files with 518 additions and 0 deletions
33
examples/HDRBloom/blur.comp.wgsl
Normal file
33
examples/HDRBloom/blur.comp.wgsl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// HDRBloom blur pass (PlainComputeShader). Box-blurs the thresholded bloom
|
||||
// mip into a second rgba16float target — demonstrating an N-target float
|
||||
// chain: this pass SAMPLES the texture the threshold pass wrote (storage
|
||||
// write → sampled read across a submit barrier) and WRITES another
|
||||
// user-owned float storage texture. Two such targets prove the mip-pyramid
|
||||
// shape a real bloom needs.
|
||||
//
|
||||
// Layout mirrors threshold.comp.wgsl (src = bloom mip A, dst = bloom mip B).
|
||||
|
||||
struct Dim { w: u32, h: u32, _0: u32, _1: u32 };
|
||||
@group(0) @binding(0) var<uniform> dim : Dim;
|
||||
@group(1) @binding(0) var src : texture_2d<f32>;
|
||||
@group(1) @binding(1) var dst : texture_storage_2d<rgba16float, write>;
|
||||
|
||||
const R: i32 = 6; // box radius → 13×13 kernel; a wide, cheap glow
|
||||
|
||||
@compute @workgroup_size(8, 8, 1)
|
||||
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
||||
if (gid.x >= dim.w || gid.y >= dim.h) { return; }
|
||||
let maxX = i32(dim.w) - 1;
|
||||
let maxY = i32(dim.h) - 1;
|
||||
var sum = vec3<f32>(0.0);
|
||||
var count = 0.0;
|
||||
for (var dy = -R; dy <= R; dy = dy + 1) {
|
||||
for (var dx = -R; dx <= R; dx = dx + 1) {
|
||||
let x = clamp(i32(gid.x) + dx, 0, maxX);
|
||||
let y = clamp(i32(gid.y) + dy, 0, maxY);
|
||||
sum = sum + textureLoad(src, vec2<i32>(x, y), 0).rgb;
|
||||
count = count + 1.0;
|
||||
}
|
||||
}
|
||||
textureStore(dst, vec2<i32>(i32(gid.x), i32(gid.y)), vec4<f32>(sum / count, 1.0));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue