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.

86 lines (83 loc) 3.19 kB
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