2026-08-05 09:24:13 +02:00
|
|
|
import type { Framebuffer } from "../engine/render/Framebuffer"
|
|
|
|
|
import type { RenderConfig } from "../engine/render/RenderConfig"
|
2026-08-08 14:15:32 +02:00
|
|
|
import { MOB_KINDS } from "../game/actors/Mob"
|
|
|
|
|
import { renderBand, MOB_FLOATS, type MobDraw, type Scene } from "../game/renderScene"
|
2026-08-05 09:24:13 +02:00
|
|
|
|
|
|
|
|
/** One-time setup: shared framebuffer + control/param buffers, the (cloned)
|
|
|
|
|
* scene, this worker's row band, and its index into the per-worker times array. */
|
|
|
|
|
type Init = {
|
|
|
|
|
colorSAB: SharedArrayBuffer
|
|
|
|
|
depthSAB: SharedArrayBuffer
|
|
|
|
|
width: number
|
|
|
|
|
height: number
|
|
|
|
|
scene: Scene
|
|
|
|
|
band: [number, number]
|
|
|
|
|
config: RenderConfig
|
|
|
|
|
skyStep: number
|
|
|
|
|
ctrlSAB: SharedArrayBuffer
|
|
|
|
|
camSAB: SharedArrayBuffer
|
|
|
|
|
vpSAB: SharedArrayBuffer
|
|
|
|
|
visSAB: SharedArrayBuffer
|
2026-08-07 12:49:13 +02:00
|
|
|
mobSAB: SharedArrayBuffer
|
2026-08-05 09:24:13 +02:00
|
|
|
timesSAB: SharedArrayBuffer
|
|
|
|
|
index: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const FRAME = 0
|
|
|
|
|
const DONE = 1
|
|
|
|
|
const VIS = 2
|
2026-08-07 12:49:13 +02:00
|
|
|
const MOBVIS = 3
|
2026-08-05 09:24:13 +02:00
|
|
|
|
|
|
|
|
const ctx = globalThis as unknown as {
|
|
|
|
|
addEventListener: (type: "message", handler: (e: { data: Init }) => void) => void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.addEventListener("message", (e) => {
|
|
|
|
|
const m = e.data
|
|
|
|
|
const fb: Framebuffer = {
|
|
|
|
|
width: m.width,
|
|
|
|
|
height: m.height,
|
|
|
|
|
color: new Uint32Array(m.colorSAB),
|
|
|
|
|
depth: new Float32Array(m.depthSAB),
|
|
|
|
|
}
|
|
|
|
|
const ctrl = new Int32Array(m.ctrlSAB)
|
|
|
|
|
const cam = new Float64Array(m.camSAB)
|
|
|
|
|
const vp = new Float32Array(m.vpSAB)
|
|
|
|
|
const vis = new Int32Array(m.visSAB)
|
2026-08-07 12:49:13 +02:00
|
|
|
const mob = new Float32Array(m.mobSAB)
|
2026-08-05 09:24:13 +02:00
|
|
|
const times = new Float64Array(m.timesSAB)
|
|
|
|
|
const { scene, band, config, skyStep, index } = m
|
|
|
|
|
|
|
|
|
|
// Lock-free frame loop: block until main bumps the frame counter, render this
|
|
|
|
|
// band, record the band time, and signal done. No messages per frame.
|
|
|
|
|
let last = 0
|
|
|
|
|
for (;;) {
|
|
|
|
|
Atomics.wait(ctrl, FRAME, last)
|
|
|
|
|
last = Atomics.load(ctrl, FRAME)
|
|
|
|
|
const t0 = performance.now()
|
|
|
|
|
const camera = { position: { x: cam[0], y: cam[1], z: cam[2] }, yaw: cam[3], pitch: cam[4], fov: cam[5] }
|
|
|
|
|
const count = Atomics.load(ctrl, VIS)
|
|
|
|
|
const visible = [...vis.subarray(0, count)]
|
2026-08-07 12:49:13 +02:00
|
|
|
const mobCount = Atomics.load(ctrl, MOBVIS)
|
|
|
|
|
const mobDraws: MobDraw[] = []
|
|
|
|
|
for (let i = 0; i < mobCount; i++) {
|
|
|
|
|
const o = i * MOB_FLOATS
|
2026-08-07 13:37:30 +02:00
|
|
|
mobDraws.push({ kind: MOB_KINDS[mob[o]] ?? "frog", x: mob[o + 1], y: mob[o + 2], z: mob[o + 3], heading: mob[o + 4], scale: mob[o + 5] })
|
2026-08-07 12:49:13 +02:00
|
|
|
}
|
|
|
|
|
renderBand(fb, scene, camera, vp, visible, mobDraws, config, skyStep, cam[6], band[0], band[1])
|
2026-08-05 09:24:13 +02:00
|
|
|
times[index] = performance.now() - t0
|
|
|
|
|
Atomics.add(ctrl, DONE, 1)
|
|
|
|
|
}
|
|
|
|
|
})
|