render3d + lab: bakes as PNGs, and impostors, the sky's light and the carpet read from their bakes

ludic.lab: lab_png_write / lab_png_write_from (raw 8-bit, 1-4 channels, stored deflate) in png_write.ludic,
importable alone with its own LabPngState; png_convert.ludic's previews of float textures (R32F min..max,
RG16F x255, HDR x/(1+x) + sRGB); lab_ppm_to_png on the same encoder.
render3d: bake_load.ludic - impostor_from_baked / impostor_source / impostor_refill (a fog re-open reads
the bake), sky_baked_in and sky_precompute trying the bake at the start yaw (sky_compute is the
convolution, and sky_ibl_bytes always uses it), carpet_from_baked / carpet_bytes / carpet_finish,
bake_part_count / _len / _off. Compile-only: nothing run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 19:10:06 +03:00
parent f79390838a
commit 6c690c5db6
15 changed files with 396 additions and 107 deletions

View file

@ -1,4 +1,4 @@
# lab_test.ludic - what the lab computes without a window: the PNG it keeps a shot as, the cameras
# lab_test.ludic - what the lab computes without a window: the PNGs it writes (a shot, raw pixels), the cameras
# a scene names, and the scenes a program adds
import "ludic.lab"
program LabTest {
@ -35,6 +35,30 @@ program LabTest {
expect(not Fs.exists(`{dir}/lab_test.ppm`))
}
test "raw pixels become a PNG of their channel count" (lab_png_st: LabPngState) {
let dir = Os.temp_dir()
let px = buffer(3 * 2 * 4)
for i in 0 .. 24 { px[i] = i * 10 }
expect(lab_png_write(lab_png_st, `{dir}/lab_test_rgba.png`, 3, 2, 4, px))
let p = Fs.read_bytes(`{dir}/lab_test_rgba.png`)
expect_eq(p[19], 3) # width
expect_eq(p[25], 6) # colour type RGBA
expect_eq(len(p), lp_png_size(3, 2, 4))
expect(not lab_png_write(lab_png_st, `{dir}/lab_test_short.png`, 9, 9, 4, px))
}
test "a half float and a float read as the numbers they store" {
let b = buffer(8)
b[0] = 0; b[1] = 60 # half 1.0 = 0x3C00
b[2] = 0; b[3] = 192 # half -2.0 = 0xC000
b[4] = 0; b[5] = 0; b[6] = 128; b[7] = 63 # float 1.0 = 0x3F800000
expect_near(lab_f16_at(b, 0), 1.0, 0.0001)
expect_near(lab_f16_at(b, 2), -2.0, 0.0001)
expect_near(lab_f32_at(b, 4), 1.0, 0.0001)
let g = lab_px_rgba16f_hdr(b, 0, 1) # 1.0 -> 0.5 -> sRGB 188
expect_eq(g[0] & 255, 188)
}
test "a camera at a point looks back at it" (lab_st: mut LabState) {
lab_shots_reset(lab_st)
lab_shot_at(lab_st, "front", 0.0, 1.0, 0.0, 10.0, 0.0, 0.0)