@group(0) @binding(0) var output: texture_storage_2d; @group(0) @binding(1) var camera: Camera; @group(0) @binding(2) var rays: array; struct Camera { projection: mat4x4, view: mat4x4, pos: vec3, }; struct Ray { pos: vec3, dist: f32, dir: vec3, hit: u32, } @compute @workgroup_size(8, 8, 1) fn compute(@builtin(global_invocation_id) global_id: vec3) { let img_coord = global_id.xy; let img_dims = textureDimensions(output); // This discards the extra pixels in cases where the image size isn't perfectly divisible by the kernel.xy if (img_coord.x >= img_dims.x || img_coord.y >= img_dims.y) { return; } // Construct ray let img_coord_frac = vec2(img_coord) / vec2(img_dims); let screen_pos = img_coord_frac * 2.0 - vec2(1.0); var ray_eye = camera.projection * vec4(screen_pos, -1.0, 0.0); ray_eye = vec4(ray_eye.xy, -1.0, 0.0); let ray_dir = normalize((camera.view * ray_eye).xyz); let ray_pos = camera.pos; let idx = img_coord.x + img_coord.y * img_dims.x; let ray = Ray(ray_pos, 0.0, ray_dir, 0); rays[idx] = ray; }