From 13263b91c69401a232aad938b09885dd74a5ec95 Mon Sep 17 00:00:00 2001 From: asrael Date: Fri, 6 Feb 2026 23:28:02 -0600 Subject: [PATCH] improve baked lighting and improve wireframe perf --- README.md | 4 +-- demo/mod/first_person3d.fnl | 2 +- pxl8d/src/procgen.rs | 7 +++-- src/gfx/pxl8_gfx.h | 8 ++++++ src/gfx/pxl8_render.c | 55 ++++++++++++++++++++++++++++++------- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 49b7324..29963a4 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,12 @@ - **Rust nightly** (edition 2024) - Required for [pxl8d](pxl8d) server - **SDL3** - System package or auto-vendored -## License +### License pxl8 is free and open source. All code in this repository is licensed under: - Mozilla Public License, Version 2.0 ([LICENSE](LICENSE) or https://mozilla.org/MPL/2.0/) -Third-party dependencies (Fennel, linenoise, LuaJIT, miniz, SDL3) retain their original licenses. -
 @@@@@@@@@@@@@@@@@@@@@**^^""~~~"^@@^*@*@@**@@@@@@@@@
 @@@@@@@@@@@@@*^^'"~   , - ' '; ,@@b. '  -e@@@@@@@@@
diff --git a/demo/mod/first_person3d.fnl b/demo/mod/first_person3d.fnl
index 81d25be..bc3fa85 100644
--- a/demo/mod/first_person3d.fnl
+++ b/demo/mod/first_person3d.fnl
@@ -343,7 +343,7 @@
 
         (pxl8.push_target)
         (pxl8.begin_frame_3d camera lights {
-          :ambient 25
+          :ambient 2
           :dither true
           :fog_density 0.0
           :celestial_dir [0.5 -0.8 0.3]
diff --git a/pxl8d/src/procgen.rs b/pxl8d/src/procgen.rs
index f6fb97e..a344792 100644
--- a/pxl8d/src/procgen.rs
+++ b/pxl8d/src/procgen.rs
@@ -533,8 +533,9 @@ fn compute_vertex_light(
         let light_dir = to_light.normalize();
         let ndotl = normal.dot(light_dir).max(0.0);
 
-        let attenuation = (1.0 - dist / light.radius).max(0.0);
-        let attenuation = attenuation * attenuation;
+        let dist_sq = to_light.dot(to_light);
+        let radius_sq = light.radius * light.radius;
+        let attenuation = (1.0 - dist_sq / radius_sq).max(0.0);
 
         total += light.intensity * ndotl * attenuation;
     }
@@ -1056,7 +1057,7 @@ pub fn generate_rooms(params: &ProcgenParams) -> Bsp {
 
         Some(LightSource {
             position: Vec3::new(cx, light_height, cz),
-            intensity: 1.8,
+            intensity: 1.5,
             radius: 160.0,
         })
     }).collect();
diff --git a/src/gfx/pxl8_gfx.h b/src/gfx/pxl8_gfx.h
index 81b83cf..196b486 100644
--- a/src/gfx/pxl8_gfx.h
+++ b/src/gfx/pxl8_gfx.h
@@ -21,6 +21,14 @@ typedef struct pxl8_gfx_stats {
     u64 triangles;
 } pxl8_gfx_stats;
 
+enum {
+    PXL8_CLIP_INSIDE = 0,
+    PXL8_CLIP_LEFT   = 1,
+    PXL8_CLIP_RIGHT  = 2,
+    PXL8_CLIP_BOTTOM = 4,
+    PXL8_CLIP_TOP    = 8,
+};
+
 typedef enum pxl8_gfx_effect {
     PXL8_GFX_EFFECT_GLOWS = 0,
 } pxl8_gfx_effect;
diff --git a/src/gfx/pxl8_render.c b/src/gfx/pxl8_render.c
index ee7954a..76417e7 100644
--- a/src/gfx/pxl8_render.c
+++ b/src/gfx/pxl8_render.c
@@ -630,10 +630,18 @@ static void rasterize_triangle(
     }
 }
 
