UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

138 lines (135 loc) 5.41 kB
import { B as BU, F as F32, a9 as packMat4IntoF32, r as retireGpuResources, aH as bumpVisibilityEpoch, ai as U32 } from './index-By0tcgYN.esm.js'; function syncThinInstanceGpuData(engine, ti, hasColor) { const device = engine._device; const needsStorage = ti._gpuCullingEnabled; const retiredBuffers = []; let recreated = false; if (ti._version !== ti._gpuVersion || ti._gpuBufferStorage !== needsStorage) { const byteSize = ti.count * 64; let bufferRecreated = false; if (!ti._gpuBuffer || ti._gpuBuffer.size < byteSize || ti._gpuBufferStorage !== needsStorage) { if (ti._gpuBuffer) { retiredBuffers.push(ti._gpuBuffer); } ti._gpuBuffer = device.createBuffer({ label: "thin-instance-matrices", size: Math.max(ti._capacity * 64, 4), // STORAGE is always included: the GPU picker binds this matrix // buffer as a read-only storage buffer for thin-instance picking, // so it must be storage-capable even when compute culling is off // (otherwise the whole pick pass is invalidated → nothing is pickable). usage: BU.VERTEX | BU.COPY_DST | BU.STORAGE }); ti._gpuBufferStorage = needsStorage; bufferRecreated = true; recreated = true; } const dirtyMin = bufferRecreated ? 0 : ti._dirtyMin; const dirtyMax = bufferRecreated ? ti.count : Math.min(ti._dirtyMax, ti.count); if (dirtyMax > dirtyMin) { const minByte = dirtyMin * 64; const maxByte = dirtyMax * 64; if (ti.matrices instanceof F32) { device.queue.writeBuffer(ti._gpuBuffer, minByte, ti.matrices.buffer, ti.matrices.byteOffset + minByte, maxByte - minByte); } else { const neededFloats = ti._capacity * 16; if (!ti._uploadF32 || ti._uploadF32.length < neededFloats) { ti._uploadF32 = new F32(neededFloats); } const upload = ti._uploadF32; for (let i = dirtyMin; i < dirtyMax; i++) { packMat4IntoF32(upload, ti.matrices, i * 16, i * 16); } device.queue.writeBuffer(ti._gpuBuffer, minByte, upload.buffer, upload.byteOffset + minByte, maxByte - minByte); } } ti._dirtyMin = ti.count; ti._dirtyMax = 0; ti._gpuVersion = ti._version; } if (hasColor && ti.colors) { if (ti._colorVersion !== ti._colorGpuVersion || ti._colorGpuBufferStorage !== needsStorage) { const colorByteSize = ti.count * 16; let colorRecreated = false; if (!ti._colorGpuBuffer || ti._colorGpuBuffer.size < colorByteSize || ti._colorGpuBufferStorage !== needsStorage) { if (ti._colorGpuBuffer) { retiredBuffers.push(ti._colorGpuBuffer); } ti._colorGpuBuffer = device.createBuffer({ label: "thin-instance-colors", size: Math.max(ti._capacity * 16, 4), usage: BU.VERTEX | BU.COPY_DST | (needsStorage ? BU.STORAGE : 0) }); ti._colorGpuBufferStorage = needsStorage; colorRecreated = true; recreated = true; } const cMin = colorRecreated ? 0 : ti._colorDirtyMin; const cMax = colorRecreated ? ti.count : Math.min(ti._colorDirtyMax, ti.count); if (cMax > cMin) { device.queue.writeBuffer(ti._colorGpuBuffer, cMin * 16, ti.colors.buffer, ti.colors.byteOffset + cMin * 16, (cMax - cMin) * 16); } ti._colorDirtyMin = ti.count; ti._colorDirtyMax = 0; ti._colorGpuVersion = ti._colorVersion; } } if (retiredBuffers.length > 0) { retireGpuResources(engine, () => { for (const buffer of retiredBuffers) { buffer.destroy(); } }); } if (recreated) { bumpVisibilityEpoch(); } return recreated; } function syncThinInstanceDrawArgs(engine, ti, indexCount) { if (!ti._drawArgsBuffer) { ti._drawArgsBuffer = engine._device.createBuffer({ size: 20, usage: BU.INDIRECT | BU.COPY_DST }); ti._drawArgsData = new U32(5); ti._drawArgsIndexCount = -1; ti._drawArgsInstanceCount = -1; bumpVisibilityEpoch(); } if (ti._drawArgsIndexCount !== indexCount || ti._drawArgsInstanceCount !== ti.count) { const args = ti._drawArgsData; args[0] = indexCount; args[1] = ti.count; args[2] = 0; args[3] = 0; args[4] = 0; engine._device.queue.writeBuffer(ti._drawArgsBuffer, 0, args.buffer, args.byteOffset, args.byteLength); ti._drawArgsIndexCount = indexCount; ti._drawArgsInstanceCount = ti.count; } return ti._drawArgsBuffer; } function syncThinInstanceForDraw(engine, ti, hasColor, indexCount) { syncThinInstanceGpuData(engine, ti, hasColor); if (!ti._drawArgsBuffer && (ti._drawArgsInstanceCount ??= ti.count) === ti.count) { return null; } return syncThinInstanceDrawArgs(engine, ti, indexCount); } function syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, drawBuffers) { syncThinInstanceGpuData(engine, ti, hasColor); const matrixBuffer = drawBuffers?.matrixBuffer ?? ti._gpuBuffer; if (matrixBuffer) { pass.setVertexBuffer(slot++, matrixBuffer); } if (hasColor) { const colorBuffer = drawBuffers?.colorBuffer ?? ti._colorGpuBuffer; if (colorBuffer) { pass.setVertexBuffer(slot++, colorBuffer); } } return slot; } export { syncThinInstanceBuffers, syncThinInstanceDrawArgs, syncThinInstanceForDraw, syncThinInstanceGpuData }; //# sourceMappingURL=thin-instance-gpu-Cg2wPFiI.esm.js.map