Optimize renderer
This commit is contained in:
+36
-13
@@ -1,7 +1,7 @@
|
||||
import type { Camera } from "../camera.ts";
|
||||
import { mat4 } from "gl-matrix";
|
||||
import type { RenderLayer } from "$/common/everything_registry.ts";
|
||||
import { TERRAIN_VERTEX_FLOATS } from "../workers/chunk_messages.ts";
|
||||
import { TERRAIN_VERTEX_BYTES } from "../workers/chunk_messages.ts";
|
||||
|
||||
export let device: GPUDevice;
|
||||
export let canvas: HTMLCanvasElement;
|
||||
@@ -375,10 +375,16 @@ export function flush_batch() {
|
||||
vert_index = 0;
|
||||
}
|
||||
|
||||
// draws a chunk mesh made of quads (4 vertices each). without an index buffer the quads are drawn in order
|
||||
// what's bound for terrain draws in the current pass, so drawing hundreds of chunks doesn't bind the same things
|
||||
// again for each one. cleared whenever the pipeline changes
|
||||
let terrain_binds: { slot: number; texture: GPUTexture; index_buffer: GPUBuffer } | undefined;
|
||||
|
||||
// draws quads first to first + quad_count of a chunk mesh (4 vertices each). without an index buffer the quads are
|
||||
// drawn in order
|
||||
export function draw_terrain(
|
||||
layer: RenderLayer,
|
||||
vertex_buffer: GPUBuffer,
|
||||
first: number,
|
||||
quad_count: number,
|
||||
index_buffer?: GPUBuffer,
|
||||
) {
|
||||
@@ -386,7 +392,7 @@ export function draw_terrain(
|
||||
return;
|
||||
}
|
||||
if (!index_buffer) {
|
||||
ensure_quad_indices(quad_count);
|
||||
ensure_quad_indices(first + quad_count);
|
||||
index_buffer = quad_index_buffer!;
|
||||
}
|
||||
|
||||
@@ -395,17 +401,33 @@ export function draw_terrain(
|
||||
if (current_pipeline !== pipeline) {
|
||||
render_pass.setPipeline(pipeline);
|
||||
current_pipeline = pipeline;
|
||||
terrain_binds = undefined;
|
||||
}
|
||||
|
||||
render_pass.setBindGroup(0, uniform_bind_group, [uniform_slot * UNIFORM_SLOT_SIZE]);
|
||||
render_pass.setBindGroup(1, get_texture_bind_group(current_texture));
|
||||
render_pass.setBindGroup(2, lightmap_bind_group);
|
||||
if (!terrain_binds) {
|
||||
render_pass.setBindGroup(2, lightmap_bind_group);
|
||||
}
|
||||
if (terrain_binds?.slot !== uniform_slot) {
|
||||
render_pass.setBindGroup(0, uniform_bind_group, [uniform_slot * UNIFORM_SLOT_SIZE]);
|
||||
}
|
||||
if (terrain_binds?.texture !== current_texture) {
|
||||
render_pass.setBindGroup(1, get_texture_bind_group(current_texture));
|
||||
}
|
||||
if (terrain_binds?.index_buffer !== index_buffer) {
|
||||
render_pass.setIndexBuffer(index_buffer, "uint32");
|
||||
}
|
||||
terrain_binds = { slot: uniform_slot, texture: current_texture, index_buffer };
|
||||
|
||||
render_pass.setVertexBuffer(0, vertex_buffer);
|
||||
render_pass.setIndexBuffer(index_buffer, "uint32");
|
||||
render_pass.drawIndexed(quad_count * 6);
|
||||
render_pass.drawIndexed(quad_count * 6, 1, first * 6);
|
||||
}
|
||||
|
||||
export function create_vertex_buffer(vertices: Float32Array): GPUBuffer {
|
||||
// the camera's view and projection, for frustum culling. only meaningful in 3d mode
|
||||
export function view_projection(): Readonly<Float32Array> {
|
||||
return mvp as Float32Array;
|
||||
}
|
||||
|
||||
export function create_vertex_buffer(vertices: Float32Array<ArrayBuffer> | Uint8Array<ArrayBuffer>): GPUBuffer {
|
||||
const buffer = device.createBuffer({
|
||||
size: Math.max(4, vertices.byteLength),
|
||||
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
||||
@@ -598,6 +620,7 @@ function ensure_pass(): GPURenderPassEncoder {
|
||||
pending_color_clear = false;
|
||||
pending_depth_clear = false;
|
||||
current_pipeline = undefined;
|
||||
terrain_binds = undefined;
|
||||
apply_scissor(pass);
|
||||
|
||||
return pass;
|
||||
@@ -762,12 +785,12 @@ function create_pipelines() {
|
||||
module: terrain_module,
|
||||
entryPoint: "vs_terrain",
|
||||
buffers: [{
|
||||
arrayStride: TERRAIN_VERTEX_FLOATS * 4,
|
||||
arrayStride: TERRAIN_VERTEX_BYTES,
|
||||
attributes: [
|
||||
{ shaderLocation: 0, offset: 0, format: "float32x3" },
|
||||
{ shaderLocation: 1, offset: 12, format: "float32x2" },
|
||||
{ shaderLocation: 2, offset: 20, format: "float32x4" },
|
||||
{ shaderLocation: 3, offset: 36, format: "float32x2" },
|
||||
{ shaderLocation: 1, offset: 12, format: "unorm16x2" },
|
||||
{ shaderLocation: 2, offset: 16, format: "unorm8x4" },
|
||||
{ shaderLocation: 3, offset: 20, format: "unorm8x2" },
|
||||
],
|
||||
}],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user