diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-02 16:46:59 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-02 16:46:59 +0100 |
| commit | 2184a1043d1a071cdc78303b2247145bf3f18c0b (patch) | |
| tree | 948703ba6541391578c0917fd1ffb208209a321e /src/3d | |
| parent | fe00b372ea6c376d5e67a1b7392c3fa4f72e6378 (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.
Diffstat (limited to 'src/3d')
| -rw-r--r-- | src/3d/renderer.cc | 46 | ||||
| -rw-r--r-- | src/3d/visual_debug.cc | 29 | ||||
| -rw-r--r-- | src/3d/visual_debug.h | 2 |
3 files changed, 56 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); |
