39 lines
1.2 KiB
WebGPU Shading Language
39 lines
1.2 KiB
WebGPU Shading Language
|
@group(0) @binding(0) var output: texture_storage_2d<rgba8unorm, write>;
|
||
|
@group(0) @binding(1) var<uniform> camera: Camera;
|
||
|
@group(0) @binding(2) var<storage, read_write> rays: array<Ray>;
|
||
|
|
||
|
struct Camera {
|
||
|
projection: mat4x4<f32>,
|
||
|
view: mat4x4<f32>,
|
||
|
pos: vec3<f32>,
|
||
|
};
|
||
|
|
||
|
struct Ray {
|
||
|
pos: vec3<f32>,
|
||
|
dist: f32,
|
||
|
dir: vec3<f32>,
|
||
|
hit: u32,
|
||
|
}
|
||
|
|
||
|
@compute @workgroup_size(8, 8, 1)
|
||
|
fn compute(@builtin(global_invocation_id) global_id: vec3<u32>) {
|
||
|
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<f32>(img_coord) / vec2<f32>(img_dims);
|
||
|
let screen_pos = img_coord_frac * 2.0 - vec2<f32>(1.0);
|
||
|
var ray_eye = camera.projection * vec4<f32>(screen_pos, -1.0, 0.0);
|
||
|
ray_eye = vec4<f32>(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;
|
||
|
}
|