From bb4cab327afe943ea3eee46487a97a80f587420e Mon Sep 17 00:00:00 2001 From: Paula Date: Sun, 15 Mar 2026 14:07:55 -0300 Subject: [PATCH] Improve chunk mesh worker --- build.ts | 2 +- client/systems/rendering/dimension.ts | 175 +----------------- .../chunk_mesh_worker.ts | 10 +- 3 files changed, 16 insertions(+), 171 deletions(-) rename client/{systems/rendering => workers}/chunk_mesh_worker.ts (94%) diff --git a/build.ts b/build.ts index 2186b5a..a559a5c 100644 --- a/build.ts +++ b/build.ts @@ -118,7 +118,7 @@ async function build_assets() { async function build_client() { const _result = await Deno.bundle({ - entrypoints: ["./client/main.ts", "./client/systems/rendering/chunk_mesh_worker.ts"], + entrypoints: ["./client/main.ts", "./client/workers/chunk_mesh_worker.ts"], outputDir: `${BUILD_FOLDER}/client`, platform: "browser", minify: false, diff --git a/client/systems/rendering/dimension.ts b/client/systems/rendering/dimension.ts index 9fb1ed9..2d288ad 100644 --- a/client/systems/rendering/dimension.ts +++ b/client/systems/rendering/dimension.ts @@ -1,24 +1,12 @@ -import { get_sprite_region } from "$/common/utils.ts"; -import { Chunk, CHUNK_AREA, CHUNK_SIZE, Dimension } from "$/client/components/dimension.ts"; -import { TEXTURE_SIZE } from "$/common/constants.ts"; -import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; -import { - flush_buffer, - gl, - push_back_face, - push_bottom_face, - push_front_face, - push_left_face, - push_right_face, - push_top_face, - set_current_texture, -} from "$/client/renderer/mod.ts"; +import { EverythingRegistry } from "$/common/everything_registry.ts"; +import { Chunk, Dimension } from "$/client/components/dimension.ts"; import { Camera } from "$/client/components/camera.ts"; -import { AssetManager } from "../../assets.ts"; +import { AssetManager } from "$/client/assets.ts"; +import { flush_buffer, gl, set_current_texture } from "$/client/renderer/mod.ts"; let gdimension: Dimension; -const worker = new Worker(new URL("./systems/rendering/chunk_mesh_worker.js", import.meta.url), { +const worker = new Worker(new URL("./workers/chunk_mesh_worker.js", import.meta.url), { type: "module", }); @@ -40,7 +28,6 @@ worker.onmessage = (event) => { vertices.subarray(0, count), gl.STATIC_DRAW, ); - //make_chunk_mesh(chunk, dimension, camera); }; function strip_functions>(obj: T) { @@ -67,21 +54,17 @@ export function render_dimension(dimension: Dimension, camera: Camera) { set_current_texture(dimension.image.tex); for (const chunk of dimension.chunks) { - if (chunk.dirty) { + if (chunk.dirty && chunk.generated) { + const padded_chunk = dimension.create_padded_chunk(chunk); worker.postMessage({ chunk_x: chunk.x, chunk_z: chunk.z, - padded_chunk: dimension.create_padded_chunk(chunk), + padded_chunk, blocks_registry: strip_functions(EverythingRegistry.get_registry("blocks")), textures_info: AssetManager.instance.get("bworld:textures_info"), image: { width: dimension.image.width, height: dimension.image.height }, - }); + }, [padded_chunk.buffer]); chunk.dirty = false; - // dimension.delete_chunk_mesh(chunk); - - // make_chunk_mesh(chunk, dimension, camera); - // only generate one mesh per frame - // break; } } for (const chunk of dimension.chunks) { @@ -96,143 +79,3 @@ function render_chunk_opaque(chunk: Chunk) { flush_buffer(chunk.vertex_buffer, chunk.vertex_count); } - -const FACE_PUSHING_FUNCTIONS = { - top: push_top_face, - bottom: push_bottom_face, - front: push_front_face, - back: push_back_face, - left: push_left_face, - right: push_right_face, -} as const; - -function make_chunk_mesh(chunk: Chunk, dimension: Dimension, camera: Camera) { - let vertices = new Float32Array(CHUNK_AREA * 24 * 6 * 9); - let count = 0; - const blocks_registry = EverythingRegistry.get_registry("blocks"); - - const show_face = (x: number, y: number, z: number) => { - const block = dimension.get_block(x, y, z); - if (block === -1) { - return false; - } - if (block === 0) { - return true; - } - const block_info = blocks_registry[block]; - if (block_info?.transparent) { - return true; - } - return false; - }; - - for (let i = 0; i < chunk.blocks.length; i += 1) { - const block_nid = chunk.blocks[i]; - if (block_nid === 0) { - continue; - } - - const block_info = blocks_registry[block_nid]; - - const texture_ids = { - top: "bworld:missing", - bottom: "bworld:missing", - front: "bworld:missing", - back: "bworld:missing", - left: "bworld:missing", - right: "bworld:missing", - }; - - const textures = block_info.textures; - if (!textures) { - throw new Error(`no textures for ${block_nid}`); - } - - if (typeof textures === "string") { - texture_ids.top = textures; - texture_ids.bottom = textures; - texture_ids.front = textures; - texture_ids.back = textures; - texture_ids.left = textures; - texture_ids.right = textures; - } else if ("top" in textures && "bottom" in textures && "side" in textures) { - texture_ids.top = textures.top; - texture_ids.bottom = textures.bottom; - texture_ids.front = textures.side; - texture_ids.back = textures.side; - texture_ids.left = textures.side; - texture_ids.right = textures.side; - } else if ("front" in textures && "side" in textures) { - texture_ids.top = textures.side; - texture_ids.bottom = textures.side; - texture_ids.front = textures.front; - texture_ids.back = textures.side; - texture_ids.left = textures.side; - texture_ids.right = textures.side; - } - - const [x, y, z] = dimension.index_to_xyz(i); - - const wx = chunk.x * CHUNK_SIZE + x; - const wz = chunk.z * CHUNK_SIZE + z; - - const faces = { - front: show_face(wx, y, wz + 1), - back: show_face(wx, y, wz - 1), - left: show_face(wx - 1, y, wz), - right: show_face(wx + 1, y, wz), - top: show_face(wx, y + 1, wz), - bottom: show_face(wx, y - 1, wz), - } as const; - - for (const side of ["front", "back", "left", "right", "top", "bottom"] as const) { - if (faces[side]) { - const region = get_sprite_region(texture_ids[side]); - - vertices = ensure_capacity(vertices, count + (6 * 6 * 9)); - count = FACE_PUSHING_FUNCTIONS[side]( - vertices, - count, - dimension.image, - wx, - y, - wz, - region.x * TEXTURE_SIZE, - region.y * TEXTURE_SIZE, - TEXTURE_SIZE, - TEXTURE_SIZE, - 1, - 1, - 1, - 1, - ); - } - } - } - - chunk.vertex_buffer = gl.createBuffer(); - chunk.vertex_count = count / 9; - - gl.bindBuffer(gl.ARRAY_BUFFER, chunk.vertex_buffer); - gl.bufferData( - gl.ARRAY_BUFFER, - vertices.subarray(0, count), - gl.STATIC_DRAW, - ); -} - -function ensure_capacity( - buffer: Float32Array, - required: number, -) { - if (required <= buffer.length) return buffer; - - let new_length = buffer.length; - while (new_length < required) { - new_length *= 2; - } - - const new_buffer = new Float32Array(new_length); - new_buffer.set(buffer); - return new_buffer; -} diff --git a/client/systems/rendering/chunk_mesh_worker.ts b/client/workers/chunk_mesh_worker.ts similarity index 94% rename from client/systems/rendering/chunk_mesh_worker.ts rename to client/workers/chunk_mesh_worker.ts index 48cb873..412073e 100644 --- a/client/systems/rendering/chunk_mesh_worker.ts +++ b/client/workers/chunk_mesh_worker.ts @@ -1,3 +1,5 @@ +/// + import type { BlockRegistry } from "$/common/everything_registry.ts"; import type { SpriteRegion } from "$/common/constants.ts"; import { @@ -7,8 +9,8 @@ import { push_left_face, push_right_face, push_top_face, -} from "../../renderer/models.ts"; -import type { Texture } from "../../renderer/types.ts"; +} from "../renderer/models.ts"; +import type { Texture } from "../renderer/types.ts"; type TexturesInfo = Record; @@ -28,7 +30,7 @@ const FACE_PUSHING_FUNCTIONS = { self.onmessage = (event) => { const { chunk_x, chunk_z, padded_chunk, blocks_registry, textures_info, image } = event.data; const [vertices, count] = make_chunk_mesh(chunk_x, chunk_z, padded_chunk, blocks_registry, textures_info, image); - self.postMessage({ vertices, count, chunk_x, chunk_z }); + self.postMessage({ vertices, count, chunk_x, chunk_z }, [vertices.buffer]); }; function make_chunk_mesh( @@ -38,7 +40,7 @@ function make_chunk_mesh( blocks_registry: BlockRegistry[], textures_info: TexturesInfo, image: Texture, -) { +): [Float32Array, number] { let vertices = new Float32Array(2048); let count = 0;