feat: fancy clouds, fps meter

This commit is contained in:
Dan Finch 2026-08-04 03:00:58 +02:00
parent b0878ad5e1
commit 2c31bd82bf
5 changed files with 120 additions and 26 deletions

View file

@ -1,5 +1,5 @@
import { Color } from "../engine/render/Color"
import type { SkyConfig } from "../engine/render/Sky"
import type { CloudLayer, SkyConfig } from "../engine/render/Sky"
import type { Mesh } from "../engine/scene/Mesh"
type Corner = [number, number, number]
@ -40,6 +40,29 @@ const CRATE = { x: -2, z: -2, half: 1, top: 1 }
* from the render side. */
const DIVISIONS_PER_UNIT = 1.3
/** The two cloud styles; swap which one the sky uses in `buildLevel`.
* `basicCumulus` is cheap flat puffs; `fancyCumulus` is the pricier
* heightfield-shaded, domain-warped version with faked volume. */
export const basicCumulus: CloudLayer = {
kind: "basic",
color: Color.rgb(248, 250, 255),
coverage: 0.5,
scale: 0.9,
speed: 0.5,
edge: 0.02,
}
export const fancyCumulus: CloudLayer = {
kind: "fancy",
color: Color.rgb(250, 251, 255),
coverage: 0.5,
scale: 0.6,
speed: 0.5,
edge: 0.02,
warp: 0.4,
relief: 7,
}
export function buildLevel(): Level {
const floor = mesh()
quadGrid(floor, [-ARENA, 0, -ARENA], [ARENA, 0, -ARENA], [ARENA, 0, ARENA], [-ARENA, 0, ARENA], 12, 12)
@ -76,13 +99,7 @@ export function buildLevel(): Level {
sun: Color.rgb(255, 246, 214),
sunDir: { x: 0.3, y: 0.5, z: -0.8 },
sunSize: 0.04,
clouds: {
color: Color.rgb(248, 250, 255),
coverage: 0.5,
scale: 0.9,
speed: 0.5,
edge: 0.02,
},
clouds: fancyCumulus,
}
return { floor, walls, crate, colliders, npcPosition: { x: 2, y: 0, z: -1 }, sky }

View file

@ -14,6 +14,7 @@ const screen = document.querySelector<HTMLCanvasElement>("#screen")!
const ctx = screen.getContext("2d")!
const back = document.createElement("canvas")
const backCtx = back.getContext("2d")!
const fpsEl = document.querySelector<HTMLDivElement>("#fps")!
let config: RenderConfig = RenderConfig.standard
let fb = Framebuffer.create(1, 1)
@ -82,9 +83,17 @@ async function main(): Promise<void> {
resize()
let last = performance.now()
let fpsLast = last
let fpsFrames = 0
function frame(now: number): void {
const dt = Math.min(0.05, (now - last) / 1000)
last = now
fpsFrames++
if (now - fpsLast >= 250) {
fpsEl.textContent = `${Math.round((fpsFrames * 1000) / (now - fpsLast))} fps`
fpsLast = now
fpsFrames = 0
}
Player.update(player, keys, dt, level)
const camera: Camera = {