@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
JavaScript
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