@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.
161 lines (157 loc) • 4.65 kB
JavaScript
import { S as SS, aw as getPickingSceneBGL, h as createSingleUniformBGL } from './index-By0tcgYN.esm.js';
const PICK_INPUT = (
/* wgsl */
`
struct PickDiscardInput {
worldPos: vec3f,
fragmentCoord: vec2f,
pickId: u32,
thinInstanceIndex: u32,
hasThinInstance: u32,
instanceExtras: vec4f,
};
`
);
const DEFAULT_DISCARD = (
/* wgsl */
`
fn shouldDiscardPick(input: PickDiscardInput) -> bool {
return false;
}
`
);
function storageDecls(opts) {
const storage = opts?.storage;
return storage?.length ? storage.map((s, binding) => ` var<storage, read> ${s.name}: ${s.type};`).join("\n") : "";
}
const SCENE = (
/* wgsl */
`
struct SceneUniforms {
viewProjection: mat4x4f,
fragmentCoord: vec2f,
};
var<uniform> scene: SceneUniforms;
`
);
const FRAGMENT = (
/* wgsl */
`
struct VsOut {
p: vec4f,
pickId: u32,
worldPos: vec3f,
thinInstanceIndex: u32,
hasThinInstance: u32,
instanceExtras: vec4f,
};
struct FsOut { color: vec4f, depth: f32 };
fn fs(input: VsOut) -> FsOut {
if (shouldDiscardPick(PickDiscardInput(input.worldPos, scene.fragmentCoord, input.pickId, input.thinInstanceIndex, input.hasThinInstance, input.instanceExtras))) { discard; }
let id = input.pickId;
let r = f32((id >> 16u) & 0xFFu) / 255.0;
let g = f32((id >> 8u) & 0xFFu) / 255.0;
let b = f32(id & 0xFFu) / 255.0;
return FsOut(vec4f(r, g, b, 1.0), input.p.z);
}
`
);
function pickingShaderSource(opts) {
return (
/* wgsl */
`
${SCENE}
struct MeshUniforms {
world: mat4x4f,
pickId: u32,
};
var<uniform> mesh: MeshUniforms;
${PICK_INPUT}
${storageDecls(opts)}
${opts?.discardWgsl ?? DEFAULT_DISCARD}
${FRAGMENT}
fn vs( position: vec3f) -> VsOut {
var out: VsOut;
let wp = (mesh.world * vec4f(position, 1.0)).xyz;
out.p = scene.viewProjection * vec4f(wp, 1.0);
out.pickId = mesh.pickId;
out.worldPos = wp;
out.thinInstanceIndex = 0xffffffffu;
out.hasThinInstance = 0u;
out.instanceExtras = vec4f(0.0);
return out;
}
`
);
}
let _device = null;
let _meshBGL = null;
let _sets = null;
function invalidate(engine) {
if (_device === engine._device) {
return;
}
_device = engine._device;
_meshBGL = null;
_sets = null;
}
function meshBGL(engine) {
invalidate(engine);
return _meshBGL ??= createSingleUniformBGL(engine, "picking-mesh-bgl", SS.VERTEX | SS.FRAGMENT);
}
function discardBGL(engine, discard) {
return engine._device.createBindGroupLayout({
label: `picking-discard-${discard.key}-bgl`,
entries: (discard.storage ?? []).map((_, binding) => ({
binding,
visibility: SS.FRAGMENT,
buffer: { type: "read-only-storage" }
}))
});
}
const POSITION = {
arrayStride: 12,
attributes: [{ shaderLocation: 0, offset: 0, format: "float32x3" }]
};
function pipeline(engine, discard, group2, label) {
const device = engine._device;
const module = device.createShaderModule({
label: `${label}-shader`,
code: pickingShaderSource(discard ? { discardWgsl: discard.wgsl, storage: discard.storage } : void 0)
});
const group1 = meshBGL(engine);
const layout = device.createPipelineLayout({
label: `${label}-pipeline-layout`,
bindGroupLayouts: group2 ? [getPickingSceneBGL(engine), group1, group2] : [getPickingSceneBGL(engine), group1]
});
return device.createRenderPipeline({
label: `${label}-pipeline`,
layout,
vertex: { module, entryPoint: "vs", buffers: [POSITION] },
fragment: { module, entryPoint: "fs", targets: [{ format: "rgba8unorm" }, { format: "r32float" }] },
depthStencil: { format: "depth24plus", depthCompare: "greater", depthWriteEnabled: true },
primitive: { topology: "triangle-list", cullMode: "none" },
multisample: { count: 1 }
});
}
function getPickingPipelineSet(engine, discard) {
invalidate(engine);
const key = discard ? `discard:${discard.key}` : "default";
const sets = _sets ??= /* @__PURE__ */ new Map();
const cached = sets.get(key);
if (cached) {
return cached;
}
const active = discard ?? null;
const group2 = active?.storage?.length ? discardBGL(engine, active) : null;
const regularPipeline = pipeline(engine, active, group2, active ? `picking-${active.key}` : "picking");
const set = {
regularPipeline,
thinInstancePipeline: regularPipeline,
discardBGL: group2
};
sets.set(key, set);
return set;
}
export { getPickingPipelineSet };
//# sourceMappingURL=picking-pipeline-CuZudL2f.esm.js.map