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

@ -1,4 +1,5 @@
import { Framebuffer } from "../engine/render/Framebuffer"
import { Frustum } from "../engine/render/Frustum"
import { Rasterizer } from "../engine/render/Rasterizer"
import { RenderConfig } from "../engine/render/RenderConfig"
import { Sky } from "../engine/render/Sky"
@ -9,6 +10,8 @@ import { buildLevel } from "./level"
import { EYE_HEIGHT, Player } from "./player"
const FOV = Math.PI / 3
/** Sky is drawn at 1/SKY_STEP resolution (the cloud fbm is the costly part). */
const SKY_STEP = 2
const screen = document.querySelector<HTMLCanvasElement>("#screen")!
const ctx = screen.getContext("2d")!
@ -109,15 +112,23 @@ async function main(): Promise<void> {
}
const viewProj = Camera.viewProjection(camera, fb.width / fb.height)
Sky.render(fb, camera, level.sky, now / 1000)
Rasterizer.draw(fb, level.ground, textures.grass, viewProj, config)
Sky.render(fb, camera, level.sky, now / 1000, SKY_STEP)
// Room is small and always near where you play; draw it unconditionally.
Rasterizer.draw(fb, level.floor, textures.floor, viewProj, config)
Rasterizer.draw(fb, level.walls, textures.wall, viewProj, config)
Rasterizer.draw(fb, level.crate, textures.crate, viewProj, config)
Rasterizer.draw(fb, level.boulders, textures.rock, viewProj, config)
Rasterizer.draw(fb, level.trunks, textures.bark, viewProj, config)
Rasterizer.draw(fb, level.oakFoliage, textures.leaf, viewProj, config)
Rasterizer.draw(fb, level.spruceFoliage, textures.needle, viewProj, config)
// Outdoor world: skip whole chunks that fall outside the view frustum.
const frustum = Frustum.fromViewProj(viewProj)
for (const c of level.chunks) {
if (!Frustum.intersectsAabb(frustum, c.minX, c.minY, c.minZ, c.maxX, c.maxY, c.maxZ)) {
continue
}
Rasterizer.draw(fb, c.grass, textures.grass, viewProj, config, true)
Rasterizer.draw(fb, c.rock, textures.rock, viewProj, config, true)
Rasterizer.draw(fb, c.bark, textures.bark, viewProj, config, true)
Rasterizer.draw(fb, c.leaf, textures.leaf, viewProj, config, true)
Rasterizer.draw(fb, c.needle, textures.needle, viewProj, config, true)
}
Rasterizer.draw(fb, Sprite.billboard(npc, camera), npc.texture, viewProj, config)
Framebuffer.quantize(fb, config)
present()