@babylonjs/lite 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +512 -512
- package/dist/index.js.map +1 -1
- package/index.d.ts +829 -28
- package/lib/audio/analyzer.js +65 -0
- package/lib/audio/analyzer.js.map +1 -0
- package/lib/audio/audio-bus.js +38 -0
- package/lib/audio/audio-bus.js.map +1 -0
- package/lib/audio/audio-engine.js +188 -0
- package/lib/audio/audio-engine.js.map +1 -0
- package/lib/audio/audio-fetch.js +18 -0
- package/lib/audio/audio-fetch.js.map +1 -0
- package/lib/audio/audio-param.js +96 -0
- package/lib/audio/audio-param.js.map +1 -0
- package/lib/audio/audio-signal.js +46 -0
- package/lib/audio/audio-signal.js.map +1 -0
- package/lib/audio/bus.js +33 -0
- package/lib/audio/bus.js.map +1 -0
- package/lib/audio/host-types.js +2 -0
- package/lib/audio/host-types.js.map +1 -0
- package/lib/audio/index.js +12 -0
- package/lib/audio/index.js.map +1 -0
- package/lib/audio/sound-buffer.js +59 -0
- package/lib/audio/sound-buffer.js.map +1 -0
- package/lib/audio/sound-source.js +57 -0
- package/lib/audio/sound-source.js.map +1 -0
- package/lib/audio/sound-sub-graph.js +72 -0
- package/lib/audio/sound-sub-graph.js.map +1 -0
- package/lib/audio/spatial.js +466 -0
- package/lib/audio/spatial.js.map +1 -0
- package/lib/audio/static-sound.js +313 -0
- package/lib/audio/static-sound.js.map +1 -0
- package/lib/audio/stereo.js +40 -0
- package/lib/audio/stereo.js.map +1 -0
- package/lib/audio/streaming-sound.js +377 -0
- package/lib/audio/streaming-sound.js.map +1 -0
- package/lib/audio/unmute-ui.js +72 -0
- package/lib/audio/unmute-ui.js.map +1 -0
- package/lib/audio/visualizer.js +101 -0
- package/lib/audio/visualizer.js.map +1 -0
- package/lib/camera/geospatial-camera-controls.js +22 -0
- package/lib/camera/geospatial-camera-controls.js.map +1 -1
- package/lib/camera/geospatial-camera-fly.js +2 -1
- package/lib/camera/geospatial-camera-fly.js.map +1 -1
- package/lib/effect/effect-renderer.js +1 -1
- package/lib/effect/effect-renderer.js.map +1 -1
- package/lib/engine/engine.js +1 -1
- package/lib/index.js +15 -1
- package/lib/index.js.map +1 -1
- package/lib/light/types.js.map +1 -1
- package/lib/loader-gltf/animation-pointer-basecolor.js +25 -0
- package/lib/loader-gltf/animation-pointer-basecolor.js.map +1 -0
- package/lib/loader-gltf/animation-pointer-ext.js +244 -0
- package/lib/loader-gltf/animation-pointer-ext.js.map +1 -0
- package/lib/loader-gltf/animation-pointer-lights.js +46 -0
- package/lib/loader-gltf/animation-pointer-lights.js.map +1 -0
- package/lib/loader-gltf/animation-pointer.js +4 -1
- package/lib/loader-gltf/animation-pointer.js.map +1 -1
- package/lib/loader-gltf/gltf-animation.js +5 -3
- package/lib/loader-gltf/gltf-animation.js.map +1 -1
- package/lib/loader-gltf/gltf-color-normalize.js +10 -1
- package/lib/loader-gltf/gltf-color-normalize.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-animation-pointer.js +67 -47
- package/lib/loader-gltf/gltf-feature-animation-pointer.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-lights-punctual.js +51 -9
- package/lib/loader-gltf/gltf-feature-lights-punctual.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-primitive.js +20 -0
- package/lib/loader-gltf/gltf-feature-primitive.js.map +1 -0
- package/lib/loader-gltf/gltf-feature-registry.js +25 -0
- package/lib/loader-gltf/gltf-feature-registry.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-skeleton.js +18 -3
- package/lib/loader-gltf/gltf-feature-skeleton.js.map +1 -1
- package/lib/loader-gltf/gltf-interleave.js +3 -2
- package/lib/loader-gltf/gltf-interleave.js.map +1 -1
- package/lib/loader-gltf/gltf-light-pointer-state.js +18 -0
- package/lib/loader-gltf/gltf-light-pointer-state.js.map +1 -0
- package/lib/loader-gltf/gltf-parser.js +7 -1
- package/lib/loader-gltf/gltf-parser.js.map +1 -1
- package/lib/loader-gltf/gltf-pbr-builder-ext.js +1 -1
- package/lib/loader-gltf/gltf-pbr-builder-ext.js.map +1 -1
- package/lib/loader-gltf/gltf-pbr-builder.js +1 -1
- package/lib/loader-gltf/gltf-pbr-builder.js.map +1 -1
- package/lib/loader-gltf/gltf-sampler-denorm.js +20 -0
- package/lib/loader-gltf/gltf-sampler-denorm.js.map +1 -0
- package/lib/loader-gltf/gltf-sampler-desc.js +11 -2
- package/lib/loader-gltf/gltf-sampler-desc.js.map +1 -1
- package/lib/loader-gltf/gltf-uv-denorm.js +28 -0
- package/lib/loader-gltf/gltf-uv-denorm.js.map +1 -0
- package/lib/loader-gltf/load-gltf.js +15 -6
- package/lib/loader-gltf/load-gltf.js.map +1 -1
- package/lib/material/material-rebuild.js +4 -0
- package/lib/material/material-rebuild.js.map +1 -1
- package/lib/material/mesh-features.js +8 -1
- package/lib/material/mesh-features.js.map +1 -1
- package/lib/material/pbr/fragments/reflectance-fragment.js +1 -1
- package/lib/material/pbr/fragments/reflectance-fragment.js.map +1 -1
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js +1 -1
- package/lib/material/pbr/fragments/refraction-rtt-fragment.js.map +1 -1
- package/lib/material/pbr/pbr-pipeline.js +7 -3
- package/lib/material/pbr/pbr-pipeline.js.map +1 -1
- package/lib/material/pbr/pbr-primitive-resolver.js +34 -0
- package/lib/material/pbr/pbr-primitive-resolver.js.map +1 -0
- package/lib/material/pbr/pbr-renderable.js +1 -1
- package/lib/material/pbr/pbr-renderable.js.map +1 -1
- package/lib/material/shader/shader-material.js +9 -5
- package/lib/material/shader/shader-material.js.map +1 -1
- package/lib/material/shader/shader-thin-instance.js +1 -1
- package/lib/material/shader/shader-thin-instance.js.map +1 -1
- package/lib/material/standard/standard-renderable.js +1 -1
- package/lib/material/standard/standard-renderable.js.map +1 -1
- package/lib/mesh/mesh-dispose.js +1 -0
- package/lib/mesh/mesh-dispose.js.map +1 -1
- package/lib/mesh/thin-instance-cull-binding.js +15 -6
- package/lib/mesh/thin-instance-cull-binding.js.map +1 -1
- package/lib/post-process/taa.js +193 -0
- package/lib/post-process/taa.js.map +1 -0
- package/lib/scene/scene-core.js +1 -0
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/scene/scene-material-swap.js +2 -0
- package/lib/scene/scene-material-swap.js.map +1 -1
- package/lib/shadow/csm-shadow-task-hooks.js +67 -9
- package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
- package/lib/sprite/billboard-custom-shader.js +32 -32
- package/lib/sprite/billboard-custom-shader.js.map +1 -1
- package/lib/sprite/billboard-pipeline.js +54 -56
- package/lib/sprite/billboard-pipeline.js.map +1 -1
- package/lib/sprite/custom-shader-core.js +1 -1
- package/lib/sprite/custom-shader-core.js.map +1 -1
- package/lib/sprite/shared/sprite-atlas.js +2 -2
- package/lib/sprite/shared/sprite-atlas.js.map +1 -1
- package/lib/sprite/sprite-2d-coverage-gamma.js +58 -0
- package/lib/sprite/sprite-2d-coverage-gamma.js.map +1 -0
- package/lib/sprite/sprite-2d-uvscroll.js +39 -0
- package/lib/sprite/sprite-2d-uvscroll.js.map +1 -0
- package/lib/sprite/sprite-2d.js +6 -36
- package/lib/sprite/sprite-2d.js.map +1 -1
- package/lib/sprite/sprite-coverage-gamma-hook.js +10 -0
- package/lib/sprite/sprite-coverage-gamma-hook.js.map +1 -0
- package/lib/sprite/sprite-custom-shader.js +2 -2
- package/lib/sprite/sprite-custom-shader.js.map +1 -1
- package/lib/sprite/sprite-pipeline.js +61 -73
- package/lib/sprite/sprite-pipeline.js.map +1 -1
- package/lib/sprite/sprite-renderable.js +5 -5
- package/lib/sprite/sprite-renderable.js.map +1 -1
- package/lib/sprite/sprite-renderer.js +4 -4
- package/lib/sprite/sprite-renderer.js.map +1 -1
- package/lib/sprite/sprite-scene.js +1 -1
- package/lib/sprite/sprite-scene.js.map +1 -1
- package/lib/text/_gpu/text-pipeline.js +1 -1
- package/lib/text/_gpu/text-pipeline.js.map +1 -1
- package/lib/text/text-renderer.js +3 -1
- package/lib/text/text-renderer.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-gltf.js","sources":["../../../src/loader-gltf/load-gltf.ts"],"sourcesContent":["import { F32, U32, U16, U8, DV } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { TransformNode } from \"../scene/transform-node.js\";\nimport type { AssetContainer } from \"../asset-container.js\";\nimport { createTransformNode } from \"../scene/transform-node.js\";\nimport { createSceneNodeFromMatrix } from \"../scene/scene-node.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Mesh, MeshGPU } from \"../mesh/mesh.js\";\nimport { initMeshTransform } from \"../mesh/mesh.js\";\nimport { getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport { createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport { resolveAccessor, buildParentMap, computeNodeWorldMatrix, anyPrimitive, needsOrmComposite, TYPE_SIZES } from \"./gltf-parser.js\";\nimport type { AccessorView } from \"./gltf-parser.js\";\nimport type { GltfVb } from \"./gltf-interleave.js\";\nimport type { GltfMaterialData, GltfMatExtCtx } from \"./gltf-material.js\";\nimport { assembleMaterial, makeImageFetcher } from \"./gltf-material.js\";\nimport type { DecodedPrimitive, GltfFeature, GltfLoadCtx } from \"./gltf-feature.js\";\nimport type { TextureWrapFn } from \"./gltf-pbr-builder.js\";\nimport { assemblePbrProps, buildDefaultPbrTextures, identityTexWrap, runMatExts, uploadTex } from \"./gltf-pbr-builder.js\";\nimport type * as GltfColorNormalize from \"./gltf-color-normalize.js\";\nimport type * as GltfFeatureRegistry from \"./gltf-feature-registry.js\";\nimport type * as GltfPbrBuilderExt from \"./gltf-pbr-builder-ext.js\";\n\n/** Dynamically-imported interleave module — loaded only when an asset actually\n * contains a strided bufferView, so non-interleaved scenes pay zero cost. */\ntype InterleaveModule = typeof import(\"./gltf-interleave.js\");\nlet _interleavePromise: Promise<InterleaveModule> | undefined;\nfunction loadInterleave(): Promise<InterleaveModule> {\n return (_interleavePromise ??= import(\"./gltf-interleave.js\"));\n}\n\nlet _gltfFeatureRegistryPromise: Promise<typeof GltfFeatureRegistry> | undefined;\nfunction importGltfFeatureRegistry(): Promise<typeof GltfFeatureRegistry> {\n return (_gltfFeatureRegistryPromise ??= import(\"./gltf-feature-registry.js\"));\n}\n\nlet _colorNormalizePromise: Promise<typeof GltfColorNormalize> | undefined;\nfunction importColorNormalize(): Promise<typeof GltfColorNormalize> {\n return (_colorNormalizePromise ??= import(\"./gltf-color-normalize.js\"));\n}\n\n/** Parsed mesh data ready for GPU upload. */\nexport interface GltfMeshData {\n /** @internal Tight CPU positions, or null when sourced from an interleaved\n * bufferView (in which case `_vb._p` holds the strided source for lazy de-striding). */\n _positions: Float32Array | null;\n /** @internal */\n _normals: Float32Array | null;\n /** @internal */\n _tangents: Float32Array | null;\n /** @internal */\n _uvs: Float32Array | null;\n /** @internal */\n _uv2s: Float32Array | null;\n /** @internal */\n _colors: Float32Array | null;\n /** @internal Primitive had no NORMAL attribute → flat-shade (glTF spec). */\n _flatNormal?: boolean;\n /** @internal */\n _indices: Uint16Array | Uint32Array;\n /** @internal */\n _vertexCount: number;\n /** @internal */\n _indexCount: number;\n /** @internal */\n _worldMatrix: Mat4;\n /** @internal */\n _material: GltfMaterialData;\n /** @internal Interleaved vertex sources (genuine GPU interleaving + lazy CPU de-stride).\n * Absent → all tight. */\n _vb?: GltfVb;\n /** @internal glTF node index this mesh came from (for hierarchy reconstruction\n * and for features that need to resolve skin/morph data lazily). */\n _nodeIndex: number;\n /** @internal Raw primitive definition — features (skeleton, morph, …) read their\n * own attributes/targets from here without bloating core extraction. */\n _primitive: any;\n /** @internal Pre-decoded primitive (Draco et al.) if a preMesh feature produced one. */\n _decoded?: DecodedPrimitive;\n}\n\n/**\n * Load a glTF/GLB asset, parse it, and upload mesh + material data to GPU.\n * Supports both binary GLB and separate .gltf + .bin + image files.\n * Registers a deferred PBR renderable builder.\n * Automatically parses glTF animations if present.\n *\n * Returns a AssetContainer. Pass it to addToScene() which adds the hierarchy,\n * registers animation ticks, and applies any scene-level settings.\n *\n * @param engine - The engine to upload GPU resources to.\n * @param url - URL of the .glb/.gltf asset to fetch.\n */\nexport function loadGltf(engine: EngineContext, url: string): Promise<AssetContainer>;\n/**\n * Load a glTF/GLB asset directly from already-loaded local data (drag-and-drop, OPFS, a `fetch` body, etc.).\n *\n * GLB-vs-glTF is determined from the data's magic bytes, not a file extension. `ArrayBuffer`/`Blob` inputs\n * have no base URL, so they must be self-contained: a GLB, or a glTF whose buffers/images use `data:` URIs.\n * A glTF that references external `.bin`/image files by relative path can only be loaded from a URL.\n *\n * @param engine - The engine to upload GPU resources to.\n * @param data - The raw `ArrayBuffer` or `Blob` of a self-contained glTF/GLB asset.\n */\nexport function loadGltf(engine: EngineContext, data: ArrayBuffer | Blob): Promise<AssetContainer>;\nexport async function loadGltf(engine: EngineContext, source: string | ArrayBuffer | Blob): Promise<AssetContainer> {\n const { json, binChunk, baseUrl } = await fetchGltfAsset(source);\n\n // Build parent map + world-matrix cache once for O(n) hierarchy traversal\n const parentMap = buildParentMap(json);\n const worldMatrixCache = new Map<number, Mat4>();\n\n // Discover every triggered feature (material exts, skeleton, morph,\n // animations, variants, …). The feature registry + its ~24 dynamic-import\n // thunks live in a separate module that is itself dynamic-imported only when\n // the asset can possibly trigger a feature — so plain metallic-roughness\n // GLBs (no extensions/animations/skins/morphs/ORM-composite) never fetch the\n // registry. Core loader knows zero feature names.\n const features = assetUsesGltfFeatures(json) ? await (await importGltfFeatureRegistry()).loadGltfFeatures(json) : [];\n\n // Pre-parse hooks (EXT_meshopt_compression decompression, KHR_mesh_quantization\n // dequantization) may rewrite bufferViews/accessors and hand back a replacement\n // binary chunk. Run sequentially in registry order so later features see earlier\n // rewrites. No-op (and zero cost) when no triggered feature defines preParse.\n let activeBin = binChunk;\n for (const f of features) {\n if (f.preParse) {\n const replacement = await f.preParse(json, activeBin);\n if (replacement) {\n activeBin = replacement;\n }\n }\n }\n\n const matExts: GltfFeature[] = features.filter((f) => f.applyMaterial);\n // Compose every feature's wrapTexture hook into a single function. Identity\n // when no feature contributes one (common case) — keeps the hot path free\n // of per-texture work and lets bundlers tree-shake the helpers.\n const texWraps = features.filter((f) => f.wrapTexture).map((f) => f.wrapTexture!);\n const wrapTex: TextureWrapFn = !texWraps.length ? identityTexWrap : (tex, ti) => texWraps.reduce((acc, w) => w(acc, ti), tex);\n\n // Run every feature's pre-mesh hook (e.g. Draco decompression) and merge\n // their primitive-keyed decode caches. Features without `preMesh` contribute\n // nothing; the map stays empty when no primitive-level feature triggered.\n const decodedPrimitives = new Map<unknown, DecodedPrimitive>();\n for (const frag of await Promise.all(features.flatMap((f) => (f.preMesh ? [f.preMesh(json, activeBin, baseUrl)] : [])))) {\n for (const [k, v] of frag) {\n decodedPrimitives.set(k, v);\n }\n }\n\n const meshDatas = await extractAllMeshes(json, activeBin, baseUrl, parentMap, worldMatrixCache, decodedPrimitives);\n\n const ctx: GltfLoadCtx = {\n _engine: engine,\n _json: json,\n _binChunk: activeBin,\n _baseUrl: baseUrl,\n _parentMap: parentMap,\n _worldMatrixCache: worldMatrixCache,\n _matExts: matExts,\n _wrapTex: wrapTex,\n };\n\n const meshes = await uploadMeshes(meshDatas, features, ctx);\n\n // Build TransformNode hierarchy from glTF nodes. Returns both the synthetic root\n // and a glTF-node-index → SceneNode map (used by node-visibility + animation-pointer).\n const { root, nodeMap } = buildNodeHierarchy(json, meshes, meshDatas);\n ctx._nodeMap = nodeMap;\n\n // Run every feature's per-asset hook (animations, variants, metadata, …) and\n // merge the returned AssetContainer fragments. `entities` is appended (never\n // overwritten) so features like KHR_lights_punctual can contribute lights\n // without trampling the root TransformNode.\n const assetFragments = await Promise.all(features.flatMap((f) => (f.applyAsset ? [f.applyAsset(meshes, root, ctx)] : [])));\n const container: AssetContainer = { entities: [root] };\n for (const frag of assetFragments) {\n if (frag.entities?.length) {\n container.entities.push(...frag.entities);\n }\n const { entities: _ignored, ...rest } = frag;\n void _ignored;\n Object.assign(container, rest);\n }\n return container;\n}\n\n/** Fetch/resolve + parse a glTF or GLB asset from a URL string, ArrayBuffer, or Blob.\n * Returns the JSON, binary chunk, and base URL (empty for non-URL sources). */\nasync function fetchGltfAsset(source: string | ArrayBuffer | Blob): Promise<{ json: any; binChunk: DataView; baseUrl: string }> {\n // Resolve the source to bytes. Only a URL string yields a base URL for resolving external .bin/image\n // references; ArrayBuffer/Blob inputs are self-contained (GLB, or glTF with data: URIs).\n const isUrl = typeof source === \"string\";\n const baseUrl = isUrl ? source.substring(0, source.lastIndexOf(\"/\") + 1) : \"\";\n const buffer = isUrl ? await fetch(source).then((r) => r.arrayBuffer()) : source instanceof Blob ? await source.arrayBuffer() : source;\n\n // Classify by the GLB magic (\"glTF\" = 0x46546c67, little-endian) rather than the URL extension, so\n // object URLs (blob:…), OPFS handles, and extensionless sources are detected correctly. The length guard\n // keeps an empty/too-short input failing with the JSON/GLB parse error below, not a DataView RangeError.\n if (buffer.byteLength >= 4 && new DV(buffer).getUint32(0, true) === 0x46546c67) {\n const glb = await import(\"./gltf-glb-parser.js\");\n return { ...glb.parseGlbContainer(buffer), baseUrl };\n }\n\n const jsonAsset = await import(\"./gltf-json-asset.js\");\n return jsonAsset.parseGltfJsonAsset(buffer, baseUrl);\n}\n\n/** Cheap superset gate: returns true iff the asset can possibly trigger at least\n * one optional glTF feature. Every `_features` predicate in gltf-feature-registry\n * is implied by one of these buckets (all hasExt/hasMatExt features require a\n * non-empty `extensionsUsed`), so when this returns false the registry's\n * `loadGltfFeatures` would return `[]` anyway — letting the core loader skip the\n * registry import entirely and keep its ~24 feature import-thunks out of the\n * bundle for plain metallic-roughness assets. */\nfunction assetUsesGltfFeatures(json: any) {\n return (\n json.extensionsUsed?.length ||\n json.animations?.length ||\n JSON.stringify(json).includes(\"extras\") ||\n (json.skins?.length && anyPrimitive(json, (p) => p.attributes?.JOINTS_0 !== undefined)) ||\n anyPrimitive(json, (p) => !!p.targets?.length) ||\n needsOrmComposite(json)\n );\n}\n\n// --- Hierarchy Reconstruction ---\n\n/** Build a TransformNode tree mirroring the glTF node hierarchy.\n * Meshes are attached as children. Non-mesh nodes become\n * pure TransformNodes preserving TRS for cloning/repositioning.\n * Parent links are set by addToScene() when the tree is added to the scene.\n * Also returns a glTF-node-index → SceneNode map used by per-asset features\n * (KHR_node_visibility, KHR_animation_pointer) to address specific nodes. */\nfunction buildNodeHierarchy(json: any, meshes: Mesh[], meshDatas: GltfMeshData[]): { root: TransformNode; nodeMap: (TransformNode | undefined)[] } {\n // Map nodeIndex → uploaded Mesh[]\n const nodeToMeshes = new Map<number, Mesh[]>();\n for (let i = 0; i < meshDatas.length; i++) {\n const ni = meshDatas[i]!._nodeIndex;\n let arr = nodeToMeshes.get(ni);\n if (!arr) {\n arr = [];\n nodeToMeshes.set(ni, arr);\n }\n arr.push(meshes[i]!);\n }\n\n const nodeMap: (TransformNode | undefined)[] = new Array(json.nodes?.length ?? 0);\n\n // Recursive builder\n function buildNode(nodeIdx: number): TransformNode {\n const node = json.nodes[nodeIdx];\n const name = node.name ?? `node_${nodeIdx}`;\n let tn: TransformNode;\n if (node.matrix) {\n tn = createSceneNodeFromMatrix(name, node.matrix as Mat4);\n } else {\n const t = node.translation ?? [0, 0, 0];\n const r = node.rotation ?? [0, 0, 0, 1];\n const s = node.scale ?? [1, 1, 1];\n tn = createTransformNode(name, t[0], t[1], t[2], r[0], r[1], r[2], r[3], s[0], s[1], s[2]);\n }\n nodeMap[nodeIdx] = tn;\n if (node.children) {\n for (const childIdx of node.children) {\n tn.children.push(buildNode(childIdx));\n }\n }\n const nodeMeshes = nodeToMeshes.get(nodeIdx) ?? [];\n tn.children.push(...nodeMeshes);\n return tn;\n }\n\n // Synthetic root (like BJS __root__) — applies RH→LH conversion via scale\n // BJS: rotation [0,1,0,0] + scale [1,1,-1] = diag(-1, 1, 1, 1)\n const sceneRoots: number[] = json.scenes?.[json.scene ?? 0]?.nodes ?? [];\n const rootChildren = sceneRoots.map((ni: number) => buildNode(ni));\n const root = createTransformNode(\"__root__\", 0, 0, 0, 0, 0, 0, 1, -1, 1, 1);\n root.children.push(...rootChildren);\n return { root, nodeMap };\n}\n\n// --- Mesh Extraction ---\n\nasync function extractAllMeshes(\n json: any,\n binChunk: DataView,\n baseUrl: string,\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n decodedPrimitives: Map<unknown, DecodedPrimitive>\n): Promise<GltfMeshData[]> {\n // Per-load image cache — avoids decoding the same glTF image index multiple times\n const imageCache = new Map<number, Promise<ImageBitmap>>();\n\n // Cache material assembly by glTF material index — avoids duplicate image fetches\n const matCache = new Map<number, Promise<GltfMaterialData>>();\n const getMat = (matIdx: number): Promise<GltfMaterialData> => {\n const key = matIdx ?? -1;\n let p = matCache.get(key);\n if (!p) {\n p = assembleMaterial(json, binChunk, matIdx, baseUrl, imageCache);\n matCache.set(key, p);\n }\n return p;\n };\n\n // First pass: do all sync work, fire all material fetches concurrently\n const partials: Array<Omit<GltfMeshData, \"_material\">> = [];\n const matPromises: Promise<GltfMaterialData>[] = [];\n\n // Genuine GPU interleaving is the ONLY reason to touch the interleave module.\n // Many exporters declare `byteStride` even on tightly-packed bufferViews, and a\n // preMesh feature (e.g. the basisu extension's readStridedFloat path) may already\n // de-stride a primitive — so we load the module only for a primitive that is\n // genuinely over-strided AND not already decoded. Other scenes pay zero cost: the\n // module is fetched lazily on the first such primitive (memoized), never before.\n const _accs = json.accessors as any[];\n const _bvs = json.bufferViews as any[] | undefined;\n const _strided = (p: any): boolean => {\n for (const k in p.attributes) {\n const a = _accs[p.attributes[k]];\n const s = _bvs?.[a?.bufferView]?.byteStride;\n if (\n s !== undefined &&\n s !== (TYPE_SIZES[a.type] ?? 1) * (a.componentType === 5126 || a.componentType === 5125 ? 4 : a.componentType === 5123 || a.componentType === 5122 ? 2 : 1)\n ) {\n return true;\n }\n }\n return false;\n };\n\n for (let nodeIdx = 0; nodeIdx < json.nodes.length; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n\n const meshIndex = node.mesh as number;\n const mesh = json.meshes[meshIndex];\n const worldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n\n for (let primitiveIndex = 0; primitiveIndex < mesh.primitives.length; primitiveIndex++) {\n const primitive = mesh.primitives[primitiveIndex];\n const attrs = primitive.attributes;\n const decoded = decodedPrimitives.get(primitive);\n\n // Genuine GPU interleaving: only a primitive that genuinely sources ≥1\n // attribute from an over-strided bufferView (and was not already decoded\n // by a preMesh feature) takes this path. The module is imported lazily on\n // first need — non-interleaved assets never fetch it. Tight primitives\n // fall through to the path below (byte-identical to non-interleaved).\n if (!decoded && _strided(primitive)) {\n const ip = (await loadInterleave()).buildInterleavedPartial(json, binChunk, primitive, worldMatrix, nodeIdx);\n if (ip) {\n matPromises.push(getMat(primitive.material));\n partials.push(ip);\n continue;\n }\n }\n\n const resolveAttr = (name: string): AccessorView | null => {\n if (decoded && decoded._attributes.has(name)) {\n const data = decoded._attributes.get(name)!;\n const componentCount = data.length / decoded._vertexCount;\n return { _data: data, _count: decoded._vertexCount, _componentCount: componentCount };\n }\n const idx = attrs[name];\n return idx !== undefined ? resolveAccessor(json, binChunk, idx) : null;\n };\n const posData = resolveAttr(\"POSITION\")!;\n const normData = resolveAttr(\"NORMAL\");\n const uvData = resolveAttr(\"TEXCOORD_0\");\n const uv2Data = resolveAttr(\"TEXCOORD_1\");\n const tanData = resolveAttr(\"TANGENT\");\n const colorData = resolveAttr(\"COLOR_0\");\n const idxData = decoded\n ? decoded._indexCount > 0\n ? { _data: decoded._indices, _count: decoded._indexCount, _componentCount: 1 }\n : null\n : primitive.indices !== undefined\n ? resolveAccessor(json, binChunk, primitive.indices)\n : null;\n const normalsHelper = !idxData || !normData ? await import(\"./gltf-normals.js\") : null;\n // glTF COLOR_0 may be VEC3 or VEC4 with float, normalized ubyte, or normalized\n // ushort components, but the PBR pipeline binds vertex color as a single\n // float32x4 layout (rgb modulates base color, a modulates alpha). Normalize any\n // source to a tight float32 RGBA buffer so the GPU stride matches the layout\n // (otherwise every vertex misaligns -> garbage/black); a VEC3 source gets a=1.\n // The normalizer is imported lazily on first need — colorless assets never fetch it\n // (the runtime caches the module, so the per-primitive import() resolves instantly).\n const colors = colorData ? (await importColorNormalize()).normalizeColorToVec4(colorData._data, colorData._count, colorData._componentCount) : null;\n\n // Keep vertex data as-is from glTF — RH→LH conversion handled by root world matrix\n const indices = idxData\n ? idxData._data instanceof U32\n ? new U32(idxData._data as Uint32Array)\n : idxData._data instanceof U8\n ? Uint16Array.from(idxData._data as Uint8Array)\n : new U16(idxData._data!.buffer, idxData._data!.byteOffset, idxData._count)\n : normalsHelper!.createSequentialIndices(posData._count);\n\n // Fire material fetch without awaiting — all materials load in parallel\n matPromises.push(getMat(primitive.material));\n\n // Smooth-normal generation is lazily imported on first need — assets that\n // always provide NORMAL (the common case) never bundle or fetch this code.\n const normals = normData ? (normData._data as Float32Array) : normalsHelper!.computeSmoothNormals(posData._data as Float32Array, indices, posData._count);\n\n partials.push({\n _positions: posData._data as Float32Array,\n _normals: normals,\n _tangents: tanData ? (tanData._data as Float32Array) : null,\n _uvs: uvData ? (uvData._data as Float32Array) : new F32(posData._count * 2),\n _uv2s: uv2Data ? (uv2Data._data as Float32Array) : null,\n _colors: colors,\n _flatNormal: !normData,\n _indices: indices,\n _vertexCount: posData._count,\n _indexCount: indices.length,\n _worldMatrix: worldMatrix,\n _nodeIndex: nodeIdx,\n _primitive: primitive,\n _decoded: decoded,\n });\n }\n }\n\n // Resolve all material fetches in parallel\n const materials = await Promise.all(matPromises);\n return partials.map((p, i) => ({ ...p, _material: materials[i]! }));\n}\n\n// --- GPU Upload ---\n\n// Pre-resolved generateMipmaps function— loaded once before texture uploads\nlet _generateMipmaps: ((engine: EngineContext, texture: GPUTexture, face?: number) => void) | null = null;\n\nasync function ensureMipmapModule(): Promise<void> {\n if (!_generateMipmaps) {\n _generateMipmaps = (await import(\"../texture/generate-mipmaps.js\")).generateMipmaps;\n }\n}\n\nasync function uploadMeshes(meshDatas: GltfMeshData[], features: GltfFeature[], ctx: GltfLoadCtx): Promise<Mesh[]> {\n const { _engine: engine, _json: json, _binChunk: binChunk, _baseUrl: baseUrl, _matExts: matExts, _wrapTex: wrapTex } = ctx;\n // Default sampler (repeat/linear) used for factor textures and when a texture has no glTF sampler.\n const sampler = getOrCreateSampler(engine, {\n magFilter: \"linear\",\n minFilter: \"linear\",\n mipmapFilter: \"linear\",\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n maxAnisotropy: 4,\n });\n // Per-texture glTF samplers (wrap/filter) are honored only when the asset declares a\n // NON-default sampler (clamp/mirror wrap, or nearest filtering); the common case\n // (default repeat/linear) uses the single shared sampler above and the master-identical\n // buildDefaultPbrTextures path. Both the descriptor logic AND the sampler-aware texture\n // builder are lazy so default-sampler assets pay zero bundle bytes for the feature.\n let samplerFor: ((texInfo: any) => GPUSampler) | undefined;\n let buildSampledPbrTextures: typeof import(\"./gltf-sampler-desc.js\").buildSampledPbrTextures | undefined;\n if (json.samplers?.some((s: any) => s.wrapS > 10497 || s.wrapT > 10497 || s.magFilter === 9728 || (s.minFilter != null && s.minFilter !== 9729 && s.minFilter !== 9987))) {\n const mod = await import(\"./gltf-sampler-desc.js\");\n samplerFor = mod.makeSamplerFor(engine, json, sampler);\n buildSampledPbrTextures = mod.buildSampledPbrTextures;\n }\n\n await ensureMipmapModule();\n const meshFeatures = features.filter((f) => f.applyMesh);\n\n // Texture cache: shared textures uploaded once, keyed by (bitmap, srgb).\n const texCache = new Map<number, Texture2D>();\n let texId = 0;\n const bitmapIds = new Map<ImageBitmap, number>();\n\n function getCachedTexture(bitmap: ImageBitmap, srgb: boolean): Texture2D {\n let id = bitmapIds.get(bitmap);\n if (id === undefined) {\n bitmapIds.set(bitmap, (id = texId++));\n }\n const key = id * 2 + +srgb;\n let tex = texCache.get(key);\n if (!tex) {\n tex = uploadTex(engine, bitmap, srgb, sampler, _generateMipmaps!);\n texCache.set(key, tex);\n }\n return tex;\n }\n\n // Per-load image fetcher for ext modules (uses same image cache as core).\n const extImageCache = matExts.length ? new Map<number, Promise<ImageBitmap>>() : null;\n const extFetchImg = extImageCache ? makeImageFetcher(json, binChunk, baseUrl, extImageCache) : null;\n const extCtx: GltfMatExtCtx = {\n _engine: engine,\n async _texture(texInfo, sRGB) {\n if (!texInfo || !extFetchImg) {\n return undefined;\n }\n const img = await extFetchImg(texInfo);\n return img ? wrapTex(getCachedTexture(img, sRGB), texInfo) : undefined;\n },\n _uploadImage(bitmap, sRGB) {\n return uploadTex(engine, bitmap, sRGB, sampler, _generateMipmaps!);\n },\n };\n\n // Slow-path trigger: per-texture UV wrapping (KHR_texture_transform)\n // or any core texture declaring texCoord=1. Scene1 stays identity→fast path.\n let _needsPbrExt = wrapTex !== identityTexWrap;\n if (!_needsPbrExt) {\n const mats = (json as { materials?: unknown[] }).materials;\n if (mats && JSON.stringify(mats).includes('\"texCoord\":1')) {\n _needsPbrExt = true;\n }\n }\n let _pbrExtPromise: Promise<typeof GltfPbrBuilderExt> | null = null;\n const _ensurePbrExt = () => (_pbrExtPromise ??= import(\"./gltf-pbr-builder-ext.js\"));\n\n /** Default ORM upload: single MR-or-occlusion image, or 1×1 fallback baked from\n * metallicFactor/roughnessFactor. The composite case (MR+occlusion separate) is\n * handled by the gltf-ext-orm extension which overrides this via `extLayers`. */\n\n // Build a PbrMaterialProps from parsed glTF material data.\n // Uses shared texture caches so identical bitmaps are uploaded once.\n const builtMaterialCache = new Map<GltfMaterialData, Promise<PbrMaterialProps>>();\n async function buildPbrFromGltfMat(mat: GltfMaterialData): Promise<PbrMaterialProps> {\n let cached = builtMaterialCache.get(mat);\n if (cached) {\n return cached;\n }\n cached = (async () => {\n const extLayers = await runMatExts(mat, matExts, extCtx);\n if (_needsPbrExt) {\n const extMod = await _ensurePbrExt();\n const tex = extMod.buildDefaultPbrTexturesExt(engine, mat, sampler, _generateMipmaps!, getCachedTexture, wrapTex, samplerFor);\n return extMod.assemblePbrPropsExt(mat, tex, extLayers);\n }\n const tex = buildSampledPbrTextures\n ? buildSampledPbrTextures(engine, mat, sampler, _generateMipmaps!, samplerFor!, getCachedTexture)\n : buildDefaultPbrTextures(engine, mat, sampler, _generateMipmaps!, getCachedTexture);\n return assemblePbrProps(mat, tex.baseColorTexture, tex.ormTexture, tex.normalTexture, tex.emissiveTexture, extLayers);\n })();\n builtMaterialCache.set(mat, cached);\n return cached;\n }\n\n const meshes = await Promise.all(\n meshDatas.map(async (m, i): Promise<Mesh> => {\n const material = await buildPbrFromGltfMat(m._material);\n const meshName = json.meshes[json.nodes[m._nodeIndex].mesh].name;\n\n // Interleaved meshes are fully built by the dynamic module (kept out of\n // this bundle for non-interleaved scenes). The tight path below is\n // byte-identical to the non-interleaved engine.\n let mesh: Mesh;\n if (m._vb) {\n mesh = (await loadInterleave()).buildInterleavedMesh(engine, m, i, material, meshName) as Mesh;\n } else {\n const [boundMin, boundMax] = computeAabb(m._positions!, m._worldMatrix);\n const gpu: MeshGPU = {\n positionBuffer: createMappedBuffer(engine, m._positions!, BU.VERTEX),\n normalBuffer: createMappedBuffer(engine, m._normals!, BU.VERTEX),\n tangentBuffer: m._tangents ? createMappedBuffer(engine, m._tangents, BU.VERTEX) : null,\n uvBuffer: createMappedBuffer(engine, m._uvs!, BU.VERTEX),\n uv2Buffer: m._uv2s ? createMappedBuffer(engine, m._uv2s, BU.VERTEX) : null,\n colorBuffer: m._colors ? createMappedBuffer(engine, m._colors, BU.VERTEX) : null,\n indexBuffer: createMappedBuffer(engine, m._indices, BU.INDEX),\n indexCount: m._indexCount,\n indexFormat: (m._indices instanceof U32 ? \"uint32\" : \"uint16\") as GPUIndexFormat,\n };\n\n mesh = {\n name: meshName || `gltf_mesh_${i}`,\n material,\n receiveShadows: false,\n boundMin,\n boundMax,\n skeleton: null,\n morphTargets: null,\n _gpu: gpu,\n _flatNormal: m._flatNormal,\n } as unknown as Mesh;\n initMeshTransform(mesh);\n\n // Retain CPU geometry for detailed picking.\n mesh._cpuPositions = m._positions!;\n mesh._cpuNormals = m._normals!;\n mesh._cpuUvs = m._uvs!;\n mesh._cpuIndices = m._indices instanceof U32 ? m._indices : new U32(m._indices);\n engine._dlr?.m(mesh, m._uv2s, m._tangents, m._colors, m._indices, gpu.indexFormat);\n }\n\n // Run all per-mesh feature hooks (skeleton, morph, …) in parallel.\n // Each hook mutates `mesh` directly (e.g. attaches mesh.skeleton).\n if (meshFeatures.length > 0) {\n await Promise.all(meshFeatures.map((f) => f.applyMesh!(m, mesh, ctx)));\n }\n\n return mesh;\n })\n );\n\n return meshes;\n}\n"],"names":["tex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"load-gltf.js","sources":["../../../src/loader-gltf/load-gltf.ts"],"sourcesContent":["import { F32, U32, U16, U8, DV } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { TransformNode } from \"../scene/transform-node.js\";\nimport type { AssetContainer } from \"../asset-container.js\";\nimport { createTransformNode } from \"../scene/transform-node.js\";\nimport { createSceneNodeFromMatrix } from \"../scene/scene-node.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Mesh, MeshGPU } from \"../mesh/mesh.js\";\nimport { initMeshTransform } from \"../mesh/mesh.js\";\nimport { getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport { createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport { resolveAccessor, buildParentMap, computeNodeWorldMatrix, anyPrimitive, needsOrmComposite, TYPE_SIZES } from \"./gltf-parser.js\";\nimport type { AccessorView } from \"./gltf-parser.js\";\nimport type { GltfVb } from \"./gltf-interleave.js\";\nimport type { GltfMaterialData, GltfMatExtCtx } from \"./gltf-material.js\";\nimport { assembleMaterial, makeImageFetcher } from \"./gltf-material.js\";\nimport type { DecodedPrimitive, GltfFeature, GltfLoadCtx } from \"./gltf-feature.js\";\nimport type { TextureWrapFn } from \"./gltf-pbr-builder.js\";\nimport { assemblePbrProps, buildDefaultPbrTextures, identityTexWrap, runMatExts, uploadTex } from \"./gltf-pbr-builder.js\";\nimport type * as GltfColorNormalize from \"./gltf-color-normalize.js\";\nimport type * as GltfFeatureRegistry from \"./gltf-feature-registry.js\";\nimport type * as GltfPbrBuilderExt from \"./gltf-pbr-builder-ext.js\";\n\n/** Dynamically-imported interleave module — loaded only when an asset actually\n * contains a strided bufferView, so non-interleaved scenes pay zero cost. */\ntype InterleaveModule = typeof import(\"./gltf-interleave.js\");\nlet _interleavePromise: Promise<InterleaveModule> | undefined;\nfunction loadInterleave(): Promise<InterleaveModule> {\n return (_interleavePromise ??= import(\"./gltf-interleave.js\"));\n}\n\nlet _gltfFeatureRegistryPromise: Promise<typeof GltfFeatureRegistry> | undefined;\nfunction importGltfFeatureRegistry(): Promise<typeof GltfFeatureRegistry> {\n return (_gltfFeatureRegistryPromise ??= import(\"./gltf-feature-registry.js\"));\n}\n\nlet _colorNormalizePromise: Promise<typeof GltfColorNormalize> | undefined;\nfunction importColorNormalize(): Promise<typeof GltfColorNormalize> {\n return (_colorNormalizePromise ??= import(\"./gltf-color-normalize.js\"));\n}\n\n/** Parsed mesh data ready for GPU upload. */\nexport interface GltfMeshData {\n /** @internal Tight CPU positions, or null when sourced from an interleaved\n * bufferView (in which case `_vb._p` holds the strided source for lazy de-striding). */\n _positions: Float32Array | null;\n /** @internal */\n _normals: Float32Array | null;\n /** @internal */\n _tangents: Float32Array | null;\n /** @internal */\n _uvs: Float32Array | null;\n /** @internal */\n _uv2s: Float32Array | null;\n /** @internal */\n _colors: Float32Array | null;\n /** @internal Primitive had no NORMAL attribute → flat-shade (glTF spec). */\n _flatNormal?: boolean;\n /** @internal Non-triangle-list primitive topology index (1=points, 2=lines,\n * 3=line-strip, 4=triangle-strip) from the glTF primitive `mode`. Undefined =\n * triangle-list (the default). LINE_LOOP/TRIANGLE_FAN are unsupported (so is BJS). */\n _topology?: number;\n /** @internal */\n _indices: Uint16Array | Uint32Array;\n /** @internal */\n _vertexCount: number;\n /** @internal */\n _indexCount: number;\n /** @internal */\n _worldMatrix: Mat4;\n /** @internal */\n _material: GltfMaterialData;\n /** @internal Interleaved vertex sources (genuine GPU interleaving + lazy CPU de-stride).\n * Absent → all tight. */\n _vb?: GltfVb;\n /** @internal glTF node index this mesh came from (for hierarchy reconstruction\n * and for features that need to resolve skin/morph data lazily). */\n _nodeIndex: number;\n /** @internal Raw primitive definition — features (skeleton, morph, …) read their\n * own attributes/targets from here without bloating core extraction. */\n _primitive: any;\n /** @internal Pre-decoded primitive (Draco et al.) if a preMesh feature produced one. */\n _decoded?: DecodedPrimitive;\n}\n\n/**\n * Load a glTF/GLB asset, parse it, and upload mesh + material data to GPU.\n * Supports both binary GLB and separate .gltf + .bin + image files.\n * Registers a deferred PBR renderable builder.\n * Automatically parses glTF animations if present.\n *\n * Returns a AssetContainer. Pass it to addToScene() which adds the hierarchy,\n * registers animation ticks, and applies any scene-level settings.\n *\n * @param engine - The engine to upload GPU resources to.\n * @param url - URL of the .glb/.gltf asset to fetch.\n */\nexport function loadGltf(engine: EngineContext, url: string): Promise<AssetContainer>;\n/**\n * Load a glTF/GLB asset directly from already-loaded local data (drag-and-drop, OPFS, a `fetch` body, etc.).\n *\n * GLB-vs-glTF is determined from the data's magic bytes, not a file extension. `ArrayBuffer`/`Blob` inputs\n * have no base URL, so they must be self-contained: a GLB, or a glTF whose buffers/images use `data:` URIs.\n * A glTF that references external `.bin`/image files by relative path can only be loaded from a URL.\n *\n * @param engine - The engine to upload GPU resources to.\n * @param data - The raw `ArrayBuffer` or `Blob` of a self-contained glTF/GLB asset.\n */\nexport function loadGltf(engine: EngineContext, data: ArrayBuffer | Blob): Promise<AssetContainer>;\nexport async function loadGltf(engine: EngineContext, source: string | ArrayBuffer | Blob): Promise<AssetContainer> {\n const { json, binChunk, baseUrl } = await fetchGltfAsset(source);\n\n // Build parent map + world-matrix cache once for O(n) hierarchy traversal\n const parentMap = buildParentMap(json);\n const worldMatrixCache = new Map<number, Mat4>();\n\n // Discover every triggered feature (material exts, skeleton, morph,\n // animations, variants, …). The feature registry + its ~24 dynamic-import\n // thunks live in a separate module that is itself dynamic-imported only when\n // the asset can possibly trigger a feature — so plain metallic-roughness\n // GLBs (no extensions/animations/skins/morphs/ORM-composite) never fetch the\n // registry. Core loader knows zero feature names.\n const features = assetUsesGltfFeatures(json) ? await (await importGltfFeatureRegistry()).loadGltfFeatures(json) : [];\n\n // Pre-parse hooks (EXT_meshopt_compression decompression, KHR_mesh_quantization\n // dequantization) may rewrite bufferViews/accessors and hand back a replacement\n // binary chunk. Run sequentially in registry order so later features see earlier\n // rewrites. No-op (and zero cost) when no triggered feature defines preParse.\n let activeBin = binChunk;\n for (const f of features) {\n if (f.preParse) {\n const replacement = await f.preParse(json, activeBin);\n if (replacement) {\n activeBin = replacement;\n }\n }\n }\n\n const matExts: GltfFeature[] = features.filter((f) => f.applyMaterial);\n // Compose every feature's wrapTexture hook into a single function. Identity\n // when no feature contributes one (common case) — keeps the hot path free\n // of per-texture work and lets bundlers tree-shake the helpers.\n const texWraps = features.filter((f) => f.wrapTexture).map((f) => f.wrapTexture!);\n const wrapTex: TextureWrapFn = !texWraps.length ? identityTexWrap : (tex, ti) => texWraps.reduce((acc, w) => w(acc, ti), tex);\n\n // Run every feature's pre-mesh hook (e.g. Draco decompression) and merge\n // their primitive-keyed decode caches. Features without `preMesh` contribute\n // nothing; the map stays empty when no primitive-level feature triggered.\n const decodedPrimitives = new Map<unknown, DecodedPrimitive>();\n for (const frag of await Promise.all(features.flatMap((f) => (f.preMesh ? [f.preMesh(json, activeBin, baseUrl)] : [])))) {\n for (const [k, v] of frag) {\n decodedPrimitives.set(k, v);\n }\n }\n\n const meshDatas = await extractAllMeshes(json, activeBin, baseUrl, parentMap, worldMatrixCache, decodedPrimitives);\n\n const ctx: GltfLoadCtx = {\n _engine: engine,\n _json: json,\n _binChunk: activeBin,\n _baseUrl: baseUrl,\n _parentMap: parentMap,\n _worldMatrixCache: worldMatrixCache,\n _matExts: matExts,\n _wrapTex: wrapTex,\n };\n\n const meshes = await uploadMeshes(meshDatas, features, ctx);\n\n // Build TransformNode hierarchy from glTF nodes. Returns both the synthetic root\n // and a glTF-node-index → SceneNode map (used by node-visibility + animation-pointer).\n const { root, nodeMap } = buildNodeHierarchy(json, meshes, meshDatas);\n ctx._nodeMap = nodeMap;\n\n // Run every feature's per-asset hook (animations, variants, metadata, …) and\n // merge the returned AssetContainer fragments. `entities` is appended (never\n // overwritten) so features like KHR_lights_punctual can contribute lights\n // without trampling the root TransformNode.\n const assetFragments = await Promise.all(features.flatMap((f) => (f.applyAsset ? [f.applyAsset(meshes, root, ctx)] : [])));\n const container: AssetContainer = { entities: [root] };\n for (const frag of assetFragments) {\n if (frag.entities?.length) {\n container.entities.push(...frag.entities);\n }\n const { entities: _ignored, ...rest } = frag;\n void _ignored;\n Object.assign(container, rest);\n }\n return container;\n}\n\n/** Fetch/resolve + parse a glTF or GLB asset from a URL string, ArrayBuffer, or Blob.\n * Returns the JSON, binary chunk, and base URL (empty for non-URL sources). */\nasync function fetchGltfAsset(source: string | ArrayBuffer | Blob): Promise<{ json: any; binChunk: DataView; baseUrl: string }> {\n // Resolve the source to bytes. Only a URL string yields a base URL for resolving external .bin/image\n // references; ArrayBuffer/Blob inputs are self-contained (GLB, or glTF with data: URIs).\n const isUrl = typeof source === \"string\";\n // Resolve the source to an absolute URL so external .bin / image URIs resolve correctly even when the\n // caller passes a root-relative (\"/models/foo.gltf\") or document-relative path — `new URL(uri, base)`\n // downstream requires an absolute base. Absolute inputs (https://…) are returned unchanged. In a\n // non-DOM context (Node / a worker without `location`) fall back to a plain directory-prefix base.\n const baseUrl = !isUrl ? \"\" : typeof location !== \"undefined\" ? new URL(\".\", new URL(source, location.href)).href : source.slice(0, source.lastIndexOf(\"/\") + 1);\n const buffer = isUrl ? await fetch(source).then((r) => r.arrayBuffer()) : source instanceof Blob ? await source.arrayBuffer() : source;\n\n // Classify by the GLB magic (\"glTF\" = 0x46546c67, little-endian) rather than the URL extension, so\n // object URLs (blob:…), OPFS handles, and extensionless sources are detected correctly. The length guard\n // keeps an empty/too-short input failing with the JSON/GLB parse error below, not a DataView RangeError.\n if (buffer.byteLength >= 4 && new DV(buffer).getUint32(0, true) === 0x46546c67) {\n const glb = await import(\"./gltf-glb-parser.js\");\n return { ...glb.parseGlbContainer(buffer), baseUrl };\n }\n\n const jsonAsset = await import(\"./gltf-json-asset.js\");\n return jsonAsset.parseGltfJsonAsset(buffer, baseUrl);\n}\n\n/** Cheap superset gate: returns true iff the asset can possibly trigger at least\n * one optional glTF feature. Every `_features` predicate in gltf-feature-registry\n * is implied by one of these buckets (all hasExt/hasMatExt features require a\n * non-empty `extensionsUsed`), so when this returns false the registry's\n * `loadGltfFeatures` would return `[]` anyway — letting the core loader skip the\n * registry import entirely and keep its ~24 feature import-thunks out of the\n * bundle for plain metallic-roughness assets. */\nfunction assetUsesGltfFeatures(json: any) {\n return (\n json.extensionsUsed?.length ||\n json.animations?.length ||\n JSON.stringify(json).includes(\"extras\") ||\n (json.skins?.length && anyPrimitive(json, (p) => p.attributes?.JOINTS_0 !== undefined)) ||\n anyPrimitive(json, (p) => !!p.targets?.length) ||\n // A node with a negative-determinant local transform (odd negative scale, or a `matrix`\n // with negative 3x3 determinant) may need the negative-winding feature. This mirrors the\n // registry's `hasNegDetNode` predicate so a positive-determinant `matrix` node — extremely\n // common, e.g. TextureSettingsTest — does NOT needlessly pull the feature registry.\n (json.nodes as any[] | undefined)?.some((n: any) =>\n n.scale\n ? n.scale[0] * n.scale[1] * n.scale[2] < 0\n : n.matrix\n ? n.matrix[0] * (n.matrix[5] * n.matrix[10] - n.matrix[6] * n.matrix[9]) +\n n.matrix[1] * (n.matrix[6] * n.matrix[8] - n.matrix[4] * n.matrix[10]) +\n n.matrix[2] * (n.matrix[4] * n.matrix[9] - n.matrix[5] * n.matrix[8]) <\n 0\n : false\n ) ||\n // Non-triangle primitive topology (POINTS/LINES/LINE_STRIP/TRIANGLE_STRIP).\n anyPrimitive(json, (p) => p.mode !== undefined && p.mode !== 4) ||\n needsOrmComposite(json)\n );\n}\n\n// --- Hierarchy Reconstruction ---\n\n/** Build a TransformNode tree mirroring the glTF node hierarchy.\n * Meshes are attached as children. Non-mesh nodes become\n * pure TransformNodes preserving TRS for cloning/repositioning.\n * Parent links are set by addToScene() when the tree is added to the scene.\n * Also returns a glTF-node-index → SceneNode map used by per-asset features\n * (KHR_node_visibility, KHR_animation_pointer) to address specific nodes. */\nfunction buildNodeHierarchy(json: any, meshes: Mesh[], meshDatas: GltfMeshData[]): { root: TransformNode; nodeMap: (TransformNode | undefined)[] } {\n // Map nodeIndex → uploaded Mesh[]\n const nodeToMeshes = new Map<number, Mesh[]>();\n for (let i = 0; i < meshDatas.length; i++) {\n const ni = meshDatas[i]!._nodeIndex;\n let arr = nodeToMeshes.get(ni);\n if (!arr) {\n arr = [];\n nodeToMeshes.set(ni, arr);\n }\n arr.push(meshes[i]!);\n }\n\n const nodeMap: (TransformNode | undefined)[] = new Array(json.nodes?.length ?? 0);\n\n // Recursive builder\n function buildNode(nodeIdx: number): TransformNode {\n const node = json.nodes[nodeIdx];\n const name = node.name ?? `node_${nodeIdx}`;\n let tn: TransformNode;\n if (node.matrix) {\n tn = createSceneNodeFromMatrix(name, node.matrix as Mat4);\n } else {\n const t = node.translation ?? [0, 0, 0];\n const r = node.rotation ?? [0, 0, 0, 1];\n const s = node.scale ?? [1, 1, 1];\n tn = createTransformNode(name, t[0], t[1], t[2], r[0], r[1], r[2], r[3], s[0], s[1], s[2]);\n }\n nodeMap[nodeIdx] = tn;\n if (node.children) {\n for (const childIdx of node.children) {\n tn.children.push(buildNode(childIdx));\n }\n }\n const nodeMeshes = nodeToMeshes.get(nodeIdx) ?? [];\n tn.children.push(...nodeMeshes);\n return tn;\n }\n\n // Synthetic root (like BJS __root__) — applies RH→LH conversion via scale\n // BJS: rotation [0,1,0,0] + scale [1,1,-1] = diag(-1, 1, 1, 1)\n const sceneRoots: number[] = json.scenes?.[json.scene ?? 0]?.nodes ?? [];\n const rootChildren = sceneRoots.map((ni: number) => buildNode(ni));\n const root = createTransformNode(\"__root__\", 0, 0, 0, 0, 0, 0, 1, -1, 1, 1);\n root.children.push(...rootChildren);\n return { root, nodeMap };\n}\n\n// --- Mesh Extraction ---\n\nasync function extractAllMeshes(\n json: any,\n binChunk: DataView,\n baseUrl: string,\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n decodedPrimitives: Map<unknown, DecodedPrimitive>\n): Promise<GltfMeshData[]> {\n // Per-load image cache — avoids decoding the same glTF image index multiple times\n const imageCache = new Map<number, Promise<ImageBitmap>>();\n\n // Cache material assembly by glTF material index — avoids duplicate image fetches\n const matCache = new Map<number, Promise<GltfMaterialData>>();\n const getMat = (matIdx: number): Promise<GltfMaterialData> => {\n const key = matIdx ?? -1;\n let p = matCache.get(key);\n if (!p) {\n p = assembleMaterial(json, binChunk, matIdx, baseUrl, imageCache);\n matCache.set(key, p);\n }\n return p;\n };\n\n // First pass: do all sync work, fire all material fetches concurrently\n const partials: Array<Omit<GltfMeshData, \"_material\">> = [];\n const matPromises: Promise<GltfMaterialData>[] = [];\n\n // Genuine GPU interleaving is the ONLY reason to touch the interleave module.\n // Many exporters declare `byteStride` even on tightly-packed bufferViews, and a\n // preMesh feature (e.g. the basisu extension's readStridedFloat path) may already\n // de-stride a primitive — so we load the module only for a primitive that is\n // genuinely over-strided AND not already decoded. Other scenes pay zero cost: the\n // module is fetched lazily on the first such primitive (memoized), never before.\n const _accs = json.accessors as any[];\n const _bvs = json.bufferViews as any[] | undefined;\n const _strided = (p: any): boolean => {\n for (const k in p.attributes) {\n const a = _accs[p.attributes[k]];\n const s = _bvs?.[a?.bufferView]?.byteStride;\n if (\n s !== undefined &&\n s !== (TYPE_SIZES[a.type] ?? 1) * (a.componentType === 5126 || a.componentType === 5125 ? 4 : a.componentType === 5123 || a.componentType === 5122 ? 2 : 1)\n ) {\n return true;\n }\n }\n return false;\n };\n\n for (let nodeIdx = 0; nodeIdx < json.nodes.length; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n\n const meshIndex = node.mesh as number;\n const mesh = json.meshes[meshIndex];\n const worldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n\n for (let primitiveIndex = 0; primitiveIndex < mesh.primitives.length; primitiveIndex++) {\n const primitive = mesh.primitives[primitiveIndex];\n const attrs = primitive.attributes;\n const decoded = decodedPrimitives.get(primitive);\n\n // Genuine GPU interleaving: only a primitive that genuinely sources ≥1\n // attribute from an over-strided bufferView (and was not already decoded\n // by a preMesh feature) takes this path. The module is imported lazily on\n // first need — non-interleaved assets never fetch it. Tight primitives\n // fall through to the path below (byte-identical to non-interleaved).\n if (!decoded && _strided(primitive)) {\n const ip = await (await loadInterleave()).buildInterleavedPartial(json, binChunk, primitive, worldMatrix, nodeIdx);\n if (ip) {\n matPromises.push(getMat(primitive.material));\n partials.push(ip);\n continue;\n }\n }\n\n const resolveAttr = (name: string): AccessorView | null => {\n if (decoded && decoded._attributes.has(name)) {\n const data = decoded._attributes.get(name)!;\n const componentCount = data.length / decoded._vertexCount;\n return { _data: data, _count: decoded._vertexCount, _componentCount: componentCount };\n }\n const idx = attrs[name];\n return idx !== undefined ? resolveAccessor(json, binChunk, idx) : null;\n };\n const posData = resolveAttr(\"POSITION\")!;\n const normData = resolveAttr(\"NORMAL\");\n const uvData = resolveAttr(\"TEXCOORD_0\");\n const uv2Data = resolveAttr(\"TEXCOORD_1\");\n const tanData = resolveAttr(\"TANGENT\");\n const colorData = resolveAttr(\"COLOR_0\");\n const idxData = decoded\n ? decoded._indexCount > 0\n ? { _data: decoded._indices, _count: decoded._indexCount, _componentCount: 1 }\n : null\n : primitive.indices !== undefined\n ? resolveAccessor(json, binChunk, primitive.indices)\n : null;\n const normalsHelper = !idxData || !normData ? await import(\"./gltf-normals.js\") : null;\n // glTF COLOR_0 may be VEC3 or VEC4 with float, normalized ubyte, or normalized\n // ushort components, but the PBR pipeline binds vertex color as a single\n // float32x4 layout (rgb modulates base color, a modulates alpha). Normalize any\n // source to a tight float32 RGBA buffer so the GPU stride matches the layout\n // (otherwise every vertex misaligns -> garbage/black); a VEC3 source gets a=1.\n // The normalizer is imported lazily on first need — colorless assets never fetch it\n // (the runtime caches the module, so the per-primitive import() resolves instantly).\n const colors = colorData ? (await importColorNormalize()).normalizeColorToVec4(colorData._data, colorData._count, colorData._componentCount) : null;\n\n // TEXCOORD_0/_1 may be FLOAT or a normalized UNSIGNED_BYTE/SHORT accessor; the vertex\n // pipeline binds UVs as float32x2, so integer UVs are denormalized to [0,1] (reusing the\n // lazily-imported color/UV normalizer). Float UVs (the common case) pass through untouched.\n const uvs = uvData\n ? uvData._data instanceof F32\n ? (uvData._data as Float32Array)\n : (await importColorNormalize()).normalizeUvToVec2(uvData._data, uvData._count)\n : new F32(posData._count * 2);\n const uv2s = uv2Data\n ? uv2Data._data instanceof F32\n ? (uv2Data._data as Float32Array)\n : (await importColorNormalize()).normalizeUvToVec2(uv2Data._data, uv2Data._count)\n : null;\n\n // Keep vertex data as-is from glTF — RH→LH conversion handled by root world matrix\n const indices = idxData\n ? idxData._data instanceof U32\n ? new U32(idxData._data as Uint32Array)\n : idxData._data instanceof U8\n ? Uint16Array.from(idxData._data as Uint8Array)\n : new U16(idxData._data!.buffer, idxData._data!.byteOffset, idxData._count)\n : normalsHelper!.createSequentialIndices(posData._count);\n\n // Fire material fetch without awaiting — all materials load in parallel\n matPromises.push(getMat(primitive.material));\n\n // Smooth-normal generation is lazily imported on first need — assets that\n // always provide NORMAL (the common case) never bundle or fetch this code.\n const normals = normData ? (normData._data as Float32Array) : normalsHelper!.computeSmoothNormals(posData._data as Float32Array, indices, posData._count);\n\n partials.push({\n _positions: posData._data as Float32Array,\n _normals: normals,\n _tangents: tanData ? (tanData._data as Float32Array) : null,\n _uvs: uvs,\n _uv2s: uv2s,\n _colors: colors,\n _flatNormal: !normData,\n _indices: indices,\n _vertexCount: posData._count,\n _indexCount: indices.length,\n _worldMatrix: worldMatrix,\n _nodeIndex: nodeIdx,\n _primitive: primitive,\n _decoded: decoded,\n });\n }\n }\n\n // Resolve all material fetches in parallel\n const materials = await Promise.all(matPromises);\n return partials.map((p, i) => ({ ...p, _material: materials[i]! }));\n}\n\n// --- GPU Upload ---\n\n// Pre-resolved generateMipmaps function— loaded once before texture uploads\nlet _generateMipmaps: ((engine: EngineContext, texture: GPUTexture, face?: number) => void) | null = null;\n\nasync function ensureMipmapModule(): Promise<void> {\n if (!_generateMipmaps) {\n _generateMipmaps = (await import(\"../texture/generate-mipmaps.js\")).generateMipmaps;\n }\n}\n\nasync function uploadMeshes(meshDatas: GltfMeshData[], features: GltfFeature[], ctx: GltfLoadCtx): Promise<Mesh[]> {\n const { _engine: engine, _json: json, _binChunk: binChunk, _baseUrl: baseUrl, _matExts: matExts, _wrapTex: wrapTex } = ctx;\n // Default sampler (repeat/linear) used for factor textures and when a texture has no glTF sampler.\n const sampler = getOrCreateSampler(engine, {\n magFilter: \"linear\",\n minFilter: \"linear\",\n mipmapFilter: \"linear\",\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n maxAnisotropy: 4,\n });\n // Per-texture glTF samplers (wrap/filter) are honored only when the asset declares a\n // NON-default sampler (clamp/mirror wrap, or nearest filtering); the common case\n // (default repeat/linear) uses the single shared sampler above and the master-identical\n // buildDefaultPbrTextures path. Both the descriptor logic AND the sampler-aware texture\n // builder are lazy so default-sampler assets pay zero bundle bytes for the feature.\n let samplerFor: ((texInfo: any) => GPUSampler) | undefined;\n let buildSampledPbrTextures: typeof import(\"./gltf-sampler-desc.js\").buildSampledPbrTextures | undefined;\n if (json.samplers?.some((s: any) => s.wrapS > 10497 || s.wrapT > 10497 || s.magFilter === 9728 || (s.minFilter != null && s.minFilter !== 9729 && s.minFilter !== 9987))) {\n const mod = await import(\"./gltf-sampler-desc.js\");\n samplerFor = mod.makeSamplerFor(engine, json, sampler);\n buildSampledPbrTextures = mod.buildSampledPbrTextures;\n }\n\n await ensureMipmapModule();\n const meshFeatures = features.filter((f) => f.applyMesh);\n\n // Texture cache: shared textures uploaded once, keyed by (bitmap, srgb).\n const texCache = new Map<number, Texture2D>();\n let texId = 0;\n const bitmapIds = new Map<ImageBitmap, number>();\n\n function getCachedTexture(bitmap: ImageBitmap, srgb: boolean): Texture2D {\n let id = bitmapIds.get(bitmap);\n if (id === undefined) {\n bitmapIds.set(bitmap, (id = texId++));\n }\n const key = id * 2 + +srgb;\n let tex = texCache.get(key);\n if (!tex) {\n tex = uploadTex(engine, bitmap, srgb, sampler, _generateMipmaps!);\n texCache.set(key, tex);\n }\n return tex;\n }\n\n // Per-load image fetcher for ext modules (uses same image cache as core).\n const extImageCache = matExts.length ? new Map<number, Promise<ImageBitmap>>() : null;\n const extFetchImg = extImageCache ? makeImageFetcher(json, binChunk, baseUrl, extImageCache) : null;\n const extCtx: GltfMatExtCtx = {\n _engine: engine,\n async _texture(texInfo, sRGB) {\n if (!texInfo || !extFetchImg) {\n return undefined;\n }\n const img = await extFetchImg(texInfo);\n return img ? wrapTex(getCachedTexture(img, sRGB), texInfo) : undefined;\n },\n _uploadImage(bitmap, sRGB) {\n return uploadTex(engine, bitmap, sRGB, sampler, _generateMipmaps!);\n },\n };\n\n // Slow-path trigger: per-texture UV wrapping (KHR_texture_transform)\n // or any core texture declaring texCoord=1. Scene1 stays identity→fast path.\n let _needsPbrExt = wrapTex !== identityTexWrap;\n if (!_needsPbrExt) {\n const mats = (json as { materials?: unknown[] }).materials;\n if (mats && JSON.stringify(mats).includes('\"texCoord\":1')) {\n _needsPbrExt = true;\n }\n }\n let _pbrExtPromise: Promise<typeof GltfPbrBuilderExt> | null = null;\n const _ensurePbrExt = () => (_pbrExtPromise ??= import(\"./gltf-pbr-builder-ext.js\"));\n\n /** Default ORM upload: single MR-or-occlusion image, or 1×1 fallback baked from\n * metallicFactor/roughnessFactor. The composite case (MR+occlusion separate) is\n * handled by the gltf-ext-orm extension which overrides this via `extLayers`. */\n\n // Build a PbrMaterialProps from parsed glTF material data.\n // Uses shared texture caches so identical bitmaps are uploaded once.\n const builtMaterialCache = new Map<GltfMaterialData, Promise<PbrMaterialProps>>();\n async function buildPbrFromGltfMat(mat: GltfMaterialData): Promise<PbrMaterialProps> {\n let cached = builtMaterialCache.get(mat);\n if (cached) {\n return cached;\n }\n cached = (async () => {\n const extLayers = await runMatExts(mat, matExts, extCtx);\n if (_needsPbrExt) {\n const extMod = await _ensurePbrExt();\n const tex = extMod.buildDefaultPbrTexturesExt(engine, mat, sampler, _generateMipmaps!, getCachedTexture, wrapTex, samplerFor);\n return extMod.assemblePbrPropsExt(mat, tex, extLayers);\n }\n const tex = buildSampledPbrTextures\n ? buildSampledPbrTextures(engine, mat, sampler, _generateMipmaps!, samplerFor!, getCachedTexture)\n : buildDefaultPbrTextures(engine, mat, sampler, _generateMipmaps!, getCachedTexture);\n return assemblePbrProps(mat, tex.baseColorTexture, tex.ormTexture, tex.normalTexture, tex.emissiveTexture, extLayers);\n })();\n builtMaterialCache.set(mat, cached);\n return cached;\n }\n\n const meshes = await Promise.all(\n meshDatas.map(async (m, i): Promise<Mesh> => {\n const material = await buildPbrFromGltfMat(m._material);\n const meshName = json.meshes[json.nodes[m._nodeIndex].mesh].name;\n\n // Interleaved meshes are fully built by the dynamic module (kept out of\n // this bundle for non-interleaved scenes). The tight path below is\n // byte-identical to the non-interleaved engine.\n let mesh: Mesh;\n if (m._vb) {\n mesh = (await loadInterleave()).buildInterleavedMesh(engine, m, i, material, meshName) as Mesh;\n } else {\n const [boundMin, boundMax] = computeAabb(m._positions!, m._worldMatrix);\n const gpu: MeshGPU = {\n positionBuffer: createMappedBuffer(engine, m._positions!, BU.VERTEX),\n normalBuffer: createMappedBuffer(engine, m._normals!, BU.VERTEX),\n tangentBuffer: m._tangents ? createMappedBuffer(engine, m._tangents, BU.VERTEX) : null,\n uvBuffer: createMappedBuffer(engine, m._uvs!, BU.VERTEX),\n uv2Buffer: m._uv2s ? createMappedBuffer(engine, m._uv2s, BU.VERTEX) : null,\n colorBuffer: m._colors ? createMappedBuffer(engine, m._colors, BU.VERTEX) : null,\n indexBuffer: createMappedBuffer(engine, m._indices, BU.INDEX),\n indexCount: m._indexCount,\n indexFormat: (m._indices instanceof U32 ? \"uint32\" : \"uint16\") as GPUIndexFormat,\n };\n\n mesh = {\n name: meshName || `gltf_mesh_${i}`,\n material,\n receiveShadows: false,\n boundMin,\n boundMax,\n skeleton: null,\n morphTargets: null,\n _gpu: gpu,\n _flatNormal: m._flatNormal,\n } as unknown as Mesh;\n initMeshTransform(mesh);\n\n // Retain CPU geometry for detailed picking.\n mesh._cpuPositions = m._positions!;\n mesh._cpuNormals = m._normals!;\n mesh._cpuUvs = m._uvs!;\n mesh._cpuIndices = m._indices instanceof U32 ? m._indices : new U32(m._indices);\n engine._dlr?.m(mesh, m._uv2s, m._tangents, m._colors, m._indices, gpu.indexFormat);\n }\n\n // Run all per-mesh feature hooks (skeleton, morph, …) in parallel.\n // Each hook mutates `mesh` directly (e.g. attaches mesh.skeleton).\n if (meshFeatures.length > 0) {\n await Promise.all(meshFeatures.map((f) => f.applyMesh!(m, mesh, ctx)));\n }\n\n return mesh;\n })\n );\n\n return meshes;\n}\n"],"names":["tex"],"mappings":"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"}
|
|
@@ -7,11 +7,15 @@ function rebuildMaterial(scene, materialOrView, options) {
|
|
|
7
7
|
for (const mesh of scene.meshes) {
|
|
8
8
|
if (matchesMaterial(mesh.material, source, materialOrView, rebuildViews)) {
|
|
9
9
|
rebuildSceneMesh(scene, mesh);
|
|
10
|
+
if (mesh.material) {
|
|
11
|
+
mesh.material._csmGen = (mesh.material._csmGen ?? 0) + 1;
|
|
12
|
+
}
|
|
10
13
|
changed = true;
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
16
|
if (changed) {
|
|
14
17
|
scene._renderableVersion++;
|
|
18
|
+
scene._materialEpoch++;
|
|
15
19
|
}
|
|
16
20
|
if (options?.rebuildFrameGraph) {
|
|
17
21
|
scene._frameGraph.build();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material-rebuild.js","sources":["../../../src/material/material-rebuild.ts"],"sourcesContent":["import type { SceneContext } from \"../scene/scene.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { Material } from \"./material.js\";\nimport { getMaterialSource, isMaterialView } from \"./material-view.js\";\n\nexport interface RebuildMaterialOptions {\n /** Rebuild views created from the same source material. Defaults to true. */\n rebuildViews?: boolean;\n /** Rebuild the frame graph after material renderables are refreshed. Defaults to false so callers can batch updates. */\n rebuildFrameGraph?: boolean;\n}\n\n/** Rebuild renderables whose pipeline/bind-group feature state depends on a material.\n * Use after texture, sampler, bind-group layout, culling, or feature changes.\n * UBO-only scalar/vector changes should use markMaterialUboDirty instead. */\nexport function rebuildMaterial(scene: SceneContext, materialOrView: Material, options?: RebuildMaterialOptions): void {\n const source = getMaterialSource(materialOrView);\n const rebuildViews = options?.rebuildViews !== false;\n let changed = false;\n\n for (const mesh of scene.meshes) {\n if (matchesMaterial(mesh.material, source, materialOrView, rebuildViews)) {\n rebuildSceneMesh(scene, mesh);\n changed = true;\n }\n }\n\n if (changed) {\n scene._renderableVersion++;\n }\n if (options?.rebuildFrameGraph) {\n scene._frameGraph.build();\n }\n}\n\nfunction matchesMaterial(meshMaterial: Material | null, source: Material, materialOrView: Material, rebuildViews: boolean): boolean {\n if (!meshMaterial) {\n return false;\n }\n if (!rebuildViews) {\n return meshMaterial === materialOrView;\n }\n return meshMaterial === source || (isMaterialView(meshMaterial) && meshMaterial.source === source);\n}\n\nfunction rebuildSceneMesh(ctx: SceneContext, mesh: Mesh): void {\n const material = mesh.material;\n if (!material) {\n return;\n }\n const rebuild = material._buildGroup._rebuildSingle;\n if (!rebuild) {\n return;\n }\n const old = ctx._meshDisposables.get(mesh);\n if (old) {\n for (const fn of old) {\n fn();\n }\n ctx._meshDisposables.delete(mesh);\n }\n for (let i = ctx._renderables.length - 1; i >= 0; i--) {\n if (ctx._renderables[i]!.mesh === mesh) {\n ctx._renderables.splice(i, 1);\n }\n }\n const renderable = rebuild(ctx, mesh);\n let i = ctx._renderables.length;\n while (i > 0 && ctx._renderables[i - 1]!.order > renderable.order) {\n i--;\n }\n ctx._renderables.splice(i, 0, renderable);\n}\n"],"names":["i"],"mappings":";;AAeO,SAAS,eAAA,CAAgB,KAAA,EAAqB,cAAA,EAA0B,OAAA,EAAwC;AACnH,EAAA,MAAM,MAAA,GAAS,kBAAkB,cAAc,CAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,SAAS,YAAA,KAAiB,KAAA;AAC/C,EAAA,IAAI,OAAA,GAAU,KAAA;AAEd,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,MAAA,EAAQ;AAC7B,IAAA,IAAI,gBAAgB,IAAA,CAAK,QAAA,EAAU,MAAA,EAAQ,cAAA,EAAgB,YAAY,CAAA,EAAG;AACtE,MAAA,gBAAA,CAAiB,OAAO,IAAI,CAAA;AAC5B,MAAA,OAAA,GAAU,IAAA;AAAA,IACd;AAAA,EACJ;AAEA,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,KAAA,CAAM,kBAAA,EAAA;AAAA,EACV;AACA,EAAA,IAAI,SAAS,iBAAA,EAAmB;AAC5B,IAAA,KAAA,CAAM,YAAY,KAAA,EAAM;AAAA,EAC5B;AACJ;AAEA,SAAS,eAAA,CAAgB,YAAA,EAA+B,MAAA,EAAkB,cAAA,EAA0B,YAAA,EAAgC;AAChI,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAO,KAAA;AAAA,EACX;AACA,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAO,YAAA,KAAiB,cAAA;AAAA,EAC5B;AACA,EAAA,OAAO,iBAAiB,MAAA,IAAW,cAAA,CAAe,YAAY,CAAA,IAAK,aAAa,MAAA,KAAW,MAAA;AAC/F;AAEA,SAAS,gBAAA,CAAiB,KAAmB,IAAA,EAAkB;AAC3D,EAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,OAAA,GAAU,SAAS,WAAA,CAAY,cAAA;AACrC,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA;AACzC,EAAA,IAAI,GAAA,EAAK;AACL,IAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AAClB,MAAA,EAAA,EAAG;AAAA,IACP;AACA,IAAA,GAAA,CAAI,gBAAA,CAAiB,OAAO,IAAI,CAAA;AAAA,EACpC;AACA,EAAA,KAAA,IAASA,KAAI,GAAA,CAAI,YAAA,CAAa,SAAS,CAAA,EAAGA,EAAAA,IAAK,GAAGA,EAAAA,EAAAA,EAAK;AACnD,IAAA,IAAI,GAAA,CAAI,YAAA,CAAaA,EAAC,CAAA,CAAG,SAAS,IAAA,EAAM;AACpC,MAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAOA,EAAAA,EAAG,CAAC,CAAA;AAAA,IAChC;AAAA,EACJ;AACA,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAA;AACpC,EAAA,IAAI,CAAA,GAAI,IAAI,YAAA,CAAa,MAAA;AACzB,EAAA,OAAO,CAAA,GAAI,KAAK,GAAA,CAAI,YAAA,CAAa,IAAI,CAAC,CAAA,CAAG,KAAA,GAAQ,UAAA,CAAW,KAAA,EAAO;AAC/D,IAAA,CAAA,EAAA;AAAA,EACJ;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAC5C;;;;"}
|
|
1
|
+
{"version":3,"file":"material-rebuild.js","sources":["../../../src/material/material-rebuild.ts"],"sourcesContent":["import type { SceneContext } from \"../scene/scene.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { Material } from \"./material.js\";\nimport { getMaterialSource, isMaterialView } from \"./material-view.js\";\n\nexport interface RebuildMaterialOptions {\n /** Rebuild views created from the same source material. Defaults to true. */\n rebuildViews?: boolean;\n /** Rebuild the frame graph after material renderables are refreshed. Defaults to false so callers can batch updates. */\n rebuildFrameGraph?: boolean;\n}\n\n/** Rebuild renderables whose pipeline/bind-group feature state depends on a material.\n * Use after texture, sampler, bind-group layout, culling, or feature changes.\n * UBO-only scalar/vector changes should use markMaterialUboDirty instead. */\nexport function rebuildMaterial(scene: SceneContext, materialOrView: Material, options?: RebuildMaterialOptions): void {\n const source = getMaterialSource(materialOrView);\n const rebuildViews = options?.rebuildViews !== false;\n let changed = false;\n\n for (const mesh of scene.meshes) {\n if (matchesMaterial(mesh.material, source, materialOrView, rebuildViews)) {\n rebuildSceneMesh(scene, mesh);\n if (mesh.material) {\n // Per-material generation (twin of scene-material-swap): lets the CSM detect when a CASTER's own\n // material was rebuilt — and ONLY then rebuild its shadow views — instead of on the global epoch.\n (mesh.material as { _csmGen?: number })._csmGen = ((mesh.material as { _csmGen?: number })._csmGen ?? 0) + 1;\n }\n changed = true;\n }\n }\n\n if (changed) {\n scene._renderableVersion++;\n scene._materialEpoch++; // material renderables (and their UBOs) were rebuilt → bump the material epoch\n }\n if (options?.rebuildFrameGraph) {\n scene._frameGraph.build();\n }\n}\n\nfunction matchesMaterial(meshMaterial: Material | null, source: Material, materialOrView: Material, rebuildViews: boolean): boolean {\n if (!meshMaterial) {\n return false;\n }\n if (!rebuildViews) {\n return meshMaterial === materialOrView;\n }\n return meshMaterial === source || (isMaterialView(meshMaterial) && meshMaterial.source === source);\n}\n\nfunction rebuildSceneMesh(ctx: SceneContext, mesh: Mesh): void {\n const material = mesh.material;\n if (!material) {\n return;\n }\n const rebuild = material._buildGroup._rebuildSingle;\n if (!rebuild) {\n return;\n }\n const old = ctx._meshDisposables.get(mesh);\n if (old) {\n for (const fn of old) {\n fn();\n }\n ctx._meshDisposables.delete(mesh);\n }\n for (let i = ctx._renderables.length - 1; i >= 0; i--) {\n if (ctx._renderables[i]!.mesh === mesh) {\n ctx._renderables.splice(i, 1);\n }\n }\n const renderable = rebuild(ctx, mesh);\n let i = ctx._renderables.length;\n while (i > 0 && ctx._renderables[i - 1]!.order > renderable.order) {\n i--;\n }\n ctx._renderables.splice(i, 0, renderable);\n}\n"],"names":["i"],"mappings":";;AAeO,SAAS,eAAA,CAAgB,KAAA,EAAqB,cAAA,EAA0B,OAAA,EAAwC;AACnH,EAAA,MAAM,MAAA,GAAS,kBAAkB,cAAc,CAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,SAAS,YAAA,KAAiB,KAAA;AAC/C,EAAA,IAAI,OAAA,GAAU,KAAA;AAEd,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,MAAA,EAAQ;AAC7B,IAAA,IAAI,gBAAgB,IAAA,CAAK,QAAA,EAAU,MAAA,EAAQ,cAAA,EAAgB,YAAY,CAAA,EAAG;AACtE,MAAA,gBAAA,CAAiB,OAAO,IAAI,CAAA;AAC5B,MAAA,IAAI,KAAK,QAAA,EAAU;AAGf,QAAC,KAAK,QAAA,CAAkC,OAAA,GAAA,CAAY,IAAA,CAAK,QAAA,CAAkC,WAAW,CAAA,IAAK,CAAA;AAAA,MAC/G;AACA,MAAA,OAAA,GAAU,IAAA;AAAA,IACd;AAAA,EACJ;AAEA,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,KAAA,CAAM,kBAAA,EAAA;AACN,IAAA,KAAA,CAAM,cAAA,EAAA;AAAA,EACV;AACA,EAAA,IAAI,SAAS,iBAAA,EAAmB;AAC5B,IAAA,KAAA,CAAM,YAAY,KAAA,EAAM;AAAA,EAC5B;AACJ;AAEA,SAAS,eAAA,CAAgB,YAAA,EAA+B,MAAA,EAAkB,cAAA,EAA0B,YAAA,EAAgC;AAChI,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAO,KAAA;AAAA,EACX;AACA,EAAA,IAAI,CAAC,YAAA,EAAc;AACf,IAAA,OAAO,YAAA,KAAiB,cAAA;AAAA,EAC5B;AACA,EAAA,OAAO,iBAAiB,MAAA,IAAW,cAAA,CAAe,YAAY,CAAA,IAAK,aAAa,MAAA,KAAW,MAAA;AAC/F;AAEA,SAAS,gBAAA,CAAiB,KAAmB,IAAA,EAAkB;AAC3D,EAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,OAAA,GAAU,SAAS,WAAA,CAAY,cAAA;AACrC,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA;AACzC,EAAA,IAAI,GAAA,EAAK;AACL,IAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AAClB,MAAA,EAAA,EAAG;AAAA,IACP;AACA,IAAA,GAAA,CAAI,gBAAA,CAAiB,OAAO,IAAI,CAAA;AAAA,EACpC;AACA,EAAA,KAAA,IAASA,KAAI,GAAA,CAAI,YAAA,CAAa,SAAS,CAAA,EAAGA,EAAAA,IAAK,GAAGA,EAAAA,EAAAA,EAAK;AACnD,IAAA,IAAI,GAAA,CAAI,YAAA,CAAaA,EAAC,CAAA,CAAG,SAAS,IAAA,EAAM;AACpC,MAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAOA,EAAAA,EAAG,CAAC,CAAA;AAAA,IAChC;AAAA,EACJ;AACA,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAA;AACpC,EAAA,IAAI,CAAA,GAAI,IAAI,YAAA,CAAa,MAAA;AACzB,EAAA,OAAO,CAAA,GAAI,KAAK,GAAA,CAAI,YAAA,CAAa,IAAI,CAAC,CAAA,CAAG,KAAA,GAAQ,UAAA,CAAW,KAAA,EAAO;AAC/D,IAAA,CAAA,EAAA;AAAA,EACJ;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAC5C;;;;"}
|
|
@@ -9,6 +9,10 @@ const MSH_HAS_UV2 = 1 << 7;
|
|
|
9
9
|
const MSH_RECEIVE_SHADOWS = 1 << 8;
|
|
10
10
|
const MSH_VAT = 1 << 9;
|
|
11
11
|
const MSH_FLAT_NORMAL = 1 << 10;
|
|
12
|
+
let _meshFeatureExtra = null;
|
|
13
|
+
function _installMeshFeatureExtra(encode) {
|
|
14
|
+
_meshFeatureExtra = encode;
|
|
15
|
+
}
|
|
12
16
|
function _computeMeshFeatures(mesh, receiveShadows = false) {
|
|
13
17
|
const gpu = mesh._gpu;
|
|
14
18
|
let features = 0;
|
|
@@ -47,8 +51,11 @@ function _computeMeshFeatures(mesh, receiveShadows = false) {
|
|
|
47
51
|
if (receiveShadows) {
|
|
48
52
|
features |= MSH_RECEIVE_SHADOWS;
|
|
49
53
|
}
|
|
54
|
+
if (_meshFeatureExtra) {
|
|
55
|
+
features |= _meshFeatureExtra(mesh);
|
|
56
|
+
}
|
|
50
57
|
return features;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
export { MSH_FLAT_NORMAL, MSH_HAS_INSTANCE_COLOR, MSH_HAS_MORPH_TARGETS, MSH_HAS_SKELETON, MSH_HAS_SKELETON_8, MSH_HAS_TANGENTS, MSH_HAS_THIN_INSTANCES, MSH_HAS_UV2, MSH_HAS_VERTEX_COLOR, MSH_RECEIVE_SHADOWS, MSH_VAT, _computeMeshFeatures };
|
|
60
|
+
export { MSH_FLAT_NORMAL, MSH_HAS_INSTANCE_COLOR, MSH_HAS_MORPH_TARGETS, MSH_HAS_SKELETON, MSH_HAS_SKELETON_8, MSH_HAS_TANGENTS, MSH_HAS_THIN_INSTANCES, MSH_HAS_UV2, MSH_HAS_VERTEX_COLOR, MSH_RECEIVE_SHADOWS, MSH_VAT, _computeMeshFeatures, _installMeshFeatureExtra };
|
|
54
61
|
//# sourceMappingURL=mesh-features.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh-features.js","sources":["../../../src/material/mesh-features.ts"],"sourcesContent":["import type { Mesh } from \"../mesh/mesh.js\";\n\nexport const MSH_HAS_TANGENTS = 1 << 0;\nexport const MSH_HAS_SKELETON = 1 << 1;\nexport const MSH_HAS_SKELETON_8 = 1 << 2;\nexport const MSH_HAS_MORPH_TARGETS = 1 << 3;\nexport const MSH_HAS_THIN_INSTANCES = 1 << 4;\nexport const MSH_HAS_INSTANCE_COLOR = 1 << 5;\nexport const MSH_HAS_VERTEX_COLOR = 1 << 6;\nexport const MSH_HAS_UV2 = 1 << 7;\nexport const MSH_RECEIVE_SHADOWS = 1 << 8;\nexport const MSH_VAT = 1 << 9;\n/** Mesh has no NORMAL attribute → must be flat-shaded (glTF spec). */\nexport const MSH_FLAT_NORMAL = 1 << 10;\n\n/** @internal Compute mesh/pass feature bits shared by material renderers. */\nexport function _computeMeshFeatures(mesh: Mesh, receiveShadows = false): number {\n const gpu = mesh._gpu;\n let features = 0;\n if (gpu.tangentBuffer) {\n features |= MSH_HAS_TANGENTS;\n }\n if (mesh.vat) {\n // Baked vertex animation: the VAT vertex path replaces live skinning (still uses the 8-bone\n // joints1 attribute flag when present), so don't also set MSH_HAS_SKELETON.\n features |= MSH_VAT;\n if (mesh.vat.joints1Buffer) {\n features |= MSH_HAS_SKELETON_8;\n }\n } else if (mesh.skeleton) {\n features |= MSH_HAS_SKELETON;\n if (mesh.skeleton.joints1Buffer) {\n features |= MSH_HAS_SKELETON_8;\n }\n }\n if (mesh.morphTargets) {\n features |= MSH_HAS_MORPH_TARGETS;\n }\n if (mesh.thinInstances) {\n features |= MSH_HAS_THIN_INSTANCES;\n if (mesh.thinInstances.colors) {\n features |= MSH_HAS_INSTANCE_COLOR;\n }\n }\n if (gpu.colorBuffer) {\n features |= MSH_HAS_VERTEX_COLOR;\n }\n if (gpu.uv2Buffer) {\n features |= MSH_HAS_UV2;\n }\n if ((mesh as { _flatNormal?: boolean })._flatNormal) {\n features |= MSH_FLAT_NORMAL;\n }\n if (receiveShadows) {\n features |= MSH_RECEIVE_SHADOWS;\n }\n return features;\n}\n"],"names":[],"mappings":"AAEO,MAAM,mBAAmB,CAAA,IAAK;AAC9B,MAAM,mBAAmB,CAAA,IAAK;AAC9B,MAAM,qBAAqB,CAAA,IAAK;AAChC,MAAM,wBAAwB,CAAA,IAAK;AACnC,MAAM,yBAAyB,CAAA,IAAK;AACpC,MAAM,yBAAyB,CAAA,IAAK;AACpC,MAAM,uBAAuB,CAAA,IAAK;AAClC,MAAM,cAAc,CAAA,IAAK;AACzB,MAAM,sBAAsB,CAAA,IAAK;AACjC,MAAM,UAAU,CAAA,IAAK;AAErB,MAAM,kBAAkB,CAAA,IAAK;
|
|
1
|
+
{"version":3,"file":"mesh-features.js","sources":["../../../src/material/mesh-features.ts"],"sourcesContent":["import type { Mesh } from \"../mesh/mesh.js\";\n\nexport const MSH_HAS_TANGENTS = 1 << 0;\nexport const MSH_HAS_SKELETON = 1 << 1;\nexport const MSH_HAS_SKELETON_8 = 1 << 2;\nexport const MSH_HAS_MORPH_TARGETS = 1 << 3;\nexport const MSH_HAS_THIN_INSTANCES = 1 << 4;\nexport const MSH_HAS_INSTANCE_COLOR = 1 << 5;\nexport const MSH_HAS_VERTEX_COLOR = 1 << 6;\nexport const MSH_HAS_UV2 = 1 << 7;\nexport const MSH_RECEIVE_SHADOWS = 1 << 8;\nexport const MSH_VAT = 1 << 9;\n/** Mesh has no NORMAL attribute → must be flat-shaded (glTF spec). */\nexport const MSH_FLAT_NORMAL = 1 << 10;\n// Bits 11-15 (negative-winding + 3-bit topology index + uint32-strip flag) are owned by the lazy\n// glTF primitive feature: their constants live in pbr-primitive-resolver.ts and are encoded via the\n// `_meshFeatureExtra` hook below, so triangle-list positive-winding scenes never bundle that code.\n\n/** Extra mesh-feature encoder, installed only by the glTF primitive feature (topology +\n * negative-winding bits). Module-local with a single exported setter: when no such mesh is in the\n * bundle the setter tree-shakes, the bundler proves this is always null, and the `_meshFeatureExtra`\n * call below folds away — every common mesh keeps `_computeMeshFeatures` byte-identical. */\nlet _meshFeatureExtra: ((mesh: Mesh) => number) | null = null;\n/** @internal Install the extra mesh-feature encoder (called by the glTF primitive feature). */\nexport function _installMeshFeatureExtra(encode: (mesh: Mesh) => number): void {\n _meshFeatureExtra = encode;\n}\n\n/** @internal Compute mesh/pass feature bits shared by material renderers. */\nexport function _computeMeshFeatures(mesh: Mesh, receiveShadows = false): number {\n const gpu = mesh._gpu;\n let features = 0;\n if (gpu.tangentBuffer) {\n features |= MSH_HAS_TANGENTS;\n }\n if (mesh.vat) {\n // Baked vertex animation: the VAT vertex path replaces live skinning (still uses the 8-bone\n // joints1 attribute flag when present), so don't also set MSH_HAS_SKELETON.\n features |= MSH_VAT;\n if (mesh.vat.joints1Buffer) {\n features |= MSH_HAS_SKELETON_8;\n }\n } else if (mesh.skeleton) {\n features |= MSH_HAS_SKELETON;\n if (mesh.skeleton.joints1Buffer) {\n features |= MSH_HAS_SKELETON_8;\n }\n }\n if (mesh.morphTargets) {\n features |= MSH_HAS_MORPH_TARGETS;\n }\n if (mesh.thinInstances) {\n features |= MSH_HAS_THIN_INSTANCES;\n if (mesh.thinInstances.colors) {\n features |= MSH_HAS_INSTANCE_COLOR;\n }\n }\n if (gpu.colorBuffer) {\n features |= MSH_HAS_VERTEX_COLOR;\n }\n if (gpu.uv2Buffer) {\n features |= MSH_HAS_UV2;\n }\n if ((mesh as { _flatNormal?: boolean })._flatNormal) {\n features |= MSH_FLAT_NORMAL;\n }\n if (receiveShadows) {\n features |= MSH_RECEIVE_SHADOWS;\n }\n if (_meshFeatureExtra) {\n features |= _meshFeatureExtra(mesh);\n }\n return features;\n}\n"],"names":[],"mappings":"AAEO,MAAM,mBAAmB,CAAA,IAAK;AAC9B,MAAM,mBAAmB,CAAA,IAAK;AAC9B,MAAM,qBAAqB,CAAA,IAAK;AAChC,MAAM,wBAAwB,CAAA,IAAK;AACnC,MAAM,yBAAyB,CAAA,IAAK;AACpC,MAAM,yBAAyB,CAAA,IAAK;AACpC,MAAM,uBAAuB,CAAA,IAAK;AAClC,MAAM,cAAc,CAAA,IAAK;AACzB,MAAM,sBAAsB,CAAA,IAAK;AACjC,MAAM,UAAU,CAAA,IAAK;AAErB,MAAM,kBAAkB,CAAA,IAAK;AASpC,IAAI,iBAAA,GAAqD,IAAA;AAElD,SAAS,yBAAyB,MAAA,EAAsC;AAC3E,EAAA,iBAAA,GAAoB,MAAA;AACxB;AAGO,SAAS,oBAAA,CAAqB,IAAA,EAAY,cAAA,GAAiB,KAAA,EAAe;AAC7E,EAAA,MAAM,MAAM,IAAA,CAAK,IAAA;AACjB,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,IAAI,IAAI,aAAA,EAAe;AACnB,IAAA,QAAA,IAAY,gBAAA;AAAA,EAChB;AACA,EAAA,IAAI,KAAK,GAAA,EAAK;AAGV,IAAA,QAAA,IAAY,OAAA;AACZ,IAAA,IAAI,IAAA,CAAK,IAAI,aAAA,EAAe;AACxB,MAAA,QAAA,IAAY,kBAAA;AAAA,IAChB;AAAA,EACJ,CAAA,MAAA,IAAW,KAAK,QAAA,EAAU;AACtB,IAAA,QAAA,IAAY,gBAAA;AACZ,IAAA,IAAI,IAAA,CAAK,SAAS,aAAA,EAAe;AAC7B,MAAA,QAAA,IAAY,kBAAA;AAAA,IAChB;AAAA,EACJ;AACA,EAAA,IAAI,KAAK,YAAA,EAAc;AACnB,IAAA,QAAA,IAAY,qBAAA;AAAA,EAChB;AACA,EAAA,IAAI,KAAK,aAAA,EAAe;AACpB,IAAA,QAAA,IAAY,sBAAA;AACZ,IAAA,IAAI,IAAA,CAAK,cAAc,MAAA,EAAQ;AAC3B,MAAA,QAAA,IAAY,sBAAA;AAAA,IAChB;AAAA,EACJ;AACA,EAAA,IAAI,IAAI,WAAA,EAAa;AACjB,IAAA,QAAA,IAAY,oBAAA;AAAA,EAChB;AACA,EAAA,IAAI,IAAI,SAAA,EAAW;AACf,IAAA,QAAA,IAAY,WAAA;AAAA,EAChB;AACA,EAAA,IAAK,KAAmC,WAAA,EAAa;AACjD,IAAA,QAAA,IAAY,eAAA;AAAA,EAChB;AACA,EAAA,IAAI,cAAA,EAAgB;AAChB,IAAA,QAAA,IAAY,mBAAA;AAAA,EAChB;AACA,EAAA,IAAI,iBAAA,EAAmB;AACnB,IAAA,QAAA,IAAY,kBAAkB,IAAI,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,QAAA;AACX;;;;"}
|
|
@@ -134,7 +134,7 @@ const pbrExt = {
|
|
|
134
134
|
const hasNonDefaultF0 = m.metallicF0Factor != null && Math.abs(m.metallicF0Factor - 1) > 1e-6;
|
|
135
135
|
const mrc = m.metallicReflectanceColor;
|
|
136
136
|
const hasNonDefaultColor = mrc != null && (mrc[0] !== 1 || mrc[1] !== 1 || mrc[2] !== 1);
|
|
137
|
-
if (hasNonDefaultF0 || hasNonDefaultColor) {
|
|
137
|
+
if (hasNonDefaultF0 || hasNonDefaultColor || m._occlStrengthAnimated) {
|
|
138
138
|
f2 |= PBR2_HAS_REFLECTANCE_FACTORS;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reflectance-fragment.js","sources":["../../../../../src/material/pbr/fragments/reflectance-fragment.ts"],"sourcesContent":["/**\n * Metallic Reflectance Fragment\n *\n * Advanced F0 computation with metallicReflectanceTexture and/or reflectanceTexture.\n * Only bundled when a scene uses these textures.\n *\n * Provides: UBO fields (occlusionStrength, metallicF0Factor, specularWeight, metallicReflectanceColor),\n * conditional texture bindings, F0 computation, and occlusion handling.\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP, PBR_HAS_USE_ALPHA_ONLY_MR, PBR2_HAS_REFLECTANCE_FACTORS, PBR2_HAS_UV2 } from \"../pbr-flag-bits.js\";\n\n// Reflectance-only features2 bit (reserved in pbr-flag-bits.ts). Defined here,\n// not in the shared flag module, for zero bundle movement on scenes that never\n// load this lazy fragment.\nconst PBR2_REFL_UV_TX = 1 << 26;\n\n// WebGPU shader stage constants\nconst STAGE_FRAGMENT = 0x2;\n\nconst reflUvExpr = (name: string): string => `(vec2<f32>(dot(material.${name}m.xy, input.uv), dot(material.${name}m.zw, input.uv)) + material.${name}t.xy)`;\n\n/** Write a 2x2 UV matrix (vec4) + translate (vec4) for a reflectance texture. */\nfunction writeReflUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const mi = mOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n const ti = tOff / 4;\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n}\n\n/** Write the reflectance-extension material-UBO slice\n * (occlusionStrength, metallicF0Factor, specularWeight, metallicReflectanceColor).\n * Gated by the presence of the `occlusionStrength` field in the UBO spec,\n * which is added only when a metallic-reflectance or reflectance texture\n * is in use. */\nexport function writeReflectanceUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n if (!offsets.has(\"occlusionStrength\")) {\n return;\n }\n const off = offsets.get(\"occlusionStrength\")! / 4;\n data[off] = material.occlusionStrength ?? 1.0;\n data[off + 1] = material.metallicF0Factor ?? 1.0;\n data[off + 2] = material.specularWeight ?? material.metallicF0Factor ?? 1.0;\n const mrc = material.metallicReflectanceColor;\n data[off + 4] = mrc ? mrc[0]! : 1.0;\n data[off + 5] = mrc ? mrc[1]! : 1.0;\n data[off + 6] = mrc ? mrc[2]! : 1.0;\n\n writeReflUvTransform(data, offsets, \"reflUV\", material.reflectanceTexture);\n writeReflUvTransform(data, offsets, \"mrReflUV\", material.metallicReflectanceTexture);\n}\n\n/**\n * Create a metallic reflectance fragment.\n * @param hasMetallicReflectanceMap - Whether the material has a metallicReflectanceTexture.\n * @param hasReflectanceMap - Whether the material has a reflectanceTexture.\n * @param useAlphaOnlyMR - Whether to use only the alpha channel from the metallic reflectance map.\n */\nexport function createReflectanceFragment(\n hasMetallicReflectanceMap: boolean,\n hasReflectanceMap: boolean,\n useAlphaOnlyMR: boolean,\n hasOcclusionUv2: boolean = false,\n hasUvTx: boolean = false\n): ShaderFragment {\n const bindings: BindingDecl[] = [];\n if (hasMetallicReflectanceMap) {\n bindings.push(\n { _name: \"metallicReflectanceMap\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"metallicReflectanceMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasReflectanceMap) {\n bindings.push(\n { _name: \"reflectanceMap\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"reflectanceMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const reflUv = hasUvTx ? reflUvExpr(\"reflUV\") : \"input.uv\";\n const mrReflUv = hasUvTx ? reflUvExpr(\"mrReflUV\") : \"input.uv\";\n\n // Build F0 computation code\n let f0Code = `var mrFactors = vec4<f32>(material.metallicReflectanceColor, material.metallicF0Factor);\nvar specularWeight = material.specularWeight;`;\n if (hasReflectanceMap) {\n f0Code += `\n{ let rSample = textureSample(reflectanceMap, reflectanceMapSampler, ${reflUv});\n let rLinear = pow(rSample.rgb, vec3<f32>(2.2));\n mrFactors = vec4<f32>(mrFactors.rgb * rLinear, mrFactors.a); }`;\n }\n if (hasMetallicReflectanceMap) {\n if (!useAlphaOnlyMR) {\n f0Code += `\n{ let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv});\n let mrLinear = pow(mrSample.rgb, vec3<f32>(2.2));\n mrFactors = vec4<f32>(mrFactors.rgb * mrLinear, mrFactors.a * mrSample.a);\n specularWeight *= mrSample.a; }`;\n } else {\n f0Code += `\n{ let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv});\n mrFactors = vec4<f32>(mrFactors.rgb, mrFactors.a * mrSample.a);\n specularWeight *= mrSample.a; }`;\n }\n }\n f0Code += `\nlet dielectricF0 = material.reflectance * mrFactors.a;\nlet surfaceReflectivityColor = mrFactors.rgb;\nlet dielectricColorF0 = vec3<f32>(dielectricF0) * surfaceReflectivityColor;\nlet metallicColorF0 = baseColor;\nvar colorF0 = mix(dielectricColorF0, metallicColorF0, metallic);\nlet colorF90 = vec3<f32>(mix(specularWeight, 1.0, metallic));\nlet surfaceAlbedo = baseColor * (vec3<f32>(1.0) - vec3<f32>(dielectricF0) * surfaceReflectivityColor) * (1.0 - metallic);`;\n\n const uboFields: UboField[] = [\n { _name: \"occlusionStrength\", _type: \"f32\" },\n { _name: \"metallicF0Factor\", _type: \"f32\" },\n { _name: \"specularWeight\", _type: \"f32\" },\n { _name: \"_mrPad1\", _type: \"f32\" },\n { _name: \"metallicReflectanceColor\", _type: \"vec3<f32>\" },\n { _name: \"_mrPad2\", _type: \"f32\" },\n ];\n if (hasUvTx) {\n if (hasReflectanceMap) {\n uboFields.push({ _name: \"reflUVm\", _type: \"vec4<f32>\" }, { _name: \"reflUVt\", _type: \"vec4<f32>\" });\n }\n if (hasMetallicReflectanceMap) {\n uboFields.push({ _name: \"mrReflUVm\", _type: \"vec4<f32>\" }, { _name: \"mrReflUVt\", _type: \"vec4<f32>\" });\n }\n }\n\n return {\n _id: hasUvTx ? \"reflectance-U\" : \"reflectance\",\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _fragmentSlots: {\n MF: f0Code,\n AT: hasOcclusionUv2\n ? `let occlusion = mix(1.0, textureSample(occlusionTexture, occlusionSampler_, input.uv2).r, material.occlusionStrength);`\n : `let occlusion = mix(1.0, orm.r, material.occlusionStrength);`,\n },\n };\n}\n\n/** Create the reflectance PBR extension (group 1, fragment phase). */\nexport const pbrExt: PbrExt = {\n id: \"reflectance\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as PbrMaterialProps;\n let f = 0;\n let f2 = 0;\n if (m.metallicReflectanceTexture) {\n f |= PBR_HAS_METALLIC_REFLECTANCE_MAP;\n }\n if (m.reflectanceTexture) {\n f |= PBR_HAS_REFLECTANCE_MAP;\n }\n if (f === 0) {\n const hasNonDefaultF0 = m.metallicF0Factor != null && Math.abs(m.metallicF0Factor - 1) > 1e-6;\n const mrc = m.metallicReflectanceColor;\n const hasNonDefaultColor = mrc != null && (mrc[0] !== 1 || mrc[1] !== 1 || mrc[2] !== 1);\n if (hasNonDefaultF0 || hasNonDefaultColor) {\n f2 |= PBR2_HAS_REFLECTANCE_FACTORS;\n }\n }\n if ((f !== 0 || f2 & PBR2_HAS_REFLECTANCE_FACTORS) && m.useOnlyMetallicFromMetallicReflectanceTexture) {\n f |= PBR_HAS_USE_ALPHA_ONLY_MR;\n }\n const refHasTx = (t: { _hasTx?: boolean } | undefined): boolean => !!t?._hasTx;\n if (f !== 0 && (refHasTx(m.reflectanceTexture as { _hasTx?: boolean } | undefined) || refHasTx(m.metallicReflectanceTexture as { _hasTx?: boolean } | undefined))) {\n f2 |= PBR2_REFL_UV_TX;\n }\n return { f, f2 };\n },\n frag(ctx) {\n const hasMR = (ctx._features & PBR_HAS_METALLIC_REFLECTANCE_MAP) !== 0;\n const hasR = (ctx._features & PBR_HAS_REFLECTANCE_MAP) !== 0;\n const hasFactors = (ctx._features2 & PBR2_HAS_REFLECTANCE_FACTORS) !== 0;\n if (!hasMR && !hasR && !hasFactors) {\n return null;\n }\n return createReflectanceFragment(\n hasMR,\n hasR,\n (ctx._features & PBR_HAS_USE_ALPHA_ONLY_MR) !== 0,\n (ctx._features2 & PBR2_HAS_UV2) !== 0,\n (ctx._features2 & PBR2_REFL_UV_TX) !== 0\n );\n },\n writeUbo: writeReflectanceUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n if ((ctx._features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) === 0) {\n return b;\n }\n const m = ctx._material as PbrMaterialProps;\n if (m.metallicReflectanceTexture) {\n entries.push({ binding: b++, resource: m.metallicReflectanceTexture.view });\n entries.push({ binding: b++, resource: m.metallicReflectanceTexture.sampler });\n }\n if (m.reflectanceTexture) {\n entries.push({ binding: b++, resource: m.reflectanceTexture.view });\n entries.push({ binding: b++, resource: m.reflectanceTexture.sampler });\n }\n return b;\n },\n textures(mat, t) {\n const m = mat as PbrMaterialProps;\n if (m.metallicReflectanceTexture) {\n t.push(m.metallicReflectanceTexture);\n }\n if (m.reflectanceTexture) {\n t.push(m.reflectanceTexture);\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reflectance-fragment.js","sources":["../../../../../src/material/pbr/fragments/reflectance-fragment.ts"],"sourcesContent":["/**\n * Metallic Reflectance Fragment\n *\n * Advanced F0 computation with metallicReflectanceTexture and/or reflectanceTexture.\n * Only bundled when a scene uses these textures.\n *\n * Provides: UBO fields (occlusionStrength, metallicF0Factor, specularWeight, metallicReflectanceColor),\n * conditional texture bindings, F0 computation, and occlusion handling.\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_METALLIC_REFLECTANCE_MAP, PBR_HAS_REFLECTANCE_MAP, PBR_HAS_USE_ALPHA_ONLY_MR, PBR2_HAS_REFLECTANCE_FACTORS, PBR2_HAS_UV2 } from \"../pbr-flag-bits.js\";\n\n// Reflectance-only features2 bit (reserved in pbr-flag-bits.ts). Defined here,\n// not in the shared flag module, for zero bundle movement on scenes that never\n// load this lazy fragment.\nconst PBR2_REFL_UV_TX = 1 << 26;\n\n// WebGPU shader stage constants\nconst STAGE_FRAGMENT = 0x2;\n\nconst reflUvExpr = (name: string): string => `(vec2<f32>(dot(material.${name}m.xy, input.uv), dot(material.${name}m.zw, input.uv)) + material.${name}t.xy)`;\n\n/** Write a 2x2 UV matrix (vec4) + translate (vec4) for a reflectance texture. */\nfunction writeReflUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const mi = mOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n const ti = tOff / 4;\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n}\n\n/** Write the reflectance-extension material-UBO slice\n * (occlusionStrength, metallicF0Factor, specularWeight, metallicReflectanceColor).\n * Gated by the presence of the `occlusionStrength` field in the UBO spec,\n * which is added only when a metallic-reflectance or reflectance texture\n * is in use. */\nexport function writeReflectanceUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n if (!offsets.has(\"occlusionStrength\")) {\n return;\n }\n const off = offsets.get(\"occlusionStrength\")! / 4;\n data[off] = material.occlusionStrength ?? 1.0;\n data[off + 1] = material.metallicF0Factor ?? 1.0;\n data[off + 2] = material.specularWeight ?? material.metallicF0Factor ?? 1.0;\n const mrc = material.metallicReflectanceColor;\n data[off + 4] = mrc ? mrc[0]! : 1.0;\n data[off + 5] = mrc ? mrc[1]! : 1.0;\n data[off + 6] = mrc ? mrc[2]! : 1.0;\n\n writeReflUvTransform(data, offsets, \"reflUV\", material.reflectanceTexture);\n writeReflUvTransform(data, offsets, \"mrReflUV\", material.metallicReflectanceTexture);\n}\n\n/**\n * Create a metallic reflectance fragment.\n * @param hasMetallicReflectanceMap - Whether the material has a metallicReflectanceTexture.\n * @param hasReflectanceMap - Whether the material has a reflectanceTexture.\n * @param useAlphaOnlyMR - Whether to use only the alpha channel from the metallic reflectance map.\n */\nexport function createReflectanceFragment(\n hasMetallicReflectanceMap: boolean,\n hasReflectanceMap: boolean,\n useAlphaOnlyMR: boolean,\n hasOcclusionUv2: boolean = false,\n hasUvTx: boolean = false\n): ShaderFragment {\n const bindings: BindingDecl[] = [];\n if (hasMetallicReflectanceMap) {\n bindings.push(\n { _name: \"metallicReflectanceMap\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"metallicReflectanceMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n if (hasReflectanceMap) {\n bindings.push(\n { _name: \"reflectanceMap\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"reflectanceMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const reflUv = hasUvTx ? reflUvExpr(\"reflUV\") : \"input.uv\";\n const mrReflUv = hasUvTx ? reflUvExpr(\"mrReflUV\") : \"input.uv\";\n\n // Build F0 computation code\n let f0Code = `var mrFactors = vec4<f32>(material.metallicReflectanceColor, material.metallicF0Factor);\nvar specularWeight = material.specularWeight;`;\n if (hasReflectanceMap) {\n f0Code += `\n{ let rSample = textureSample(reflectanceMap, reflectanceMapSampler, ${reflUv});\n let rLinear = pow(rSample.rgb, vec3<f32>(2.2));\n mrFactors = vec4<f32>(mrFactors.rgb * rLinear, mrFactors.a); }`;\n }\n if (hasMetallicReflectanceMap) {\n if (!useAlphaOnlyMR) {\n f0Code += `\n{ let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv});\n let mrLinear = pow(mrSample.rgb, vec3<f32>(2.2));\n mrFactors = vec4<f32>(mrFactors.rgb * mrLinear, mrFactors.a * mrSample.a);\n specularWeight *= mrSample.a; }`;\n } else {\n f0Code += `\n{ let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv});\n mrFactors = vec4<f32>(mrFactors.rgb, mrFactors.a * mrSample.a);\n specularWeight *= mrSample.a; }`;\n }\n }\n f0Code += `\nlet dielectricF0 = material.reflectance * mrFactors.a;\nlet surfaceReflectivityColor = mrFactors.rgb;\nlet dielectricColorF0 = vec3<f32>(dielectricF0) * surfaceReflectivityColor;\nlet metallicColorF0 = baseColor;\nvar colorF0 = mix(dielectricColorF0, metallicColorF0, metallic);\nlet colorF90 = vec3<f32>(mix(specularWeight, 1.0, metallic));\nlet surfaceAlbedo = baseColor * (vec3<f32>(1.0) - vec3<f32>(dielectricF0) * surfaceReflectivityColor) * (1.0 - metallic);`;\n\n const uboFields: UboField[] = [\n { _name: \"occlusionStrength\", _type: \"f32\" },\n { _name: \"metallicF0Factor\", _type: \"f32\" },\n { _name: \"specularWeight\", _type: \"f32\" },\n { _name: \"_mrPad1\", _type: \"f32\" },\n { _name: \"metallicReflectanceColor\", _type: \"vec3<f32>\" },\n { _name: \"_mrPad2\", _type: \"f32\" },\n ];\n if (hasUvTx) {\n if (hasReflectanceMap) {\n uboFields.push({ _name: \"reflUVm\", _type: \"vec4<f32>\" }, { _name: \"reflUVt\", _type: \"vec4<f32>\" });\n }\n if (hasMetallicReflectanceMap) {\n uboFields.push({ _name: \"mrReflUVm\", _type: \"vec4<f32>\" }, { _name: \"mrReflUVt\", _type: \"vec4<f32>\" });\n }\n }\n\n return {\n _id: hasUvTx ? \"reflectance-U\" : \"reflectance\",\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _fragmentSlots: {\n MF: f0Code,\n AT: hasOcclusionUv2\n ? `let occlusion = mix(1.0, textureSample(occlusionTexture, occlusionSampler_, input.uv2).r, material.occlusionStrength);`\n : `let occlusion = mix(1.0, orm.r, material.occlusionStrength);`,\n },\n };\n}\n\n/** Create the reflectance PBR extension (group 1, fragment phase). */\nexport const pbrExt: PbrExt = {\n id: \"reflectance\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as PbrMaterialProps;\n let f = 0;\n let f2 = 0;\n if (m.metallicReflectanceTexture) {\n f |= PBR_HAS_METALLIC_REFLECTANCE_MAP;\n }\n if (m.reflectanceTexture) {\n f |= PBR_HAS_REFLECTANCE_MAP;\n }\n if (f === 0) {\n const hasNonDefaultF0 = m.metallicF0Factor != null && Math.abs(m.metallicF0Factor - 1) > 1e-6;\n const mrc = m.metallicReflectanceColor;\n const hasNonDefaultColor = mrc != null && (mrc[0] !== 1 || mrc[1] !== 1 || mrc[2] !== 1);\n // `_occlStrengthAnimated` (set lazily by the animation-pointer feature) routes an\n // animated occlusionTexture.strength through this ext's occlusion mix slot. Reflectance\n // factors stay default, so F0/albedo is identical to the base template path — only the\n // `mix(1, orm.r, occlusionStrength)` is added. Non-animated scenes never set the flag.\n if (hasNonDefaultF0 || hasNonDefaultColor || (m as { _occlStrengthAnimated?: boolean })._occlStrengthAnimated) {\n f2 |= PBR2_HAS_REFLECTANCE_FACTORS;\n }\n }\n if ((f !== 0 || f2 & PBR2_HAS_REFLECTANCE_FACTORS) && m.useOnlyMetallicFromMetallicReflectanceTexture) {\n f |= PBR_HAS_USE_ALPHA_ONLY_MR;\n }\n const refHasTx = (t: { _hasTx?: boolean } | undefined): boolean => !!t?._hasTx;\n if (f !== 0 && (refHasTx(m.reflectanceTexture as { _hasTx?: boolean } | undefined) || refHasTx(m.metallicReflectanceTexture as { _hasTx?: boolean } | undefined))) {\n f2 |= PBR2_REFL_UV_TX;\n }\n return { f, f2 };\n },\n frag(ctx) {\n const hasMR = (ctx._features & PBR_HAS_METALLIC_REFLECTANCE_MAP) !== 0;\n const hasR = (ctx._features & PBR_HAS_REFLECTANCE_MAP) !== 0;\n const hasFactors = (ctx._features2 & PBR2_HAS_REFLECTANCE_FACTORS) !== 0;\n if (!hasMR && !hasR && !hasFactors) {\n return null;\n }\n return createReflectanceFragment(\n hasMR,\n hasR,\n (ctx._features & PBR_HAS_USE_ALPHA_ONLY_MR) !== 0,\n (ctx._features2 & PBR2_HAS_UV2) !== 0,\n (ctx._features2 & PBR2_REFL_UV_TX) !== 0\n );\n },\n writeUbo: writeReflectanceUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n if ((ctx._features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) === 0) {\n return b;\n }\n const m = ctx._material as PbrMaterialProps;\n if (m.metallicReflectanceTexture) {\n entries.push({ binding: b++, resource: m.metallicReflectanceTexture.view });\n entries.push({ binding: b++, resource: m.metallicReflectanceTexture.sampler });\n }\n if (m.reflectanceTexture) {\n entries.push({ binding: b++, resource: m.reflectanceTexture.view });\n entries.push({ binding: b++, resource: m.reflectanceTexture.sampler });\n }\n return b;\n },\n textures(mat, t) {\n const m = mat as PbrMaterialProps;\n if (m.metallicReflectanceTexture) {\n t.push(m.metallicReflectanceTexture);\n }\n if (m.reflectanceTexture) {\n t.push(m.reflectanceTexture);\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -112,7 +112,7 @@ function writeRefractionUBO(data, mat, offsets) {
|
|
|
112
112
|
const ior = refr.indexOfRefraction ?? 1.5;
|
|
113
113
|
const thick = ss.thickness;
|
|
114
114
|
data[o + 1] = 1 / (refr.useThicknessAsDepth && thick?.max ? ior : 1);
|
|
115
|
-
data[o + 2] = refr.useThicknessAsDepth ? thick?.max ?? 0 :
|
|
115
|
+
data[o + 2] = refr.useThicknessAsDepth ? thick?.max ?? 0 : 0;
|
|
116
116
|
data[o + 3] = 1 / ior;
|
|
117
117
|
const vOff = offsets.get("volumeParams");
|
|
118
118
|
if (vOff !== void 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refraction-rtt-fragment.js","sources":["../../../../../src/material/pbr/fragments/refraction-rtt-fragment.ts"],"sourcesContent":["import type { ShaderFragment, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SubSurfaceProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { getTrilinearAnisotropicSampler } from \"../../../resource/trilinear-anisotropic-sampler.js\";\nimport {\n PBR_HAS_THICKNESS_MAP,\n PBR2_HAS_DISPERSION,\n PBR2_HAS_REFRACTION,\n PBR2_HAS_REFRACTION_MAP,\n PBR2_HAS_THICKNESS_GLTF_CHANNEL,\n PBR2_HAS_VOLUME,\n PBR2_LINEAR_IMAGE_PROCESSING,\n} from \"../pbr-flag-bits.js\";\n\ntype TransmissionMat = PbrMaterialProps & { _linearImageProcessing?: boolean };\nconst LINEAR_IMAGE_PROCESSING_SLOTS = { NI: `if(scene.vImageInfos.w>=0.0){`, BC: `}` };\n\nfunction makeRefractionMod(\n hasVolume: boolean,\n hasMap: boolean,\n hasThicknessMap: boolean,\n useGltfThicknessChannel: boolean,\n hasDispersion: boolean,\n dispersionSampleWgsl: string | undefined\n): string {\n const thicknessScaleLine = hasVolume || hasThicknessMap ? `let ts=max(length(mesh.world[0].xyz),max(length(mesh.world[1].xyz),length(mesh.world[2].xyz)));` : ``;\n const mapUvDecl = hasMap\n ? `let refractionMapUV=vec2<f32>(dot(material.refractionMapUVm.xy,input.uv),dot(material.refractionMapUVm.zw,input.uv))+material.refractionMapUVt.xy;\\n`\n : ``;\n const thickUvDecl = hasThicknessMap\n ? `let thicknessUV=vec2<f32>(dot(material.thicknessUVm.xy,input.uv),dot(material.thicknessUVm.zw,input.uv))+material.thicknessUVt.xy;\\n`\n : ``;\n const thicknessLine = hasThicknessMap\n ? `let ths=textureSample(thicknessTexture_,thicknessSampler_,thicknessUV).${useGltfThicknessChannel ? \"g\" : \"r\"};\nlet th=(material.thicknessParams.x+ths*material.thicknessParams.y)*ts;`\n : hasVolume\n ? `let th=material.refractionParams.z*ts;`\n : `let th=material.refractionParams.z;`;\n const textureLine = hasMap\n ? `let ri=material.refractionParams.x*textureSample(refractionMapTexture,refractionMapSampler,refractionMapUV).r;`\n : `let ri=material.refractionParams.x;`;\n const absorptionLine = hasVolume ? `let ab=exp(material.volumeParams.rgb*th);` : ``;\n const refractionLine = hasVolume\n ? `let fr=er*surfaceAlbedo*(ri*ab)*(vec3<f32>(1.0)-colorSpecularEnvReflectance.rgb);`\n : `let fr=er*surfaceAlbedo*ri*(vec3<f32>(1.0)-colorSpecularEnvReflectance.rgb);`;\n\n // Refracted environment sample. Dispersion splits the refracted ray into\n // per-RGB index-of-refraction offsets (chromatic aberration); that 3-ray WGSL\n // is injected from a dynamically-imported module (see refraction-dispersion-wgsl.ts)\n // so non-dispersion transmission scenes keep the lean single-ray path below.\n const sampleLines =\n hasDispersion && dispersionSampleWgsl\n ? dispersionSampleWgsl\n : `let rd=refract(-V,N,material.refractionParams.y);\nlet cp=scene.viewProjection*vec4<f32>(input.worldPos+rd*th,1.0);\nlet ruv=(cp.xy/cp.w)*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5,0.5);\nlet er=textureSampleLevel(refractionTexture,refractionSampler_,ruv,lv).rgb*material.environmentIntensity;`;\n\n return `{\n${thicknessScaleLine}\n${mapUvDecl}${thickUvDecl}${textureLine}\n${thicknessLine}\nlet ro=1.0-ri;\nlet ra=mix(alphaG,0.0,clamp(material.refractionParams.w*3.0-2.0,0.0,1.0));\nlet lv=clamp(log2(f32(textureDimensions(refractionTexture).x)*ra)-4.0,0.0,f32(textureNumLevels(refractionTexture)-1));\n${sampleLines}\n${absorptionLine}\n${refractionLine}\ncolor=finalIrradiance*ro*ro+finalRadianceScaled+finalSpecularScaled+directDiffuse*ro*ro+fr+emissive;\n}`;\n}\n\nfunction createRefractionRttFragment(\n hasVolume: boolean,\n hasMap: boolean,\n hasThicknessMap: boolean,\n useGltfThicknessChannel: boolean,\n linearImageProcessing: boolean,\n hasDispersion: boolean,\n dispersionSampleWgsl: string | undefined\n): ShaderFragment {\n const uboFields: UboField[] = [{ _name: \"refractionParams\", _type: \"vec4<f32>\" as const }];\n if (hasVolume) {\n uboFields.push({ _name: \"volumeParams\", _type: \"vec4<f32>\" as const });\n }\n if (hasThicknessMap) {\n uboFields.push({ _name: \"thicknessParams\", _type: \"vec4<f32>\" as const });\n }\n // Per-texture UV transforms (KHR_texture_transform on transmissionTexture / thicknessTexture),\n // animatable via KHR_animation_pointer. Emitted whenever the map is present; identity when the\n // texture carries no transform (sample at input.uv), so non-transformed scenes are unchanged.\n if (hasMap) {\n uboFields.push({ _name: \"refractionMapUVm\", _type: \"vec4<f32>\" as const }, { _name: \"refractionMapUVt\", _type: \"vec4<f32>\" as const });\n }\n if (hasThicknessMap) {\n uboFields.push({ _name: \"thicknessUVm\", _type: \"vec4<f32>\" as const }, { _name: \"thicknessUVt\", _type: \"vec4<f32>\" as const });\n }\n const bindings = [\n { _name: \"refractionTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"refractionSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 },\n ];\n if (hasMap) {\n bindings.push(\n { _name: \"refractionMapTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"refractionMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 }\n );\n }\n if (hasThicknessMap) {\n bindings.push(\n { _name: \"thicknessTexture_\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"thicknessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 }\n );\n }\n return {\n _id: \"refraction\",\n _dependencies: [\"ibl\"],\n _uboFields: uboFields,\n _bindings: bindings,\n _fragmentSlots: linearImageProcessing\n ? { AI: makeRefractionMod(hasVolume, hasMap, hasThicknessMap, useGltfThicknessChannel, hasDispersion, dispersionSampleWgsl), ...LINEAR_IMAGE_PROCESSING_SLOTS }\n : { AI: makeRefractionMod(hasVolume, hasMap, hasThicknessMap, useGltfThicknessChannel, hasDispersion, dispersionSampleWgsl) },\n };\n}\n\nfunction writeRefractionUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const mi = mOff / 4;\n const ti = tOff / 4;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nfunction writeRefractionUBO(data: Float32Array, mat: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const ss = mat.subsurface as SubSurfaceProps | undefined;\n const refr = ss?.refraction;\n if (!refr) {\n return;\n }\n const off = offsets.get(\"refractionParams\");\n if (off === undefined) {\n return;\n }\n const o = off / 4;\n data[o] = refr.intensity ?? 0;\n const ior = refr.indexOfRefraction ?? 1.5;\n const thick = ss!.thickness;\n data[o + 1] = 1.0 / (refr.useThicknessAsDepth && thick?.max ? ior : 1.0);\n data[o + 2] = refr.useThicknessAsDepth ? (thick?.max ?? 0.0) : 1.0;\n data[o + 3] = 1.0 / ior;\n\n const vOff = offsets.get(\"volumeParams\");\n if (vOff !== undefined) {\n const vo = vOff / 4;\n const tint = ss!.tint?.color ?? [1, 1, 1];\n const dist = Math.max(ss!.tint?.atDistance ?? 1, 0.0001);\n data[vo] = Math.log(Math.max(tint[0]!, 1e-6)) / dist;\n data[vo + 1] = Math.log(Math.max(tint[1]!, 1e-6)) / dist;\n data[vo + 2] = Math.log(Math.max(tint[2]!, 1e-6)) / dist;\n // w carries the chromatic dispersion strength (0 when no KHR_materials_dispersion).\n data[vo + 3] = refr.dispersion ?? 0;\n }\n\n const tOff = offsets.get(\"thicknessParams\");\n if (tOff !== undefined) {\n const to = tOff / 4;\n const min = thick?.min ?? 0;\n const max = thick?.max ?? 1;\n data[to] = min;\n data[to + 1] = max - min;\n }\n\n writeRefractionUvTransform(data, offsets, \"refractionMapUV\", refr.texture);\n writeRefractionUvTransform(data, offsets, \"thicknessUV\", thick?.texture);\n}\n\n/** Build the PBR refraction/transmission extension. When the scene contains a\n * dispersive material, `dispersionSampleWgsl` carries the per-RGB 3-ray sample\n * WGSL (dynamically imported, scene-isolated); otherwise it is undefined and the\n * lean single-ray refraction path is emitted. */\nexport function makeRefractionRttExt(dispersionSampleWgsl?: string): PbrExt {\n return {\n id: \"refraction\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as TransmissionMat;\n const ss = m.subsurface as SubSurfaceProps | undefined;\n const refr = ss?.refraction;\n const linearImageProcessing = m._linearImageProcessing ? PBR2_LINEAR_IMAGE_PROCESSING : 0;\n const intensity = m.transmissive ? (refr?.intensity ?? 0) : 0;\n if (intensity <= 0) {\n return { f: 0, f2: linearImageProcessing };\n }\n let f = 0;\n let f2 = linearImageProcessing | PBR2_HAS_REFRACTION;\n if (refr?.texture) {\n f2 |= PBR2_HAS_REFRACTION_MAP;\n }\n if (ss?.thickness?.texture) {\n f |= PBR_HAS_THICKNESS_MAP;\n }\n if (ss?.thickness?.useGlTFChannel) {\n f2 |= PBR2_HAS_THICKNESS_GLTF_CHANNEL;\n }\n if (ss?.tint?.atDistance !== undefined) {\n f2 |= PBR2_HAS_VOLUME;\n // Dispersion requires the volume path (per-channel etas + volumeParams.w storage).\n if (refr?.dispersion) {\n f2 |= PBR2_HAS_DISPERSION;\n }\n }\n return { f, f2 };\n },\n frag(ctx) {\n const linearImageProcessing = (ctx._features2 & PBR2_LINEAR_IMAGE_PROCESSING) !== 0;\n if (!(ctx._features2 & PBR2_HAS_REFRACTION)) {\n return linearImageProcessing ? { _id: \"linear\", _fragmentSlots: LINEAR_IMAGE_PROCESSING_SLOTS } : null;\n }\n return createRefractionRttFragment(\n (ctx._features2 & PBR2_HAS_VOLUME) !== 0,\n (ctx._features2 & PBR2_HAS_REFRACTION_MAP) !== 0,\n (ctx._features & PBR_HAS_THICKNESS_MAP) !== 0,\n (ctx._features2 & PBR2_HAS_THICKNESS_GLTF_CHANNEL) !== 0,\n linearImageProcessing,\n (ctx._features2 & PBR2_HAS_DISPERSION) !== 0,\n dispersionSampleWgsl\n );\n },\n writeUbo(data, mat, offsets) {\n writeRefractionUBO(data, mat as PbrMaterialProps, offsets);\n },\n bind(ctx, entries, b) {\n if (!(ctx._features2 & PBR2_HAS_REFRACTION)) {\n return b;\n }\n const texture = ctx._refractionTexture;\n if (!texture) {\n throw new Error(\"PBR transmission requires a frame-graph refraction texture.\");\n }\n entries.push({ binding: b++, resource: texture.view });\n entries.push({ binding: b++, resource: texture.sampler });\n if ((ctx._features2 & PBR2_HAS_REFRACTION_MAP) !== 0) {\n const map = ((ctx._material as PbrMaterialProps).subsurface?.refraction as SubSurfaceProps[\"refraction\"] | undefined)?.texture!;\n entries.push({ binding: b++, resource: map.view });\n entries.push({ binding: b++, resource: getTrilinearAnisotropicSampler(ctx._engine) });\n }\n if ((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0) {\n const thickness = (ctx._material as PbrMaterialProps).subsurface?.thickness?.texture!;\n entries.push({ binding: b++, resource: thickness.view });\n entries.push({ binding: b++, resource: thickness.sampler });\n }\n return b;\n },\n textures(mat, out) {\n const tex = (mat as PbrMaterialProps).subsurface?.refraction?.texture;\n if (tex) {\n out.push(tex);\n }\n const thickness = (mat as PbrMaterialProps).subsurface?.thickness?.texture;\n if (thickness) {\n out.push(thickness);\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"refraction-rtt-fragment.js","sources":["../../../../../src/material/pbr/fragments/refraction-rtt-fragment.ts"],"sourcesContent":["import type { ShaderFragment, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SubSurfaceProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { getTrilinearAnisotropicSampler } from \"../../../resource/trilinear-anisotropic-sampler.js\";\nimport {\n PBR_HAS_THICKNESS_MAP,\n PBR2_HAS_DISPERSION,\n PBR2_HAS_REFRACTION,\n PBR2_HAS_REFRACTION_MAP,\n PBR2_HAS_THICKNESS_GLTF_CHANNEL,\n PBR2_HAS_VOLUME,\n PBR2_LINEAR_IMAGE_PROCESSING,\n} from \"../pbr-flag-bits.js\";\n\ntype TransmissionMat = PbrMaterialProps & { _linearImageProcessing?: boolean };\nconst LINEAR_IMAGE_PROCESSING_SLOTS = { NI: `if(scene.vImageInfos.w>=0.0){`, BC: `}` };\n\nfunction makeRefractionMod(\n hasVolume: boolean,\n hasMap: boolean,\n hasThicknessMap: boolean,\n useGltfThicknessChannel: boolean,\n hasDispersion: boolean,\n dispersionSampleWgsl: string | undefined\n): string {\n const thicknessScaleLine = hasVolume || hasThicknessMap ? `let ts=max(length(mesh.world[0].xyz),max(length(mesh.world[1].xyz),length(mesh.world[2].xyz)));` : ``;\n const mapUvDecl = hasMap\n ? `let refractionMapUV=vec2<f32>(dot(material.refractionMapUVm.xy,input.uv),dot(material.refractionMapUVm.zw,input.uv))+material.refractionMapUVt.xy;\\n`\n : ``;\n const thickUvDecl = hasThicknessMap\n ? `let thicknessUV=vec2<f32>(dot(material.thicknessUVm.xy,input.uv),dot(material.thicknessUVm.zw,input.uv))+material.thicknessUVt.xy;\\n`\n : ``;\n const thicknessLine = hasThicknessMap\n ? `let ths=textureSample(thicknessTexture_,thicknessSampler_,thicknessUV).${useGltfThicknessChannel ? \"g\" : \"r\"};\nlet th=(material.thicknessParams.x+ths*material.thicknessParams.y)*ts;`\n : hasVolume\n ? `let th=material.refractionParams.z*ts;`\n : `let th=material.refractionParams.z;`;\n const textureLine = hasMap\n ? `let ri=material.refractionParams.x*textureSample(refractionMapTexture,refractionMapSampler,refractionMapUV).r;`\n : `let ri=material.refractionParams.x;`;\n const absorptionLine = hasVolume ? `let ab=exp(material.volumeParams.rgb*th);` : ``;\n const refractionLine = hasVolume\n ? `let fr=er*surfaceAlbedo*(ri*ab)*(vec3<f32>(1.0)-colorSpecularEnvReflectance.rgb);`\n : `let fr=er*surfaceAlbedo*ri*(vec3<f32>(1.0)-colorSpecularEnvReflectance.rgb);`;\n\n // Refracted environment sample. Dispersion splits the refracted ray into\n // per-RGB index-of-refraction offsets (chromatic aberration); that 3-ray WGSL\n // is injected from a dynamically-imported module (see refraction-dispersion-wgsl.ts)\n // so non-dispersion transmission scenes keep the lean single-ray path below.\n const sampleLines =\n hasDispersion && dispersionSampleWgsl\n ? dispersionSampleWgsl\n : `let rd=refract(-V,N,material.refractionParams.y);\nlet cp=scene.viewProjection*vec4<f32>(input.worldPos+rd*th,1.0);\nlet ruv=(cp.xy/cp.w)*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5,0.5);\nlet er=textureSampleLevel(refractionTexture,refractionSampler_,ruv,lv).rgb*material.environmentIntensity;`;\n\n return `{\n${thicknessScaleLine}\n${mapUvDecl}${thickUvDecl}${textureLine}\n${thicknessLine}\nlet ro=1.0-ri;\nlet ra=mix(alphaG,0.0,clamp(material.refractionParams.w*3.0-2.0,0.0,1.0));\nlet lv=clamp(log2(f32(textureDimensions(refractionTexture).x)*ra)-4.0,0.0,f32(textureNumLevels(refractionTexture)-1));\n${sampleLines}\n${absorptionLine}\n${refractionLine}\ncolor=finalIrradiance*ro*ro+finalRadianceScaled+finalSpecularScaled+directDiffuse*ro*ro+fr+emissive;\n}`;\n}\n\nfunction createRefractionRttFragment(\n hasVolume: boolean,\n hasMap: boolean,\n hasThicknessMap: boolean,\n useGltfThicknessChannel: boolean,\n linearImageProcessing: boolean,\n hasDispersion: boolean,\n dispersionSampleWgsl: string | undefined\n): ShaderFragment {\n const uboFields: UboField[] = [{ _name: \"refractionParams\", _type: \"vec4<f32>\" as const }];\n if (hasVolume) {\n uboFields.push({ _name: \"volumeParams\", _type: \"vec4<f32>\" as const });\n }\n if (hasThicknessMap) {\n uboFields.push({ _name: \"thicknessParams\", _type: \"vec4<f32>\" as const });\n }\n // Per-texture UV transforms (KHR_texture_transform on transmissionTexture / thicknessTexture),\n // animatable via KHR_animation_pointer. Emitted whenever the map is present; identity when the\n // texture carries no transform (sample at input.uv), so non-transformed scenes are unchanged.\n if (hasMap) {\n uboFields.push({ _name: \"refractionMapUVm\", _type: \"vec4<f32>\" as const }, { _name: \"refractionMapUVt\", _type: \"vec4<f32>\" as const });\n }\n if (hasThicknessMap) {\n uboFields.push({ _name: \"thicknessUVm\", _type: \"vec4<f32>\" as const }, { _name: \"thicknessUVt\", _type: \"vec4<f32>\" as const });\n }\n const bindings = [\n { _name: \"refractionTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"refractionSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 },\n ];\n if (hasMap) {\n bindings.push(\n { _name: \"refractionMapTexture\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"refractionMapSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 }\n );\n }\n if (hasThicknessMap) {\n bindings.push(\n { _name: \"thicknessTexture_\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" } as const, _visibility: 2 },\n { _name: \"thicknessSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" } as const, _visibility: 2 }\n );\n }\n return {\n _id: \"refraction\",\n _dependencies: [\"ibl\"],\n _uboFields: uboFields,\n _bindings: bindings,\n _fragmentSlots: linearImageProcessing\n ? { AI: makeRefractionMod(hasVolume, hasMap, hasThicknessMap, useGltfThicknessChannel, hasDispersion, dispersionSampleWgsl), ...LINEAR_IMAGE_PROCESSING_SLOTS }\n : { AI: makeRefractionMod(hasVolume, hasMap, hasThicknessMap, useGltfThicknessChannel, hasDispersion, dispersionSampleWgsl) },\n };\n}\n\nfunction writeRefractionUvTransform(\n data: Float32Array,\n offsets: ReadonlyMap<string, number>,\n name: string,\n tex: { uScale?: number; vScale?: number; uAng?: number; uOffset?: number; vOffset?: number } | undefined\n): void {\n const mOff = offsets.get(`${name}m`);\n const tOff = offsets.get(`${name}t`);\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const mi = mOff / 4;\n const ti = tOff / 4;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = s * sy;\n data[mi + 2] = -s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = tex?.uOffset ?? 0;\n data[ti + 1] = tex?.vOffset ?? 0;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nfunction writeRefractionUBO(data: Float32Array, mat: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const ss = mat.subsurface as SubSurfaceProps | undefined;\n const refr = ss?.refraction;\n if (!refr) {\n return;\n }\n const off = offsets.get(\"refractionParams\");\n if (off === undefined) {\n return;\n }\n const o = off / 4;\n data[o] = refr.intensity ?? 0;\n const ior = refr.indexOfRefraction ?? 1.5;\n const thick = ss!.thickness;\n data[o + 1] = 1.0 / (refr.useThicknessAsDepth && thick?.max ? ior : 1.0);\n data[o + 2] = refr.useThicknessAsDepth ? (thick?.max ?? 0.0) : 0.0;\n data[o + 3] = 1.0 / ior;\n\n const vOff = offsets.get(\"volumeParams\");\n if (vOff !== undefined) {\n const vo = vOff / 4;\n const tint = ss!.tint?.color ?? [1, 1, 1];\n const dist = Math.max(ss!.tint?.atDistance ?? 1, 0.0001);\n data[vo] = Math.log(Math.max(tint[0]!, 1e-6)) / dist;\n data[vo + 1] = Math.log(Math.max(tint[1]!, 1e-6)) / dist;\n data[vo + 2] = Math.log(Math.max(tint[2]!, 1e-6)) / dist;\n // w carries the chromatic dispersion strength (0 when no KHR_materials_dispersion).\n data[vo + 3] = refr.dispersion ?? 0;\n }\n\n const tOff = offsets.get(\"thicknessParams\");\n if (tOff !== undefined) {\n const to = tOff / 4;\n const min = thick?.min ?? 0;\n const max = thick?.max ?? 1;\n data[to] = min;\n data[to + 1] = max - min;\n }\n\n writeRefractionUvTransform(data, offsets, \"refractionMapUV\", refr.texture);\n writeRefractionUvTransform(data, offsets, \"thicknessUV\", thick?.texture);\n}\n\n/** Build the PBR refraction/transmission extension. When the scene contains a\n * dispersive material, `dispersionSampleWgsl` carries the per-RGB 3-ray sample\n * WGSL (dynamically imported, scene-isolated); otherwise it is undefined and the\n * lean single-ray refraction path is emitted. */\nexport function makeRefractionRttExt(dispersionSampleWgsl?: string): PbrExt {\n return {\n id: \"refraction\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as TransmissionMat;\n const ss = m.subsurface as SubSurfaceProps | undefined;\n const refr = ss?.refraction;\n const linearImageProcessing = m._linearImageProcessing ? PBR2_LINEAR_IMAGE_PROCESSING : 0;\n const intensity = m.transmissive ? (refr?.intensity ?? 0) : 0;\n if (intensity <= 0) {\n return { f: 0, f2: linearImageProcessing };\n }\n let f = 0;\n let f2 = linearImageProcessing | PBR2_HAS_REFRACTION;\n if (refr?.texture) {\n f2 |= PBR2_HAS_REFRACTION_MAP;\n }\n if (ss?.thickness?.texture) {\n f |= PBR_HAS_THICKNESS_MAP;\n }\n if (ss?.thickness?.useGlTFChannel) {\n f2 |= PBR2_HAS_THICKNESS_GLTF_CHANNEL;\n }\n if (ss?.tint?.atDistance !== undefined) {\n f2 |= PBR2_HAS_VOLUME;\n // Dispersion requires the volume path (per-channel etas + volumeParams.w storage).\n if (refr?.dispersion) {\n f2 |= PBR2_HAS_DISPERSION;\n }\n }\n return { f, f2 };\n },\n frag(ctx) {\n const linearImageProcessing = (ctx._features2 & PBR2_LINEAR_IMAGE_PROCESSING) !== 0;\n if (!(ctx._features2 & PBR2_HAS_REFRACTION)) {\n return linearImageProcessing ? { _id: \"linear\", _fragmentSlots: LINEAR_IMAGE_PROCESSING_SLOTS } : null;\n }\n return createRefractionRttFragment(\n (ctx._features2 & PBR2_HAS_VOLUME) !== 0,\n (ctx._features2 & PBR2_HAS_REFRACTION_MAP) !== 0,\n (ctx._features & PBR_HAS_THICKNESS_MAP) !== 0,\n (ctx._features2 & PBR2_HAS_THICKNESS_GLTF_CHANNEL) !== 0,\n linearImageProcessing,\n (ctx._features2 & PBR2_HAS_DISPERSION) !== 0,\n dispersionSampleWgsl\n );\n },\n writeUbo(data, mat, offsets) {\n writeRefractionUBO(data, mat as PbrMaterialProps, offsets);\n },\n bind(ctx, entries, b) {\n if (!(ctx._features2 & PBR2_HAS_REFRACTION)) {\n return b;\n }\n const texture = ctx._refractionTexture;\n if (!texture) {\n throw new Error(\"PBR transmission requires a frame-graph refraction texture.\");\n }\n entries.push({ binding: b++, resource: texture.view });\n entries.push({ binding: b++, resource: texture.sampler });\n if ((ctx._features2 & PBR2_HAS_REFRACTION_MAP) !== 0) {\n const map = ((ctx._material as PbrMaterialProps).subsurface?.refraction as SubSurfaceProps[\"refraction\"] | undefined)?.texture!;\n entries.push({ binding: b++, resource: map.view });\n entries.push({ binding: b++, resource: getTrilinearAnisotropicSampler(ctx._engine) });\n }\n if ((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0) {\n const thickness = (ctx._material as PbrMaterialProps).subsurface?.thickness?.texture!;\n entries.push({ binding: b++, resource: thickness.view });\n entries.push({ binding: b++, resource: thickness.sampler });\n }\n return b;\n },\n textures(mat, out) {\n const tex = (mat as PbrMaterialProps).subsurface?.refraction?.texture;\n if (tex) {\n out.push(tex);\n }\n const thickness = (mat as PbrMaterialProps).subsurface?.thickness?.texture;\n if (thickness) {\n out.push(thickness);\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,10 @@ let _pbrFallbackResolver = null;
|
|
|
13
13
|
function _installPbrFallbackResolver(resolve) {
|
|
14
14
|
_pbrFallbackResolver = resolve;
|
|
15
15
|
}
|
|
16
|
+
let _primitiveResolver = null;
|
|
17
|
+
function _installPbrPrimitiveResolver(resolve) {
|
|
18
|
+
_primitiveResolver = resolve;
|
|
19
|
+
}
|
|
16
20
|
const _bindingsCache = /* @__PURE__ */ new Map();
|
|
17
21
|
let _cachedDevice = null;
|
|
18
22
|
function ensureDevice(engine) {
|
|
@@ -62,7 +66,7 @@ function getOrCreatePbrPipeline(engine, sig, bindings) {
|
|
|
62
66
|
return cached;
|
|
63
67
|
}
|
|
64
68
|
const device = engine._device;
|
|
65
|
-
const { _features: features, _features2: features2, _composed: composed } = bindings;
|
|
69
|
+
const { _features: features, _features2: features2, _composed: composed, _meshFeatures: meshFeatures } = bindings;
|
|
66
70
|
const esmShadowOutput = (features2 & PBR2_ESM_SHADOW_OUTPUT) !== 0;
|
|
67
71
|
const hasAlpha = !esmShadowOutput && (features & PBR_HAS_ALPHA_BLEND) !== 0;
|
|
68
72
|
const hasDoubleSided = (features & PBR_HAS_DOUBLE_SIDED) !== 0;
|
|
@@ -95,7 +99,7 @@ function getOrCreatePbrPipeline(engine, sig, bindings) {
|
|
|
95
99
|
}
|
|
96
100
|
} : {},
|
|
97
101
|
multisample: { count: sig._sampleCount },
|
|
98
|
-
primitive: { topology: "triangle-list", cullMode: hasDoubleSided ? "none" : "back", frontFace: "ccw" }
|
|
102
|
+
primitive: _primitiveResolver ? _primitiveResolver(meshFeatures, hasDoubleSided) : { topology: "triangle-list", cullMode: hasDoubleSided ? "none" : "back", frontFace: "ccw" }
|
|
99
103
|
});
|
|
100
104
|
bindings._pipelines.set(key, pipeline);
|
|
101
105
|
return pipeline;
|
|
@@ -168,5 +172,5 @@ function createPbrMeshBindGroup(engine, bindings, composed, meshUBO, materialUBO
|
|
|
168
172
|
return device.createBindGroup({ layout: bindings._meshBGL, entries });
|
|
169
173
|
}
|
|
170
174
|
|
|
171
|
-
export { _installPbrFallbackResolver, _installPbrStencilResolver, clearPbrPipelineCache, createPbrMeshBindGroup, getOrCreatePbrBindings, getOrCreatePbrPipeline };
|
|
175
|
+
export { _installPbrFallbackResolver, _installPbrPrimitiveResolver, _installPbrStencilResolver, clearPbrPipelineCache, createPbrMeshBindGroup, getOrCreatePbrBindings, getOrCreatePbrPipeline };
|
|
172
176
|
//# sourceMappingURL=pbr-pipeline.js.map
|