meat/app/render-worker.ts

64 lines
2.1 KiB
TypeScript
Raw Permalink Normal View History

2026-08-24 15:54:44 +02:00
import type { Framebuffer } from "engine/render/Framebuffer"
import { RenderProtocol, type RenderWorkerInit } from "engine/render/RenderProtocol"
import { RenderScene, type RenderInstance } from "engine/render/RenderScene"
2026-08-05 09:24:13 +02:00
const ctx = globalThis as unknown as {
addEventListener: (
type: "message",
handler: (e: { data: RenderWorkerInit }) => void,
) => void
2026-08-05 09:24:13 +02:00
}
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 cameraData = new Float64Array(m.cameraSAB)
const viewProjection = new Float32Array(m.viewProjectionSAB)
const visibleChunks = new Int32Array(m.visibleChunkSAB)
const instanceIds = new Int32Array(m.instanceIdSAB)
const instanceTransforms = new Float32Array(m.instanceTransformSAB)
2026-08-05 09:24:13 +02:00
const times = new Float64Array(m.timesSAB)
const { scene, band, config, skyStep, workerIndex } = m
const instances: RenderInstance[] = []
2026-08-05 09:24:13 +02:00
// 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, RenderProtocol.FRAME, last)
last = Atomics.load(ctrl, RenderProtocol.FRAME)
2026-08-05 09:24:13 +02:00
const t0 = performance.now()
const frameCamera = RenderProtocol.readCamera(cameraData)
const count = Atomics.load(ctrl, RenderProtocol.VISIBLE_CHUNKS)
const visible = [...visibleChunks.subarray(0, count)]
const instanceCount = Atomics.load(ctrl, RenderProtocol.VISIBLE_INSTANCES)
RenderProtocol.readInstances(
instanceIds,
instanceTransforms,
instanceCount,
instances,
)
RenderScene.renderBand(
fb,
scene,
frameCamera.camera,
viewProjection,
visible,
instances,
config,
skyStep,
frameCamera.time,
band[0],
band[1],
)
times[workerIndex] = performance.now() - t0
Atomics.add(ctrl, RenderProtocol.DONE, 1)
2026-08-05 09:24:13 +02:00
}
})