@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.
124 lines (121 loc) • 4.23 kB
JavaScript
import { S as SS, aw as getPickingSceneBGL, h as createSingleUniformBGL } from './index-By0tcgYN.esm.js';
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 group2(engine, rule) {
if (!rule.storage?.length) {
return null;
}
return engine._device.createBindGroupLayout({
label: `picking-discard-${rule.key}-bgl`,
entries: rule.storage.map((_, binding) => ({
binding,
visibility: SS.FRAGMENT,
buffer: { type: "read-only-storage" }
}))
});
}
function shader(rule) {
const declarations = rule?.storage?.map((s, binding) => ` var<storage, read> ${s.name}: ${s.type};`).join("\n") ?? "";
const discard = rule?.wgsl ?? `fn shouldDiscardPick(input: PickDiscardInput) -> bool {
return false;
}`;
const shared = `enable primitive_index;
struct SceneUniforms { viewProjection: mat4x4f, fragmentCoord: vec2f }
var<uniform> scene: SceneUniforms;
struct PickDiscardInput {
worldPos: vec3f,
fragmentCoord: vec2f,
pickId: u32,
thinInstanceIndex: u32,
hasThinInstance: u32,
instanceExtras: vec4f,
}
${declarations}
${discard}
struct O {
p: vec4f,
id: u32,
w: vec3f,
ti: u32,
hasTi: u32,
extras: vec4f,
local: vec3f,
}
struct F { color: vec4f, depth: f32, detail: vec4u }
fn fs(i: O, primitiveIndex: u32) -> F {
if (shouldDiscardPick(PickDiscardInput(i.w, scene.fragmentCoord, i.id, i.ti, i.hasTi, i.extras))) { discard; }
let r = f32((i.id >> 16u) & 255u) / 255.0;
let g = f32((i.id >> 8u) & 255u) / 255.0;
let b = f32(i.id & 255u) / 255.0;
return F(vec4f(r, g, b, 1), i.p.z, vec4u(primitiveIndex, bitcast<u32>(i.local.x), bitcast<u32>(i.local.y), bitcast<u32>(i.local.z)));
}`;
return `${shared}
struct M { world: mat4x4f, pickId: u32 }
var<uniform> m: M;
fn vs( position: vec3f) -> O {
var o: O;
let w = (m.world * vec4f(position, 1)).xyz;
o.p = scene.viewProjection * vec4f(w, 1);
o.id = m.pickId;
o.w = w;
o.ti = 0xffffffffu;
o.hasTi = 0u;
o.extras = vec4f(0);
o.local = position;
return o;
}`;
}
const POSITION = {
arrayStride: 12,
attributes: [{ shaderLocation: 0, offset: 0, format: "float32x3" }]
};
function create(engine, rule, discardBGL, label) {
const device = engine._device;
const module = device.createShaderModule({ label: `${label}-shader`, code: shader(rule) });
const bgl1 = meshBGL(engine);
return device.createRenderPipeline({
label: `${label}-pipeline`,
layout: device.createPipelineLayout({
bindGroupLayouts: discardBGL ? [getPickingSceneBGL(engine), bgl1, discardBGL] : [getPickingSceneBGL(engine), bgl1]
}),
vertex: { module, entryPoint: "vs", buffers: [POSITION] },
fragment: { module, entryPoint: "fs", targets: [{ format: "rgba8unorm" }, { format: "r32float" }, { format: "rgba32uint" }] },
depthStencil: { format: "depth24plus", depthCompare: "greater", depthWriteEnabled: true },
primitive: { topology: "triangle-list", cullMode: "none" }
});
}
function getPickingPipelineSet(engine, rule) {
invalidate(engine);
const key = rule ? rule.key : "default";
const sets = _sets ??= /* @__PURE__ */ new Map();
const cached = sets.get(key);
if (cached) {
return cached;
}
const active = rule ?? null;
const discardBGL = active ? group2(engine, active) : null;
const regularPipeline = create(engine, active, discardBGL, active ? `picking-${active.key}-detailed` : "picking-detailed");
const set = {
regularPipeline,
thinInstancePipeline: regularPipeline,
discardBGL,
detailed: true
};
sets.set(key, set);
return set;
}
export { getPickingPipelineSet };
//# sourceMappingURL=picking-detailed-pipeline-ClVDPWRr.esm.js.map