summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-02 16:46:59 +0100
committerskal <pascal.massimino@gmail.com>2026-02-02 16:46:59 +0100
commit2184a1043d1a071cdc78303b2247145bf3f18c0b (patch)
tree948703ba6541391578c0917fd1ffb208209a321e
parentfe00b372ea6c376d5e67a1b7392c3fa4f72e6378 (diff)
fix(3d): Correct debug box transforms and restore object textures
- Updated VisualDebug to accept mat4 transforms, enabling wireframes to follow rotating objects. - Restored SDF bump mapping and floor grid texture in the fragment shader. - Added vec4::xyz() helper to mini_math.h. - Fixed Renderer3D to pass the full model matrix for debug visualization.
-rw-r--r--src/3d/renderer.cc46
-rw-r--r--src/3d/visual_debug.cc29
-rw-r--r--src/3d/visual_debug.h2
-rw-r--r--src/util/mini_math.h4
4 files changed, 60 insertions, 21 deletions
diff --git a/src/3d/renderer.cc b/src/3d/renderer.cc
index 80d0160..021374a 100644
--- a/src/3d/renderer.cc
+++ b/src/3d/renderer.cc
@@ -162,9 +162,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
if (obj_type <= 0.0) { // Raster path
p = in.world_pos;
let local_normal = normalize(cross(dpdx(in.local_pos), dpdy(in.local_pos)));
- // Normal transformation: multiply by transpose of inverse
let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz);
normal = normalize(transpose(normal_matrix) * local_normal);
+
+ // Apply grid texture to floor (type 0 is floor in test_3d_render)
+ let uv = p.xz * 0.1;
+ let grid_val = textureSample(noise_tex, noise_sampler, uv).r;
+ base_color = base_color * (0.3 + 0.7 * grid_val);
} else { // SDF path
let ro = globals.camera_pos_time.xyz;
let rd = normalize(in.world_pos - ro);
@@ -187,7 +191,42 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
}
let q_hit = (obj.inv_model * vec4<f32>(p, 1.0)).xyz;
- let n_local = get_normal(q_hit, obj_type);
+
+ // Calculate normal with bump mapping
+ let e = vec2<f32>(0.005, 0.0);
+ let disp_strength = 0.05;
+
+ let q_x1 = q_hit + e.xyy;
+ let uv_x1 = vec2<f32>(atan2(q_x1.x, q_x1.z) / 6.28 + 0.5, acos(clamp(q_x1.y / length(q_x1), -1.0, 1.0)) / 3.14);
+ let h_x1 = textureSample(noise_tex, noise_sampler, uv_x1).r;
+ let d_x1 = get_dist(q_x1, obj_type) - disp_strength * h_x1;
+
+ let q_x2 = q_hit - e.xyy;
+ let uv_x2 = vec2<f32>(atan2(q_x2.x, q_x2.z) / 6.28 + 0.5, acos(clamp(q_x2.y / length(q_x2), -1.0, 1.0)) / 3.14);
+ let h_x2 = textureSample(noise_tex, noise_sampler, uv_x2).r;
+ let d_x2 = get_dist(q_x2, obj_type) - disp_strength * h_x2;
+
+ let q_y1 = q_hit + e.yxy;
+ let uv_y1 = vec2<f32>(atan2(q_y1.x, q_y1.z) / 6.28 + 0.5, acos(clamp(q_y1.y / length(q_y1), -1.0, 1.0)) / 3.14);
+ let h_y1 = textureSample(noise_tex, noise_sampler, uv_y1).r;
+ let d_y1 = get_dist(q_y1, obj_type) - disp_strength * h_y1;
+
+ let q_y2 = q_hit - e.yxy;
+ let uv_y2 = vec2<f32>(atan2(q_y2.x, q_y2.z) / 6.28 + 0.5, acos(clamp(q_y2.y / length(q_y2), -1.0, 1.0)) / 3.14);
+ let h_y2 = textureSample(noise_tex, noise_sampler, uv_y2).r;
+ let d_y2 = get_dist(q_y2, obj_type) - disp_strength * h_y2;
+
+ let q_z1 = q_hit + e.yyx;
+ let uv_z1 = vec2<f32>(atan2(q_z1.x, q_z1.z) / 6.28 + 0.5, acos(clamp(q_z1.y / length(q_z1), -1.0, 1.0)) / 3.14);
+ let h_z1 = textureSample(noise_tex, noise_sampler, uv_z1).r;
+ let d_z1 = get_dist(q_z1, obj_type) - disp_strength * h_z1;
+
+ let q_z2 = q_hit - e.yyx;
+ let uv_z2 = vec2<f32>(atan2(q_z2.x, q_z2.z) / 6.28 + 0.5, acos(clamp(q_z2.y / length(q_z2), -1.0, 1.0)) / 3.14);
+ let h_z2 = textureSample(noise_tex, noise_sampler, uv_z2).r;
+ let d_z2 = get_dist(q_z2, obj_type) - disp_strength * h_z2;
+
+ let n_local = normalize(vec3<f32>(d_x1 - d_x2, d_y1 - d_y2, d_z1 - d_z2));
let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz);
normal = normalize(transpose(normal_matrix) * n_local);
}
@@ -478,8 +517,7 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene,
#if !defined(STRIP_ALL)
if (s_debug_enabled_) {
for (const auto& obj : scene.objects) {
- // Simple AABB approximation from scale
- visual_debug_.add_box(obj.position, obj.scale,
+ visual_debug_.add_box(obj.get_model_matrix(),
vec3(1.0f, 1.0f, 0.0f)); // Yellow boxes
}
diff --git a/src/3d/visual_debug.cc b/src/3d/visual_debug.cc
index daa1033..99d4b9f 100644
--- a/src/3d/visual_debug.cc
+++ b/src/3d/visual_debug.cc
@@ -173,25 +173,22 @@ void VisualDebug::create_pipeline(WGPUTextureFormat format) {
wgpuShaderModuleRelease(shader_module);
}
-void VisualDebug::add_box(const vec3& c, const vec3& e, const vec3& color) {
- // 8 corners
- vec3 p0 = vec3(c.x - e.x, c.y - e.y, c.z - e.z);
- vec3 p1 = vec3(c.x + e.x, c.y - e.y, c.z - e.z);
- vec3 p2 = vec3(c.x + e.x, c.y + e.y, c.z - e.z);
- vec3 p3 = vec3(c.x - e.x, c.y + e.y, c.z - e.z);
- vec3 p4 = vec3(c.x - e.x, c.y - e.y, c.z + e.z);
- vec3 p5 = vec3(c.x + e.x, c.y - e.y, c.z + e.z);
- vec3 p6 = vec3(c.x + e.x, c.y + e.y, c.z + e.z);
- vec3 p7 = vec3(c.x - e.x, c.y + e.y, c.z + e.z);
+void VisualDebug::add_box(const mat4& transform, const vec3& color) {
+ // 8 corners of unit cube [-1, 1]
+ vec4 p[] = {
+ transform * vec4(-1, -1, -1, 1), transform * vec4(1, -1, -1, 1),
+ transform * vec4(1, 1, -1, 1), transform * vec4(-1, 1, -1, 1),
+ transform * vec4(-1, -1, 1, 1), transform * vec4(1, -1, 1, 1),
+ transform * vec4(1, 1, 1, 1), transform * vec4(-1, 1, 1, 1)};
// 12 edges (each 2 vertices)
DebugLine edges[] = {
- {p0, p1, color}, {p1, p2, color},
- {p2, p3, color}, {p3, p0, color}, // Front face
- {p4, p5, color}, {p5, p6, color},
- {p6, p7, color}, {p7, p4, color}, // Back face
- {p0, p4, color}, {p1, p5, color},
- {p2, p6, color}, {p3, p7, color} // Connecting edges
+ {p[0].xyz(), p[1].xyz(), color}, {p[1].xyz(), p[2].xyz(), color},
+ {p[2].xyz(), p[3].xyz(), color}, {p[3].xyz(), p[0].xyz(), color}, // Front face
+ {p[4].xyz(), p[5].xyz(), color}, {p[5].xyz(), p[6].xyz(), color},
+ {p[6].xyz(), p[7].xyz(), color}, {p[7].xyz(), p[4].xyz(), color}, // Back face
+ {p[0].xyz(), p[4].xyz(), color}, {p[1].xyz(), p[5].xyz(), color},
+ {p[2].xyz(), p[6].xyz(), color}, {p[3].xyz(), p[7].xyz(), color} // Connecting edges
};
for (const auto& l : edges) {
diff --git a/src/3d/visual_debug.h b/src/3d/visual_debug.h
index f02ac6b..a58d913 100644
--- a/src/3d/visual_debug.h
+++ b/src/3d/visual_debug.h
@@ -22,7 +22,7 @@ class VisualDebug {
void shutdown();
// Queue a wireframe box for rendering this frame
- void add_box(const vec3& center, const vec3& extent, const vec3& color);
+ void add_box(const mat4& transform, const vec3& color);
// Render all queued primitives and clear the queue
void render(WGPURenderPassEncoder pass, const mat4& view_proj);
diff --git a/src/util/mini_math.h b/src/util/mini_math.h
index dc88ad4..56e6832 100644
--- a/src/util/mini_math.h
+++ b/src/util/mini_math.h
@@ -129,6 +129,10 @@ struct vec4 {
: x(x), y(y), z(z), w(w) {
}
VEC_OPERATORS(vec4, 4)
+
+ vec3 xyz() const {
+ return {x, y, z};
+ }
};
#endif /* defined(USE_VEC4) */