summaryrefslogtreecommitdiff
path: root/src/3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/3d')
-rw-r--r--src/3d/renderer.cc45
1 files changed, 19 insertions, 26 deletions
diff --git a/src/3d/renderer.cc b/src/3d/renderer.cc
index db50a35..9f3f40c 100644
--- a/src/3d/renderer.cc
+++ b/src/3d/renderer.cc
@@ -109,6 +109,7 @@ fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 {
if (i == skip_idx) { continue; }
let obj = object_data.objects[i];
let obj_type = obj.params.x;
+ // Skip rasterized objects (like the floor) in the SDF map
if (obj_type <= 0.0) { continue; }
let center = vec3<f32>(obj.model[3].x, obj.model[3].y, obj.model[3].z);
@@ -125,16 +126,16 @@ fn map_scene(p: vec3<f32>, skip_idx: u32) -> 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.05) { t = 0.05; } // Avoid self-shadowing
-
- for (var i = 0; i < 32; i = i + 1) {
+ for (var i = 0; i < 30; i = i + 1) {
let h = map_scene(ro + rd * t, skip_idx);
- if (h < 0.001) { return 0.0; }
- res = min(res, 16.0 * h / t); // Soft shadow k=16
- t = t + clamp(h, 0.02, 0.5);
+ if (h < 0.001) {
+ return 0.0;
+ }
+ res = min(res, 8.0 * h / t); // Soft shadow k=8
+ t = t + h;
if (t > tmax) { break; }
}
- return clamp(res, 0.0, 1.0);
+ return res;
}
fn get_normal(p: vec3<f32>, obj_type: f32) -> vec3<f32> {
@@ -155,14 +156,17 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
var p: vec3<f32>;
var normal: vec3<f32>;
var base_color = in.color.rgb;
- // Tilted light for longer, more visible shadows
- let light_dir = normalize(vec3<f32>(1.0, 1.0, 1.0));
+ let light_dir = normalize(vec3<f32>(0.2, 1.0, 0.2));
- if (obj_type <= 0.0) { // Rasterized object (legacy path)
+ if (obj_type <= 0.0) { // Rasterized object
p = in.world_pos;
let local_normal = normalize(cross(dpdx(in.local_pos), dpdy(in.local_pos)));
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);
+
+ 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));
@@ -174,13 +178,11 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let mat3 = mat3x3<f32>(obj.model[0].xyz/scale, obj.model[1].xyz/scale, obj.model[2].xyz/scale);
var hit = false;
- // Raymarch into the proxy box to find the SDF surface
- for (var i = 0; i < 64; i = i + 1) {
+ for (var i = 0; i < 40; i = i + 1) {
let q = transpose(mat3) * (p - center) / scale;
- let d_local = get_dist(q, obj_type);
- let d_world = d_local * scale;
+ let d_world = get_dist(q, obj_type) * scale;
if (d_world < 0.001) { hit = true; break; }
- if (d_world > 3.0 * scale) { break; } // Out of proxy box bounds
+ if (d_world > 3.0 * scale) { break; }
p = p + rd * d_world;
}
@@ -188,19 +190,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let q_hit = transpose(mat3) * (p - center) / scale;
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));
- }
}
- // 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;
+ let shadow = calc_shadow(p + normal * 0.01, light_dir, 0.01, 20.0, in.instance_index);
+ let lighting = (max(dot(normal, light_dir), 0.0) * shadow) + 0.1;
return vec4<f32>(base_color * lighting, 1.0);
}