// WebGPU port of raygen.glsl. Mirrors the pinhole camera setup — the // Payload type is declared in closesthit.wgsl (concatenated earlier). fn raygen_main(gid: vec3) { if (gid.x >= hdr.surfaceW || gid.y >= hdr.surfaceH) { return; } let pixel = vec2(f32(gid.x), f32(gid.y)); let resolution = vec2(f32(hdr.surfaceW), f32(hdr.surfaceH)); let uv = (pixel + vec2(0.5)) / resolution; let ndc = uv * 2.0 - vec2(1.0); let origin = vec3(0.0, 0.0, -300.0); let aspect = resolution.x / resolution.y; let fov = 60.0 * 3.14159265 / 180.0; let tanHalfFov = tan(fov * 0.5); let direction = normalize(vec3( ndc.x * aspect * tanHalfFov, -ndc.y * tanHalfFov, 1.0, )); var payload: Payload; payload.color = vec3(0.0); traceRay( 0u, // tlasIdx (unused) 0u, // ray flags 0xFFu, // cull mask 0u, 0u, 0u, // sbtRecordOffset, sbtRecordStride, missIndex origin, 0.001, direction, 10000.0, &payload, ); textureStore(outImage, vec2(i32(gid.x), i32(gid.y)), vec4(payload.color, 1.0)); }