diff options
Diffstat (limited to 'assets/final')
| -rw-r--r-- | assets/final/shaders/lighting.wgsl | 9 | ||||
| -rw-r--r-- | assets/final/shaders/math/sdf_utils.wgsl | 9 | ||||
| -rw-r--r-- | assets/final/shaders/mesh_render.wgsl | 8 | ||||
| -rw-r--r-- | assets/final/shaders/render/scene_query_bvh.wgsl | 13 | ||||
| -rw-r--r-- | assets/final/shaders/render/scene_query_linear.wgsl | 24 | ||||
| -rw-r--r-- | assets/final/shaders/renderer_3d.wgsl | 55 |
6 files changed, 79 insertions, 39 deletions
diff --git a/assets/final/shaders/lighting.wgsl b/assets/final/shaders/lighting.wgsl index 277909b..ac2142b 100644 --- a/assets/final/shaders/lighting.wgsl +++ b/assets/final/shaders/lighting.wgsl @@ -1,10 +1,11 @@ -fn get_normal_basic(p: vec3<f32>, obj_type: f32) -> vec3<f32> { +fn get_normal_basic(p: vec3<f32>, obj_params: vec4<f32>) -> vec3<f32> { + let obj_type = obj_params.x; if (obj_type == 1.0) { return normalize(p); } let e = vec2<f32>(0.001, 0.0); return normalize(vec3<f32>( - get_dist(p + e.xyy, obj_type) - get_dist(p - e.xyy, obj_type), - get_dist(p + e.yxy, obj_type) - get_dist(p - e.yxy, obj_type), - get_dist(p + e.yyx, obj_type) - get_dist(p - e.yyx, obj_type) + get_dist(p + e.xyy, obj_params) - get_dist(p - e.xyy, obj_params), + get_dist(p + e.yxy, obj_params) - get_dist(p - e.yxy, obj_params), + get_dist(p + e.yyx, obj_params) - get_dist(p - e.yyx, obj_params) )); } diff --git a/assets/final/shaders/math/sdf_utils.wgsl b/assets/final/shaders/math/sdf_utils.wgsl index 502ba5b..c2e49cf 100644 --- a/assets/final/shaders/math/sdf_utils.wgsl +++ b/assets/final/shaders/math/sdf_utils.wgsl @@ -1,10 +1,11 @@ -fn get_normal_basic(p: vec3<f32>, obj_type: f32) -> vec3<f32> { +fn get_normal_basic(p: vec3<f32>, obj_params: vec4<f32>) -> vec3<f32> { + let obj_type = obj_params.x; if (obj_type == 1.0) { return normalize(p); } let e = vec2<f32>(0.001, 0.0); return normalize(vec3<f32>( - get_dist(p + e.xyy, obj_type) - get_dist(p - e.xyy, obj_type), - get_dist(p + e.yxy, obj_type) - get_dist(p - e.yxy, obj_type), - get_dist(p + e.yyx, obj_type) - get_dist(p - e.yyx, obj_type) + get_dist(p + e.xyy, obj_params) - get_dist(p - e.xyy, obj_params), + get_dist(p + e.yxy, obj_params) - get_dist(p - e.yxy, obj_params), + get_dist(p + e.yyx, obj_params) - get_dist(p - e.yyx, obj_params) )); } diff --git a/assets/final/shaders/mesh_render.wgsl b/assets/final/shaders/mesh_render.wgsl index 3759747..068efbc 100644 --- a/assets/final/shaders/mesh_render.wgsl +++ b/assets/final/shaders/mesh_render.wgsl @@ -33,9 +33,9 @@ fn vs_main(in: VertexInput, @builtin(instance_index) instance_index: u32) -> Ver out.clip_pos = globals.view_proj * world_pos; out.world_pos = world_pos.xyz; - // Normal transform (assuming uniform scale or using transpose(inverse(model))) - // For simplicity, we use the same mat3 logic as renderer_3d.wgsl - let normal_matrix = mat3x3<f32>(obj.model[0].xyz, obj.model[1].xyz, obj.model[2].xyz); + // Use transpose of inverse for normals + // Note: mat3x3 constructor takes columns, so passing rows gives us transpose + let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz); out.normal = normalize(normal_matrix * in.normal); out.uv = in.uv; @@ -56,4 +56,4 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let lit_color = calculate_lighting(in.color.rgb, in.normal, in.world_pos, shadow); return vec4<f32>(lit_color, in.color.a); -} +}
\ No newline at end of file diff --git a/assets/final/shaders/render/scene_query_bvh.wgsl b/assets/final/shaders/render/scene_query_bvh.wgsl index c7dfdf4..61efe49 100644 --- a/assets/final/shaders/render/scene_query_bvh.wgsl +++ b/assets/final/shaders/render/scene_query_bvh.wgsl @@ -10,11 +10,13 @@ struct BVHNode { @group(0) @binding(2) var<storage, read> bvh_nodes: array<BVHNode>; -fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 { +fn get_dist(p: vec3<f32>, obj_params: vec4<f32>) -> f32 { + let obj_type = obj_params.x; if (obj_type == 1.0) { return length(p) - 1.0; } // Unit Sphere if (obj_type == 2.0) { return sdBox(p, vec3<f32>(1.0)); } // Unit Box if (obj_type == 3.0) { return sdTorus(p, vec2<f32>(1.0, 0.4)); } // Unit Torus if (obj_type == 4.0) { return sdPlane(p, vec3<f32>(0.0, 1.0, 0.0), 0.0); } + if (obj_type == 5.0) { return sdBox(p, obj_params.yzw); } // MESH AABB return 100.0; } @@ -40,7 +42,14 @@ fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 { let obj = object_data.objects[obj_idx]; let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj.params.x) * s); + // IMPORTANT: Plane (type 4.0) and Mesh (type 5.0) should not be scaled by 's'. + // The 's' factor is meant for unit primitives (sphere, box, torus) that are + // scaled by the model matrix. Meshes already have correct local-space extents. + if (obj.params.x != 4.0 && obj.params.x != 5.0) { // Not plane, not mesh + d = min(d, get_dist(q, obj.params) * s); + } else { + d = min(d, get_dist(q, obj.params)); + } } else { // Internal if (stack_ptr < 31) { stack[stack_ptr] = node.left_idx; diff --git a/assets/final/shaders/render/scene_query_linear.wgsl b/assets/final/shaders/render/scene_query_linear.wgsl index 7bcd96f..b61a7e4 100644 --- a/assets/final/shaders/render/scene_query_linear.wgsl +++ b/assets/final/shaders/render/scene_query_linear.wgsl @@ -1,26 +1,32 @@ #include "math/sdf_shapes" +#include "math/sdf_utils" -fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 { +fn get_dist(p: vec3<f32>, obj_params: vec4<f32>) -> f32 { + let obj_type = obj_params.x; if (obj_type == 1.0) { return length(p) - 1.0; } // Unit Sphere if (obj_type == 2.0) { return sdBox(p, vec3<f32>(1.0)); } // Unit Box if (obj_type == 3.0) { return sdTorus(p, vec2<f32>(1.0, 0.4)); } // Unit Torus if (obj_type == 4.0) { return sdPlane(p, vec3<f32>(0.0, 1.0, 0.0), 0.0); } + if (obj_type == 5.0) { return sdBox(p, obj_params.yzw); } // MESH AABB return 100.0; } fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 { var d = 1000.0; - let count = u32(globals.params.x); - - for (var i = 0u; i < count; i = i + 1u) { + let num_objects = arrayLength(&object_data.objects); + for (var i = 0u; i < num_objects; i++) { if (i == skip_idx) { continue; } let obj = object_data.objects[i]; - let obj_type = obj.params.x; - if (obj_type <= 0.0) { continue; } - let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj_type) * s); + // IMPORTANT: Plane (type 4.0) and Mesh (type 5.0) should not be scaled by 's'. + // The 's' factor is meant for unit primitives (sphere, box, torus) that are + // scaled by the model matrix. Meshes already have correct local-space extents. + if (obj.params.x != 4.0 && obj.params.x != 5.0) { // Not plane, not mesh + d = min(d, get_dist(q, obj.params) * s); + } else { + d = min(d, get_dist(q, obj.params)); + } } return d; -} +}
\ No newline at end of file diff --git a/assets/final/shaders/renderer_3d.wgsl b/assets/final/shaders/renderer_3d.wgsl index e7cb810..c290df8 100644 --- a/assets/final/shaders/renderer_3d.wgsl +++ b/assets/final/shaders/renderer_3d.wgsl @@ -15,6 +15,7 @@ struct VertexOutput { @location(1) color: vec4<f32>, @location(2) @interpolate(flat) instance_index: u32, @location(3) world_pos: vec3<f32>, + @location(4) transformed_normal: vec3<f32>, }; @vertex @@ -41,8 +42,10 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, let obj_type = obj.params.x; if (obj_type == 5.0) { // MESH + // For meshes, we use the actual vertex data, not proxy geometry. + // The position here is a placeholder, the real mesh data is handled by mesh_pipeline_. var out: VertexOutput; - out.position = vec4<f32>(0.0, 0.0, 0.0, 0.0); + out.position = vec4<f32>(0.0, 0.0, 2.0, 1.0); // Outside far plane, so it's not rendered by this pipeline. return out; } @@ -62,6 +65,11 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, out.color = obj.color; out.instance_index = instance_index; out.world_pos = world_pos.xyz; + + // For SDF primitives, we don't use vertex normals - they are computed analytically in the fragment shader. + // This field is only used by the mesh pipeline (mesh_render.wgsl), not this SDF pipeline. + out.transformed_normal = normalize(vec3<f32>(0.0, 1.0, 0.0)); // Placeholder + return out; } @@ -70,8 +78,13 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, #include "render/lighting_utils" #include "ray_box" +struct FragmentOutput { + @location(0) color: vec4<f32>, + @builtin(frag_depth) depth: f32, +}; + @fragment -fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { +fn fs_main(in: VertexOutput) -> FragmentOutput { let obj = object_data.objects[in.instance_index]; let obj_type = obj.params.x; @@ -80,11 +93,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { var base_color = in.color.rgb; let light_dir = normalize(vec3<f32>(1.0, 1.0, 1.0)); - if (obj_type <= 0.0) { // Raster path + if (obj_type <= 0.0) { // Raster path (legacy or generic) p = in.world_pos; - let local_normal = normalize(cross(dpdx(in.local_pos), dpdy(in.local_pos))); - 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); + // Use the transformed normal passed from the vertex shader for rasterized objects + normal = normalize(in.transformed_normal); // Apply grid pattern to floor let uv = p.xz * 0.5; @@ -100,8 +112,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let rd_local = normalize((obj.inv_model * vec4<f32>(rd_world, 0.0)).xyz); // Proxy box extent (matches vs_main) + // MESHES use obj.params.yzw for extent var extent = vec3<f32>(1.0); - if (obj_type == 3.0) { extent = vec3<f32>(1.5, 0.5, 1.5); } + if (obj.params.x == 3.0) { extent = vec3<f32>(1.5, 0.5, 1.5); } // Torus + else if (obj.params.x == 5.0) { extent = obj.params.yzw; } // MESH extent let bounds = ray_box_intersection(ro_local, rd_local, extent); @@ -111,7 +125,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { var hit = false; for (var i = 0; i < 64; i = i + 1) { let q = ro_local + rd_local * t; - let d_local = get_dist(q, obj_type); + let d_local = get_dist(q, obj.params); if (d_local < 0.0005) { hit = true; break; } t = t + d_local; if (t > bounds.t_exit) { break; } @@ -128,36 +142,37 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { 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 d_x1 = get_dist(q_x1, obj.params) - 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 d_x2 = get_dist(q_x2, obj.params) - 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 d_y1 = get_dist(q_y1, obj.params) - 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 d_y2 = get_dist(q_y2, obj.params) - 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 d_z1 = get_dist(q_z1, obj.params) - 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 d_z2 = get_dist(q_z2, obj.params) - disp_strength * h_z2; let n_local = normalize(vec3<f32>(d_x1 - d_x2, d_y1 - d_y2, d_z1 - d_z2)); + // Note: mat3x3 constructor takes columns, so passing rows gives us transpose 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); + normal = normalize(normal_matrix * n_local); // Apply texture to SDF color if (in.instance_index == 0u || obj_type == 4.0) { // Floor (index 0) or PLANE @@ -174,5 +189,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let shadow = calc_shadow(p, light_dir, 0.05, 20.0, in.instance_index); let lit_color = calculate_lighting(base_color, normal, p, shadow); - return vec4<f32>(lit_color, 1.0); + + var out: FragmentOutput; + out.color = vec4<f32>(lit_color, 1.0); + + // Calculate and write correct depth + let clip_pos = globals.view_proj * vec4<f32>(p, 1.0); + out.depth = clip_pos.z / clip_pos.w; + + return out; }
\ No newline at end of file |
