diff --git a/frontend/src/ts/minecraft/MinecraftSection.ts b/frontend/src/ts/minecraft/MinecraftSection.ts index b412c8c..a2aeef0 100644 --- a/frontend/src/ts/minecraft/MinecraftSection.ts +++ b/frontend/src/ts/minecraft/MinecraftSection.ts @@ -176,14 +176,15 @@ export class MinecraftSection { }); } - public render(renderPassEncoder: GPURenderPassEncoder) { + public render(renderPassEncoder: GPURenderPassEncoder | GPURenderBundleEncoder) { if (this._faceNumber === 0) - return; + return 0; renderPassEncoder.setVertexBuffer(0, this._geomBuffer); renderPassEncoder.setVertexBuffer(1, this._texBuffer); renderPassEncoder.setVertexBuffer(2, this._texIndexBuffer); renderPassEncoder.setBindGroup(1, this._bindGroup1); renderPassEncoder.draw(4, this._faceNumber); + return this._faceNumber; } public get minecraftWorld(): MinecraftWorld { diff --git a/frontend/src/ts/minecraft/MinecraftWorld.ts b/frontend/src/ts/minecraft/MinecraftWorld.ts index 28221b9..dfcb501 100644 --- a/frontend/src/ts/minecraft/MinecraftWorld.ts +++ b/frontend/src/ts/minecraft/MinecraftWorld.ts @@ -1,12 +1,15 @@ import { ResourcePack as ResourcePack } from "./ResourcePack"; import { MinecraftSection } from "./MinecraftSection"; import { BlockNeighborhood } from "./MinecraftBlock"; +import { gpuDevice } from "../GPUX"; +import { MinecraftOpaquePipeline } from "./MinecraftOpaquePipeline"; export type PaletteEntry = { Name: string, Properties?: { [key: string]: string } }; export class MinecraftWorld { name: string; ressourcePack: ResourcePack; + bundle!: GPURenderBundle; private _sections: { [key: string]: MinecraftSection }; @@ -22,10 +25,32 @@ export class MinecraftWorld { } } - render(renderPassEncoder: GPURenderPassEncoder) { + buildBundle(bindGroup0: GPUBindGroup) { + const e = gpuDevice.createRenderBundleEncoder({ + label: "Minecraft render bundle encoder", + colorFormats: ["bgra8unorm", "r16uint"], + depthStencilFormat: "depth24plus", + sampleCount: 4 + }); + e.setBindGroup(0, bindGroup0); + e.setPipeline(MinecraftOpaquePipeline.pipeline.gpuPipeline); + e.setBindGroup(2, MinecraftOpaquePipeline.bindGroup2) + this.render(e); + this.bundle = e.finish({ label: "Minecraft World bundle" }); + } + + render(renderPassEncoder: GPURenderPassEncoder | GPURenderBundleEncoder) { + let quads = 0; + let chunks = 0; for (const key in this._sections) { - this._sections[key].render(renderPassEncoder); + chunks++; + quads += this._sections[key].render(renderPassEncoder); } + console.log(quads, chunks); + } + + renderBundle(renderPassEncoder: GPURenderPassEncoder) { + renderPassEncoder.executeBundles([this.bundle]); } getSection(x: number, y: number, z: number): MinecraftSection | undefined { diff --git a/frontend/src/ts/rendering/Renderer.ts b/frontend/src/ts/rendering/Renderer.ts index 37832e5..158d47a 100644 --- a/frontend/src/ts/rendering/Renderer.ts +++ b/frontend/src/ts/rendering/Renderer.ts @@ -27,7 +27,7 @@ export default class Renderer { private registeredViewports = new Set(); private viewportCache = new Map(); private viewUBO: GPUBuffer; - private bindGroup0: GPUBindGroup; + bindGroup0: GPUBindGroup; bindGroup0Layout: GPUBindGroupLayout; bindGroupR3Layout: GPUBindGroupLayout; @@ -361,9 +361,7 @@ export default class Renderer { hf.render(r3renderPassEncoder); } - r3renderPassEncoder.setPipeline(MinecraftOpaquePipeline.pipeline.gpuPipeline); - r3renderPassEncoder.setBindGroup(2, MinecraftOpaquePipeline.bindGroup2) - this.project.scene.minecraftWorld?.render(r3renderPassEncoder); + this.project.scene.minecraftWorld?.renderBundle(r3renderPassEncoder); r3renderPassEncoder.end(); if (viewport.useOverlays) { diff --git a/frontend/src/ts/ui/Wrapping/WrappingPane.ts b/frontend/src/ts/ui/Wrapping/WrappingPane.ts index 02649ae..0eb66fe 100644 --- a/frontend/src/ts/ui/Wrapping/WrappingPane.ts +++ b/frontend/src/ts/ui/Wrapping/WrappingPane.ts @@ -70,8 +70,8 @@ export class WrappingPane extends HTMLElement { wasmInstance.openRegion("World", 0, 0, 0, content); const mWorld = new MinecraftWorld("World", res); project.scene.minecraftWorld = mWorld; - for (let x = 0; x < 16; x++) { - for (let z = 0; z < 16; z++) { + for (let x = 0; x < 8; x++) { + for (let z = 0; z < 8; z++) { const status = wasmInstance.buildChunk("World", 0, x, z); if (status !== 0) @@ -84,13 +84,15 @@ export class WrappingPane extends HTMLElement { let sectionDataView: any = undefined; if (palette.length > 1) sectionDataView = wasmInstance.getSectionView("World", 0, x, y, z); + else if (palette.length === 1 && palette[0].Name == "minecraft:air") + continue section = new MinecraftSection(mWorld, 0, x, y, z, palette, sectionDataView); project.scene.minecraftWorld.setSection(x, y, z, section); } } } mWorld.buildGeometry(); - console.log(res); + mWorld.buildBundle(project.renderer.bindGroup0); } catch (e) { console.error(e);