summaryrefslogtreecommitdiff
path: root/src/3d/renderer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3d/renderer.cc')
-rw-r--r--src/3d/renderer.cc89
1 files changed, 29 insertions, 60 deletions
diff --git a/src/3d/renderer.cc b/src/3d/renderer.cc
index 505cd31..db50a35 100644
--- a/src/3d/renderer.cc
+++ b/src/3d/renderer.cc
@@ -101,11 +101,12 @@ fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 {
return 100.0;
}
-fn map_scene(p: vec3<f32>) -> f32 {
+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) {
+ if (i == skip_idx) { continue; }
let obj = object_data.objects[i];
let obj_type = obj.params.x;
if (obj_type <= 0.0) { continue; }
@@ -121,16 +122,16 @@ fn map_scene(p: vec3<f32>) -> f32 {
return d;
}
-fn calc_shadow(ro: vec3<f32>, rd: vec3<f32>, tmin: f32, tmax: f32) -> f32 {
+fn calc_shadow(ro: vec3<f32>, rd: vec3<f32>, tmin: f32, tmax: f32, skip_idx: u32) -> f32 {
var res = 1.0;
var t = tmin;
- if (t < 0.02) { t = 0.02; }
+ if (t < 0.05) { t = 0.05; } // Avoid self-shadowing
for (var i = 0; i < 32; i = i + 1) {
- let h = map_scene(ro + rd * t);
+ let h = map_scene(ro + rd * t, skip_idx);
if (h < 0.001) { return 0.0; }
- res = min(res, 32.0 * h / t); // Harder shadows k=32
- t = t + clamp(h, 0.01, 0.5);
+ res = min(res, 16.0 * h / t); // Soft shadow k=16
+ t = t + clamp(h, 0.02, 0.5);
if (t > tmax) { break; }
}
return clamp(res, 0.0, 1.0);
@@ -154,84 +155,52 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
var p: vec3<f32>;
var normal: vec3<f32>;
var base_color = in.color.rgb;
- let light_dir = normalize(vec3<f32>(0.2, 1.0, 0.2)); // More vertical light for easier shadow debugging
+ // Tilted light for longer, more visible shadows
+ let light_dir = normalize(vec3<f32>(1.0, 1.0, 1.0));
- if (obj_type == 0.0) { // Rasterized object
+ if (obj_type <= 0.0) { // Rasterized object (legacy path)
p = in.world_pos;
let local_normal = normalize(cross(dpdx(in.local_pos), dpdy(in.local_pos)));
-
- // Correct normal transformation using inverse transpose
let mat3_it = mat3x3<f32>(obj.model_inv_tr[0].xyz, obj.model_inv_tr[1].xyz, obj.model_inv_tr[2].xyz);
normal = normalize(mat3_it * local_normal);
-
- // Apply grid texture for color to floor
- 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 object
let center = vec3<f32>(obj.model[3].x, obj.model[3].y, obj.model[3].z);
let scale = length(vec3<f32>(obj.model[0].x, obj.model[0].y, obj.model[0].z));
let ro = globals.camera_pos_time.xyz;
let rd = normalize(in.world_pos - ro);
- var t = length(in.world_pos - ro);
- p = ro + rd * t;
+ var t_hit = length(in.world_pos - ro);
+ p = ro + rd * t_hit;
let mat3 = mat3x3<f32>(obj.model[0].xyz/scale, obj.model[1].xyz/scale, obj.model[2].xyz/scale);
var hit = false;
- for (var i = 0; i < 40; i = i + 1) {
+ // Raymarch into the proxy box to find the SDF surface
+ for (var i = 0; i < 64; i = i + 1) {
let q = transpose(mat3) * (p - center) / scale;
- let d_world = get_dist(q, obj_type) * scale;
+ let d_local = get_dist(q, obj_type);
+ let d_world = d_local * scale;
if (d_world < 0.001) { hit = true; break; }
- if (d_world > 3.0 * scale) { break; }
+ if (d_world > 3.0 * scale) { break; } // Out of proxy box bounds
p = p + rd * d_world;
}
if (!hit) { discard; }
let q_hit = transpose(mat3) * (p - center) / scale;
-
- let e = vec2<f32>(0.005, 0.0);
- let disp_strength = 0.05;
-
- // Calculate normal with bump mapping
- 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));
-
- normal = normalize(mat3 * n_local);
+ normal = normalize(mat3 * get_normal(q_hit, obj_type));
+
+ // Optional: procedural grid for all objects, but mainly for the floor
+ if (obj_type == 4.0) { // Plane
+ let uv = p.xz * 0.2;
+ let grid = 0.5 + 0.5 * sin(uv.x * 3.14 * 2.0) * sin(uv.y * 3.14 * 2.0);
+ base_color = base_color * (0.6 + 0.4 * smoothstep(0.45, 0.55, grid));
+ }
}
- let shadow = calc_shadow(p + normal * 0.01, light_dir, 0.0, 20.0);
- let lighting = (max(dot(normal, light_dir), 0.0) * shadow) + 0.1;
+ // Shadow ray start from hit point p
+ let shadow = calc_shadow(p, light_dir, 0.1, 20.0, in.instance_index);
+ // Darken shadowed areas significantly
+ let lighting = (max(dot(normal, light_dir), 0.0) * (0.2 + 0.8 * shadow)) + 0.1;
return vec4<f32>(base_color * lighting, 1.0);
}