From 9665d123481555c9d6c5d02571441c0b0bc3a838 Mon Sep 17 00:00:00 2001 From: xfy Date: Fri, 10 Jul 2026 10:36:18 +0800 Subject: [PATCH] feat: per-pixel camera ray generation --- assets/shaders/black_hole.wgsl | 11 ++++++++--- assets/shaders/ray_gen.wgsl | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 assets/shaders/ray_gen.wgsl diff --git a/assets/shaders/black_hole.wgsl b/assets/shaders/black_hole.wgsl index d5b1084..51630ea 100644 --- a/assets/shaders/black_hole.wgsl +++ b/assets/shaders/black_hole.wgsl @@ -1,4 +1,5 @@ #import bevy_sprite::mesh2d_vertex_output::VertexOutput +#import "shaders/ray_gen.wgsl" struct BlackHoleUniforms { eye: vec4, @@ -30,7 +31,11 @@ struct BlackHoleUniforms { @fragment fn fragment(in: VertexOutput) -> @location(0) vec4 { - // Prove the camera basis + uniforms flow: tint by eye direction. - let n = normalize(uniforms.eye.xyz); - return vec4(abs(n) * 0.5 + 0.3, 1.0); + // in.uv is [0,1] across the quad. Center and flip y, apply aspect. + let aspect = uniforms.resolution.x / uniforms.resolution.y; + var uv = (in.uv * 2.0 - 1.0); + uv.x *= aspect; + let dir = ray_direction(uv); + // Visualize ray direction as a color (sanity check). + return vec4(abs(dir), 1.0); } diff --git a/assets/shaders/ray_gen.wgsl b/assets/shaders/ray_gen.wgsl new file mode 100644 index 0000000..a29f4fc --- /dev/null +++ b/assets/shaders/ray_gen.wgsl @@ -0,0 +1,14 @@ +// Builds a world-space camera ray direction for the current pixel. +// `uv` is the pixel coordinate normalized to [-1,1] with aspect correction. +fn ray_direction(uv: vec2) -> vec3 { + // NOTE: `fov` is packed into the `.w` of `up` in BlackHoleUniforms + // (the Rust struct lays out `up: Vec3` + `fov: f32` as one vec4 block). + // The WGSL struct must stay exactly as-is per the task spec, so read fov + // from `uniforms.up.w` rather than a separate `uniforms.fov` field. + let tan_half_fov = tan(uniforms.up.w * 0.5); + let dir = + normalize(uniforms.forward.xyz) + + uniforms.right.xyz * (uv.x * tan_half_fov) + + uniforms.up.xyz * (uv.y * tan_half_fov); + return normalize(dir); +}