+static inline u8 clip_outcode(i32 x, i32 y, i32 xmin, i32 ymin, i32 xmax, i32 ymax) {
+    u8 code = PXL8_CLIP_INSIDE;
+    if (x < xmin) code |= PXL8_CLIP_LEFT;
+    else if (x > xmax) code |= PXL8_CLIP_RIGHT;
+    if (y < ymin) code |= PXL8_CLIP_TOP;
+    else if (y > ymax) code |= PXL8_CLIP_BOTTOM;
+    return code;
+}
+
 static void draw_line_clipped(
     u8* fb,
     u32 fb_w,
-    u32 fb_h,
     i32 x0,
     i32 y0,
     i32 x1,
@@ -644,18 +652,45 @@ static void draw_line_clipped(
     i32 clip_max_x,
     i32 clip_max_y
 ) {
+    u8 c0 = clip_outcode(x0, y0, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+    u8 c1 = clip_outcode(x1, y1, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
+
+    for (;;) {
+        if ((c0 | c1) == 0) break;
+        if (c0 & c1) return;
+
+        u8 out = c0 ? c0 : c1;
+        i32 x, y;
+        i32 dx = x1 - x0;
+        i32 dy = y1 - y0;
+
+        if (out & PXL8_CLIP_BOTTOM) {
+            x = x0 + dx * (clip_max_y - y0) / dy;
+            y = clip_max_y;
+        } else if (out & PXL8_CLIP_TOP) {
+            x = x0 + dx * (clip_min_y - y0) / dy;
+            y = clip_min_y;
+        } else if (out & PXL8_CLIP_RIGHT) {
+            y = y0 + dy * (clip_max_x - x0) / dx;
+            x = clip_max_x;
+        } else {
+            y = y0 + dy * (clip_min_x - x0) / dx;
+            x = clip_min_x;
+        }
+
+        if (out == c0) { x0 = x; y0 = y; c0 = clip_outcode(x0, y0, clip_min_x, clip_min_y, clip_max_x, clip_max_y); }
+        else { x1 = x; y1 = y; c1 = clip_outcode(x1, y1, clip_min_x, clip_min_y, clip_max_x, clip_max_y); }
+    }
+
     i32 dx = abs(x1 - x0);
     i32 dy = -abs(y1 - y0);
     i32 sx = x0 < x1 ? 1 : -1;
     i32 sy = y0 < y1 ? 1 : -1;
     i32 err = dx + dy;
+    i32 w = (i32)fb_w;
 
-    while (true) {
-        if (x0 >= clip_min_x && x0 <= clip_max_x && y0 >= clip_min_y && y0 <= clip_max_y) {
-            if (x0 >= 0 && y0 >= 0 && x0 < (i32)fb_w && y0 < (i32)fb_h) {
-                fb[y0 * (i32)fb_w + x0] = color;
-            }
-        }
+    for (;;) {
+        fb[y0 * w + x0] = color;
         if (x0 == x1 && y0 == y1) break;
         i32 e2 = 2 * err;
         if (e2 >= dy) { err += dy; x0 += sx; }
@@ -1305,11 +1340,11 @@ static void execute_draw(
                 }
 
                 u8 wire_color = v0->color ? v0->color : 15;
-                draw_line_clipped(fb, fb_w, fb_h, sx0, sy0, sx1, sy1, wire_color,
+                draw_line_clipped(fb, fb_w, sx0, sy0, sx1, sy1, wire_color,
                     clip_min_x, clip_min_y, clip_max_x, clip_max_y);
-                draw_line_clipped(fb, fb_w, fb_h, sx1, sy1, sx2, sy2, wire_color,
+                draw_line_clipped(fb, fb_w, sx1, sy1, sx2, sy2, wire_color,
                     clip_min_x, clip_min_y, clip_max_x, clip_max_y);
-                draw_line_clipped(fb, fb_w, fb_h, sx2, sy2, sx0, sy0, wire_color,
+                draw_line_clipped(fb, fb_w, sx2, sy2, sx0, sy0, wire_color,
                     clip_min_x, clip_min_y, clip_max_x, clip_max_y);
             } else {
                 tri_setup setup;