summaryrefslogtreecommitdiff
path: root/src/effects
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-03-08 10:38:19 +0100
committerskal <pascal.massimino@gmail.com>2026-03-08 10:38:19 +0100
commit21b061b951ec3a65bc479fabeb2d9565e08a807e (patch)
tree24755d905463c8a507a34624ab3edf7295c8e0c5 /src/effects
parent5f64a20daa81a6182d4898dcd6f86870ad0bf9d5 (diff)
fix: transpose matrices on GPU upload (row-major → column-major)
mini_math mat4 is row-major; WGSL mat4x4f is column-major. Matrices uploaded without transposing were interpreted as their own transpose on the GPU, causing RotatingCube and Renderer3D to render upside-down. - Add gpu_upload_mat4() to post_process_helper for standalone uploads - Add Uniforms::make() to RotatingCube::Uniforms (handles transpose) - Add GlobalUniforms::make() and ObjectData::make() to renderer.h - Update renderer_draw.cc and visual_debug.cc to use make() handoff(Gemini): matrix layout bug fixed across all rasterized effects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/ntsc.wgsl5
-rw-r--r--src/effects/rotating_cube_effect.cc14
-rw-r--r--src/effects/rotating_cube_effect.h8
3 files changed, 16 insertions, 11 deletions
diff --git a/src/effects/ntsc.wgsl b/src/effects/ntsc.wgsl
index 6c9fa37..5c27695 100644
--- a/src/effects/ntsc.wgsl
+++ b/src/effects/ntsc.wgsl
@@ -5,6 +5,7 @@
const vignetteRounding = 160.0f;
const vignetteSmoothness = 0.7f;
+const fisheyeStrength = vec2f(.1, .24);
@group(0) @binding(0) var input_sampler: sampler;
@group(0) @binding(1) var input_texture: texture_2d<f32>;
@@ -13,7 +14,7 @@ const vignetteSmoothness = 0.7f;
// Barrel (fisheye) distortion: strength > 0 = barrel, < 0 = pincushion
fn fisheye(uv: vec2f, strength: f32) -> vec2f {
let r2 = uv * uv;
- return uv * 1.05 * (1.0 + vec2f(.1, .24) * strength * r2);
+ return uv * 1.2 * (1.0 + fisheyeStrength * strength * r2);
}
fn vignette(uv: vec2f) -> f32 {
@@ -32,7 +33,7 @@ fn vignette(uv: vec2f) -> f32 {
// Black outside screen edges
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
- discard; // return vec4f(0.0, 0.0, 0.0, 1.0);
+ return vec4f(0.0, 0.0, 0.0, 1.0);
}
// Chroma separation (horizontal RGB bleeding)
diff --git a/src/effects/rotating_cube_effect.cc b/src/effects/rotating_cube_effect.cc
index 099d06c..757d64c 100644
--- a/src/effects/rotating_cube_effect.cc
+++ b/src/effects/rotating_cube_effect.cc
@@ -5,6 +5,7 @@
#include "effects/shaders.h"
#include "gpu/bind_group_builder.h"
#include "gpu/gpu.h"
+#include "gpu/post_process_helper.h"
#include "util/fatal_error.h"
RotatingCube::RotatingCube(const GpuContext& ctx,
@@ -137,15 +138,10 @@ void RotatingCube::render(WGPUCommandEncoder encoder,
const mat4 model = T * R * S;
// Update uniforms
- const Uniforms uniforms = {
- .view_proj = view_proj,
- .inv_view_proj = view_proj.inverse(),
- .camera_pos_time =
- vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time),
- .params = vec4(1.0f, 0.0f, 0.0f, 0.0f),
- .resolution = params.resolution,
- .aspect_ratio = params.aspect_ratio,
- };
+ const Uniforms uniforms = Uniforms::make(
+ view_proj,
+ vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time),
+ vec4(1.0f, 0.0f, 0.0f, 0.0f), params.resolution, params.aspect_ratio);
const ObjectData obj_data = {
.model = model,
diff --git a/src/effects/rotating_cube_effect.h b/src/effects/rotating_cube_effect.h
index e773025..920be5c 100644
--- a/src/effects/rotating_cube_effect.h
+++ b/src/effects/rotating_cube_effect.h
@@ -28,6 +28,14 @@ class RotatingCube : public Effect {
vec2 resolution;
float aspect_ratio;
float _pad;
+
+ // Transpose matrices: mini_math is row-major, WGSL expects column-major.
+ static Uniforms make(const mat4& vp, const vec4& cam_pos_time,
+ const vec4& p, const vec2& res, float asp) {
+ return {mat4::transpose(vp), mat4::transpose(vp.inverse()),
+ cam_pos_time, p,
+ res, asp};
+ }
};
static_assert(sizeof(Uniforms) == 176, "Uniforms size mismatch");