@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.
86 lines (83 loc) • 3.19 kB
JavaScript
import { as as getBilinearSampler, S as SS } from './index-By0tcgYN.esm.js';
const BLIT_SHADER = `@group(0)@binding(0)var t:texture_2d<f32>;@group(0)@binding(1)var s:sampler;
struct V{@builtin(position)p:vec4f,@location(0)u:vec2f};
@vertex fn vs(@builtin(vertex_index)i:u32)->V{let p=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3))[i];return V(vec4f(p,0,1),p*vec2f(.5,-.5)+.5);}
@fragment fn fs(v:V)->@location(0)vec4f{return textureSample(t,s,v.u);}`;
let pipelineCache = null;
let shaderModule = null;
let linearSampler = null;
let bindGroupLayout = null;
let cachedDevice = null;
function clearCache() {
pipelineCache?.clear();
pipelineCache = null;
shaderModule = null;
linearSampler = null;
bindGroupLayout = null;
cachedDevice = null;
}
function ensureResources(engine) {
const device = engine._device;
if (device !== cachedDevice) {
clearCache();
cachedDevice = device;
}
shaderModule ??= device.createShaderModule({ code: BLIT_SHADER });
linearSampler ??= getBilinearSampler(engine);
bindGroupLayout ??= device.createBindGroupLayout({
entries: [
{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: "float" } },
{ binding: 1, visibility: SS.FRAGMENT, sampler: {} }
]
});
}
function getPipeline(engine, format) {
const device = engine._device;
ensureResources(engine);
pipelineCache ??= /* @__PURE__ */ new Map();
let pipeline = pipelineCache.get(format);
if (!pipeline) {
pipeline = device.createRenderPipeline({
layout: device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] }),
vertex: { module: shaderModule, entryPoint: "vs" },
fragment: { module: shaderModule, entryPoint: "fs", targets: [{ format }] },
primitive: { topology: "triangle-list" }
});
pipelineCache.set(format, pipeline);
}
return pipeline;
}
function generateMipmaps(engine, texture, face) {
const device = engine._device;
const encoder = device.createCommandEncoder();
recordMipmaps(engine, texture, encoder, face);
device.queue.submit([encoder.finish()]);
}
function recordMipmaps(engine, texture, encoder, face) {
if (texture.mipLevelCount <= 1) {
return;
}
const device = engine._device;
const pipeline = getPipeline(engine, texture.format);
const vp = face != null ? { dimension: "2d", baseArrayLayer: face, arrayLayerCount: 1 } : {};
for (let mip = 1; mip < texture.mipLevelCount; mip++) {
const srcView = texture.createView({ baseMipLevel: mip - 1, mipLevelCount: 1, ...vp });
const dstView = texture.createView({ baseMipLevel: mip, mipLevelCount: 1, ...vp });
const bindGroup = device.createBindGroup({
layout: bindGroupLayout,
entries: [
{ binding: 0, resource: srcView },
{ binding: 1, resource: linearSampler }
]
});
const pass = encoder.beginRenderPass({
colorAttachments: [{ view: dstView, loadOp: "clear", storeOp: "store", clearValue: { r: 0, g: 0, b: 0, a: 0 } }]
});
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.draw(3);
pass.end();
}
}
export { generateMipmaps, recordMipmaps };
//# sourceMappingURL=generate-mipmaps-BL7R_dXN.esm.js.map