feat: culling

This commit is contained in:
Dan Finch 2026-08-04 15:05:02 +02:00
parent 680e08aadc
commit ef5029da1d
7 changed files with 309 additions and 103 deletions

View file

@ -46,6 +46,7 @@ export namespace Rasterizer {
texture: Texture,
viewProj: Mat4,
config: RenderConfig,
cull = false,
): void {
const { vertices, indices } = mesh
for (let t = 0; t + 2 < indices.length; t += 3) {
@ -56,7 +57,7 @@ export namespace Rasterizer {
// Near-clipping can turn one triangle into a quad; fan it back to tris.
const poly = clipNear([project(viewProj, a), project(viewProj, b), project(viewProj, c)])
for (let k = 1; k + 1 < poly.length; k++) {
fillTriangle(fb, poly[0], poly[k], poly[k + 1], shade, texture, config)
fillTriangle(fb, poly[0], poly[k], poly[k + 1], shade, texture, config, cull)
}
}
}
@ -146,6 +147,7 @@ export namespace Rasterizer {
shade: number,
texture: Texture,
config: RenderConfig,
cull: boolean,
): void {
const a = toScreen(fb, va, config.vertexSnap)
const b = toScreen(fb, vb, config.vertexSnap)
@ -154,6 +156,12 @@ export namespace Rasterizer {
if (area === 0) {
return
}
// Backface cull: a back-facing triangle has the opposite screen winding
// (positive area here). Only enabled for solid, consistently-wound meshes;
// sprites and the room stay double-sided (cull = false).
if (cull && area > 0) {
return
}
const minX = Math.max(0, Math.floor(Math.min(a.sx, b.sx, c.sx)))
const maxX = Math.min(fb.width - 1, Math.ceil(Math.max(a.sx, b.sx, c.sx)))
const minY = Math.max(0, Math.floor(Math.min(a.sy, b.sy, c.sy)))