@babylonjs/lite 1.4.0 → 1.5.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 +381 -375
- package/dist/index.js.map +1 -1
- package/index.d.ts +757 -0
- 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/engine/engine.js +1 -1
- package/lib/index.js +11 -0
- 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/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/sprite-2d.js +4 -0
- package/lib/sprite/sprite-2d.js.map +1 -1
- package/lib/sprite/sprite-pipeline.js +25 -22
- package/lib/sprite/sprite-pipeline.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":"pbr-renderable.js","sources":["../../../../src/material/pbr/pbr-renderable.ts"],"sourcesContent":["/** PBR mesh renderable — builds Renderables from glTF PBR meshes + environment.\n *\n * `buildPbrRenderables` does shared per-scene setup (extension/fragment imports,\n * shader composer, scene bind group, multi-light UBO), then delegates per-mesh\n * work to `buildSinglePbrRenderable`. Both initial build and material-swap\n * rebuilds go through the same single-mesh function. */\n\nimport { F32 } from \"../../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Mesh } from \"../../mesh/mesh.js\";\nimport type { PbrMaterialProps } from \"./pbr-material.js\";\nimport { collectPbrBoundTextures } from \"./pbr-material.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\n\nimport type { Renderable, MeshGroupBuildResult } from \"../../render/renderable.js\";\nimport type { ShaderFragment } from \"../../shader/fragment-types.js\";\nimport { acquireTexture, releaseTexture, clearSamplerCache } from \"../../resource/gpu-pool.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { getOrCreatePbrBindings, getOrCreatePbrPipeline, createPbrMeshBindGroup, clearPbrPipelineCache } from \"./pbr-pipeline.js\";\nimport {\n _registerPbrExt,\n _getPbrExts,\n PBR_HAS_NORMAL_MAP,\n PBR_HAS_ALPHA_BLEND,\n PBR2_NO_COLOR_OUTPUT,\n PBR2_HAS_REFRACTION,\n PBR2_HAS_UV2,\n PBR_HAS_ENV,\n PBR_HAS_TONEMAP,\n PBR_HAS_FOG,\n PBR2_ESM_SHADOW_OUTPUT,\n} from \"./pbr-flags.js\";\nimport type { PbrExt } from \"./pbr-flags.js\";\nimport { createPbrComposer } from \"./pbr-compose.js\";\nimport { _computePbrMaterialFeatures } from \"./pbr-material.js\";\nimport type { ShadowGenerator } from \"../../shadow/shadow-generator.js\";\nimport type { ThinInstanceData } from \"../../mesh/thin-instance.js\";\nimport type { PbrShadowLightSlot } from \"./fragments/pbr-shadow-fragment.js\";\nimport { writeMeshLightSelection } from \"../../render/lights-ubo.js\";\nimport type { PbrLightMode } from \"./pbr-compose.js\";\nimport type { Material, MaterialRenderFeatures } from \"../material.js\";\nimport { _computeMeshFeatures, MSH_HAS_INSTANCE_COLOR, MSH_HAS_THIN_INSTANCES, MSH_HAS_UV2, MSH_HAS_VERTEX_COLOR } from \"../mesh-features.js\";\nimport { packMat4IntoF32 } from \"../../math/pack-mat4-into-f32.js\";\n\ntype SingleLightType = \"hemispheric\" | \"directional\" | \"spot\" | \"point\";\ninterface SingleLightWgslModule {\n SINGLE_LIGHT_STRUCTS: string;\n getSingleLightBlock(): string;\n}\n\n/** Build PBR Renderable(s) + a SceneUniformUpdater from PBR meshes. */\nexport async function buildPbrRenderables(scene: SceneContext, meshes: Mesh[], envTextures: EnvironmentTextures | undefined): Promise<MeshGroupBuildResult> {\n const engine = scene.surface.engine;\n const device = engine._device;\n // Per-size scratch buffers for material UBO re-writes (zero allocation per frame).\n const materialScratch = new Map<number, Float32Array>();\n const hasEnv = !!envTextures;\n const shadowLights: { lightIndex: number; shadowType: \"esm\" | \"pcf\" | \"csm\"; gen: ShadowGenerator }[] = [];\n for (let i = 0; i < scene.lights.length; i++) {\n const sg = scene.lights[i]!.shadowGenerator;\n if (sg) {\n shadowLights.push({ lightIndex: i, shadowType: sg._shadowType, gen: sg });\n }\n }\n const hasSomeShadows = shadowLights.length > 0;\n let hasAnyAffectedLight = false;\n let needsSingleLightPath = false;\n let needsMultiLightPath = false;\n const singleLightTypes: SingleLightType[] = [];\n for (const mesh of meshes) {\n const lr = writeMeshLightSelection(mesh, scene.lights);\n const affectedCount = lr > 0 ? 1 : -lr;\n hasAnyAffectedLight ||= affectedCount > 0;\n if (affectedCount === 1 && !(mesh.receiveShadows && hasSomeShadows)) {\n needsSingleLightPath = true;\n const type = getPackedSingleLightType(scene.lights, lr - 1);\n if (!singleLightTypes.includes(type)) {\n singleLightTypes.push(type);\n }\n } else if (affectedCount > 0) {\n needsMultiLightPath = true;\n }\n }\n\n // ── Single O(N) scan over meshes for all scene-wide feature flags ──\n // Flags are plain locals (not an object return) so terser can mangle their names.\n // Replaces ~11 sequential meshes.some() loops (was O(11N)).\n let hasSkybox = false;\n let hasMetallicReflectance = false;\n let hasClearcoat = false;\n let hasSheen = false;\n let hasIridescence = false;\n let hasAnyAnisotropy = false;\n let hasAnySubsurface = false;\n let hasAlphaTest = false;\n let hasTransmissionRefraction = false;\n let needsEmissiveColor = false;\n let hasSomeSkeletons = false;\n let hasSomeMorphs = false;\n let hasSomeThinInstances = false;\n let hasCullingTI = false;\n let hasAnyUnlit = false;\n let hasAnyUvTransform = false;\n let hasAnyUv2 = false;\n let hasAnyVertexColor = false;\n let hasAnyFlatNormal = false;\n for (let i = 0; i < meshes.length; i++) {\n const m = meshes[i]!;\n const mat = m.material as PbrMaterialProps & { _hasReflExt?: boolean; _hasUvTx?: boolean };\n const refractionIntensity = mat.subsurface?.refraction?.intensity ?? 0;\n hasSkybox ||= !!mat.skyboxMode;\n hasMetallicReflectance ||= !!(mat.metallicReflectanceTexture || mat.reflectanceTexture || mat._hasReflExt);\n hasClearcoat ||= !!mat.clearCoat?.isEnabled;\n hasSheen ||= !!mat.sheen?.isEnabled;\n hasIridescence ||= !!mat.iridescence?.isEnabled;\n hasAnyAnisotropy ||= !!mat.anisotropy?.isEnabled;\n hasAnySubsurface ||= !!mat.subsurface?.translucency;\n hasAlphaTest ||= mat.alphaCutOff! > 0;\n hasTransmissionRefraction ||= refractionIntensity > 0 && !!mat.transmissive;\n needsEmissiveColor ||= !!mat.emissiveColor;\n hasSomeSkeletons ||= !!m.skeleton;\n hasSomeMorphs ||= !!m.morphTargets;\n hasSomeThinInstances ||= !!m.thinInstances;\n hasCullingTI ||= !!m.thinInstances?._gpuCullingEnabled;\n hasAnyUnlit ||= !!mat.unlit;\n hasAnyUvTransform ||= !!mat._hasUvTx;\n // UV2 only counts when occlusion samples texcoord 1.\n hasAnyUv2 ||= !!m._gpu.uv2Buffer && mat.occlusionTexCoord === 1;\n hasAnyVertexColor ||= !!m._gpu.colorBuffer;\n hasAnyFlatNormal ||= !!(m as { _flatNormal?: boolean })._flatNormal;\n }\n\n // ── Dynamically import fragment creators based on scene capabilities ──\n\n // IBL fragment.\n let _iblSkyboxCalc = \"\";\n if (hasEnv) {\n const mod = await import(\"./fragments/ibl-fragment.js\");\n _registerPbrExt(mod.pbrExt);\n if (hasSkybox) {\n // Skybox-mode WGSL is only loaded when at least one mesh in the scene needs it.\n const sky = await import(\"./fragments/ibl-skybox-wgsl.js\");\n _iblSkyboxCalc = sky.IBL_SKYBOX_CALCULATION;\n }\n }\n\n // Flat-normal WGSL is only loaded when at least one mesh lacks a NORMAL attribute\n // (glTF flat-shading) — normal-having scenes bundle zero bytes.\n let _flatNormalWgsl = \"\";\n if (hasAnyFlatNormal) {\n const flatNormal = await import(\"./fragments/flat-normal-wgsl.js\");\n _flatNormalWgsl = flatNormal.FLAT_NORMAL_WGSL;\n }\n\n // Light/shadow helpers stay dynamic so single-light and non-shadow bundles stay lean.\n let _createPbrShadowFragment: ((slots: PbrShadowLightSlot[]) => ShaderFragment) | null = null;\n let _singleLightWGSL = \"\";\n let _getSingleLightBlock: ((type: string) => string) | null = null;\n const singleLightBlocks: Partial<Record<SingleLightType, () => string>> = {};\n let _multiLightWGSL = \"\";\n let _multiLightLoop = \"\";\n if (needsSingleLightPath) {\n for (const type of singleLightTypes) {\n const single = await importSingleLightWgsl(type);\n _singleLightWGSL = single.SINGLE_LIGHT_STRUCTS;\n singleLightBlocks[type] = single.getSingleLightBlock;\n }\n _getSingleLightBlock = (type) => singleLightBlocks[toSingleLightType(type)]?.() ?? \"\";\n }\n if (needsMultiLightPath) {\n const wgslMod = await import(\"./fragments/multilight-wgsl.js\");\n _multiLightWGSL = wgslMod.MULTI_LIGHT_STRUCTS() + wgslMod.COMPUTE_PBR_LIGHT;\n _multiLightLoop = wgslMod.getMultiLightLoop();\n }\n if (hasAnyAffectedLight && hasSomeShadows) {\n const shadowMod = await import(\"./fragments/pbr-shadow-fragment.js\");\n _createPbrShadowFragment = shadowMod.createPbrShadowFragment;\n }\n\n // ── Per-mesh fragment creators (imported if any mesh needs them) ──\n // Each optional PBR fragment module exports a uniform `pbrExt`, so registration\n // collapses to a single data-driven loop over [flag, loader] pairs. The `import()`\n // specifiers stay literal (required for Vite code-splitting) and the shared\n // `_registerPbrExt((await load()).pbrExt)` glue is emitted once instead of per\n // feature, keeping this management layer small as features are added.\n // Registration order is the iteration order consumed by `_getPbrExts().values()`\n // on the hot paths (composePbr, writeMaterialData, collectPbrBoundTextures).\n type PbrExtLoad = () => Promise<{ pbrExt: PbrExt }>;\n const _drainPbrExts = async (loaders: Array<readonly [boolean, PbrExtLoad]>) => {\n for (const [flag, load] of loaders) {\n if (flag) {\n _registerPbrExt((await load()).pbrExt);\n }\n }\n };\n\n await _drainPbrExts([\n [hasAlphaTest, () => import(\"./fragments/alpha-test-fragment.js\")],\n [hasMetallicReflectance, () => import(\"./fragments/reflectance-fragment.js\")],\n [hasClearcoat, () => import(\"./fragments/clearcoat-fragment.js\")],\n [hasSheen, () => import(\"./fragments/sheen-fragment.js\")],\n [hasIridescence, () => import(\"./fragments/iridescence-fragment.js\")],\n [hasAnySubsurface, () => import(\"./fragments/subsurface-fragment.js\")],\n ]);\n if (hasTransmissionRefraction) {\n const mod = await import(\"./pbr-refraction.js\");\n await mod.registerPbrRefraction(scene as SceneContext, engine, _registerPbrExt);\n }\n await _drainPbrExts([\n [needsEmissiveColor, () => import(\"./fragments/emissive-fragment.js\")],\n [hasAnyUnlit, () => import(\"./fragments/unlit-fragment.js\")],\n [hasSomeSkeletons, () => import(\"./fragments/skeleton-fragment.js\")],\n [hasSomeMorphs, () => import(\"./fragments/morph-fragment.js\")],\n [hasAnyUvTransform, () => import(\"./fragments/uv-transform-fragment.js\")],\n ]);\n\n // Anisotropy needs its module reference retained (for ANISO_BRDF_FUNCTIONS /\n // makeAnisotropyTBBlock / ANISO_DIRECT_DG / ANISO_BENT_NORMAL strings consumed\n // by the template below), so it keeps the full module binding.\n let _anisoExt: typeof import(\"./fragments/anisotropy-fragment.js\") | null = null;\n if (hasAnyAnisotropy) {\n _anisoExt = await import(\"./fragments/anisotropy-fragment.js\");\n _registerPbrExt(_anisoExt.pbrExt);\n }\n\n // Lazy-load pbr-template-ext when any advanced features are present.\n // Scene1 has none of these, so it won't pay the ~1.5KB cost.\n let _createPbrTemplateExt: typeof import(\"./pbr-template-ext.js\").createPbrTemplateExt | null = null;\n if (hasAnyUvTransform || hasAnyVertexColor || hasAnyUv2) {\n const extMod = await import(\"./pbr-template-ext.js\");\n _createPbrTemplateExt = extMod.createPbrTemplateExt;\n }\n\n let _createThinInstanceFragment: ((hasColor: boolean) => ShaderFragment) | null = null;\n let _syncThinInstanceBuffers:\n | ((\n engine: EngineContext,\n ti: ThinInstanceData,\n pass: GPURenderPassEncoder | GPURenderBundleEncoder,\n slot: number,\n hasColor: boolean,\n drawBuffers?: import(\"../../mesh/thin-instance-gpu.js\").ThinInstanceDrawBuffers | null\n ) => number)\n | null = null;\n let _cull: typeof import(\"../../mesh/thin-instance-cull-binding.js\") | undefined;\n // Per-frame thin-instance matrix/color UPLOAD (no pass — just writeBuffer of the dirty range).\n // The bundle-recorded draw only re-binds the buffer; animated instances (e.g. wind-swayed flora)\n // mutate their matrices every frame, but the cached opaque bundle is NOT re-recorded each frame,\n // so the draw-time sync never runs on a steady frame. We therefore upload dirty thin-instance data\n // from the per-frame update() below (which always runs). It is version-gated, so static instances\n // cost nothing, and it never recreates the buffer for a same-capacity update — keeping the cached\n // bundle's setVertexBuffer reference valid.\n let _syncThinInstanceGpuData: ((engine: EngineContext, ti: ThinInstanceData, hasColor: boolean) => void) | null = null;\n if (hasSomeThinInstances) {\n const mod = await import(\"../../shader/fragments/thin-instance-fragment.js\");\n _createThinInstanceFragment = mod.createThinInstanceFragment;\n const gpuMod = await import(\"../../mesh/thin-instance-gpu.js\");\n _syncThinInstanceBuffers = gpuMod.syncThinInstanceBuffers;\n if (hasCullingTI) {\n _cull = await import(\"../../mesh/thin-instance-cull-binding.js\");\n }\n _syncThinInstanceGpuData = gpuMod.syncThinInstanceGpuData;\n }\n\n // ACES tonemap WGSL is dynamically imported only when requested (keeps standard-tonemap bundles lean).\n // Must be loaded before the composer is created so deps are fully resolved.\n let _acesHelpers = \"\";\n let _acesTonemapCall = \"\";\n const hasTonemap = scene.imageProcessing.toneMappingEnabled;\n if (hasTonemap && scene.imageProcessing.toneMappingType === \"aces\") {\n const acesMod = await import(\"./pbr-aces-wgsl.js\");\n _acesHelpers = acesMod.ACES_HELPERS_WGSL;\n _acesTonemapCall = acesMod.ACES_TONEMAP_CALL_WGSL;\n }\n\n // Fog WGSL is dynamically imported only when the scene has fog, so non-fog PBR scenes\n // bundle zero fog bytes (a static import would defeat tree-shaking — see pbr-fog-wgsl.ts).\n let _fogHelper = \"\";\n let _fogBlock = \"\";\n if (scene.fog) {\n const fogMod = await import(\"./pbr-fog-wgsl.js\");\n _fogHelper = fogMod.PBR_FOG_HELPER;\n _fogBlock = fogMod.PBR_FOG_BLOCK;\n }\n\n const composePbr = createPbrComposer({\n _singleLightWGSL,\n _getSingleLightBlock,\n _multiLightWGSL,\n _multiLightLoop,\n _acesHelpers,\n _acesTonemapCall,\n _fogHelper,\n _fogBlock,\n _createPbrTemplateExt,\n _anisoExt,\n _iblSkyboxCalc,\n _flatNormalWgsl,\n _createPbrShadowFragment,\n _shadowLights: shadowLights,\n _createThinInstanceFragment,\n });\n\n const sceneFeatures = (hasEnv ? PBR_HAS_ENV : 0) | (hasTonemap ? PBR_HAS_TONEMAP : 0) | (scene.fog ? PBR_HAS_FOG : 0);\n // Shadow bind group cache — within one scene build, all receiving meshes share the\n // same shadowLights array, so a BG keyed by shadowBGL alone is correct.\n const shadowBGCache = new Map<GPUBindGroupLayout, GPUBindGroup>();\n const syncThinInstanceBuffers = _syncThinInstanceBuffers;\n const syncThinInstanceGpuData = _syncThinInstanceGpuData;\n\n // Closure used both for the initial per-mesh build below AND for later\n // material-swap / per-pass-override rebuilds (set on pbrGroupBuilder._rebuildSingle).\n // Captures the per-scene context — no separate WeakMap needed.\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const materialInput = (materialOverride ?? mesh.material) as PbrMaterialProps;\n const mat = materialInput;\n const renderFeatures = (mat._renderFeatures ??= _computePbrMaterialFeatures(mat)) as MaterialRenderFeatures;\n const isOverride = materialOverride != null;\n const mi = mesh;\n\n const lr = writeMeshLightSelection(mesh, s.lights);\n const lightCount = lr > 0 ? 1 : -lr;\n const features = renderFeatures.features;\n const features2 = renderFeatures.features2 ?? 0;\n const shadowOutput = (features2 & (PBR2_NO_COLOR_OUTPUT | PBR2_ESM_SHADOW_OUTPUT)) !== 0;\n const receiveShadows = !shadowOutput && mesh.receiveShadows && hasSomeShadows;\n const lightMode: PbrLightMode = lightCount === 0 ? 0 : lightCount === 1 && !receiveShadows ? 1 : 2;\n const singleLightType = lightMode === 1 ? getPackedSingleLightType(s.lights, lr - 1) : \"\";\n const meshFeatures = _computeMeshFeatures(mesh, receiveShadows);\n const esmShadowDepthCode = (features2 & PBR2_ESM_SHADOW_OUTPUT) !== 0 ? (mat as PbrMaterialProps & { readonly _esmShadowDepthCode: string })._esmShadowDepthCode : \"\";\n\n // Genuine GPU interleaving. Tight meshes have `_vbLayout` undefined → vbKey \"\"\n // → composed shader, bindings, and pipeline cache keys are byte-identical to\n // today. Interleaved meshes carry a precomputed vbKey from the loader module.\n const vbLayout = mi._gpu._vbLayout;\n const vbKey = mi._gpu._vbKey ?? \"\";\n\n const composed = composePbr(features, features2, meshFeatures, sceneFeatures, lightMode, singleLightType, esmShadowDepthCode, vbLayout, vbKey);\n const bindings = getOrCreatePbrBindings(engine, features, features2, meshFeatures, sceneFeatures, composed, `${lightMode}:${singleLightType}${vbKey}`, mat.stencil ?? null);\n\n // Mesh UBO (world matrix at offset 0; spec.totalBytes covers any extra fields).\n const meshUboData = new F32(composed._meshUboSpec._totalBytes / 4);\n const _packMeshWorld = engine._makePackMeshWorld?.(s as SceneContext) ?? packMat4IntoF32;\n _packMeshWorld(meshUboData, mesh.worldMatrix, 0, 0);\n writeMeshLightSelection(mesh, s.lights, meshUboData);\n const meshUBO = createUniformBuffer(engine, meshUboData);\n\n // Material UBO.\n const materialSpec = composed._materialUboSpec!;\n const matInitData = new F32(materialSpec._totalBytes / 4);\n _writeMaterialData(matInitData, mat, materialSpec);\n const materialUBO = createUniformBuffer(engine, matInitData);\n\n const needsTaskRefraction = !!mat.transmissive && (features2 & PBR2_HAS_REFRACTION) !== 0;\n const materialBindGroupStatic = needsTaskRefraction ? null : createPbrMeshBindGroup(engine, bindings, composed, meshUBO, materialUBO, mat, envTextures ?? null, mesh);\n\n // Shadow bind group (group 2) — shared across receiving meshes via shadowBGCache.\n let shadowBindGroup: GPUBindGroup | null = null;\n const meshShadowLights = receiveShadows ? shadowLights : [];\n if (meshShadowLights.length > 0 && bindings._shadowBGL) {\n let cached = shadowBGCache.get(bindings._shadowBGL);\n if (!cached) {\n const entries: GPUBindGroupEntry[] = [];\n let b = 0;\n for (const sl of meshShadowLights) {\n const sg = sl.gen;\n entries.push({ binding: b++, resource: sg._depthTexture.createView() });\n entries.push({ binding: b++, resource: sg._depthSampler });\n entries.push({ binding: b++, resource: { buffer: sg._shadowUBO } });\n }\n cached = device.createBindGroup({ layout: bindings._shadowBGL, entries });\n shadowBGCache.set(bindings._shadowBGL, cached);\n }\n shadowBindGroup = cached;\n }\n\n const boundTextures = collectPbrBoundTextures(mat);\n for (const t of boundTextures) {\n acquireTexture(t);\n }\n s._meshDisposables.set(mesh, [\n () => {\n meshUBO.destroy();\n materialUBO.destroy();\n },\n () => {\n for (const t of boundTextures) {\n releaseTexture(t);\n }\n },\n ]);\n\n const isTransparent = (features2 & (PBR2_NO_COLOR_OUTPUT | PBR2_ESM_SHADOW_OUTPUT)) === 0 && (features & PBR_HAS_ALPHA_BLEND) !== 0;\n const order = mesh.renderOrder ?? (isTransparent || needsTaskRefraction ? 150 : 100);\n\n const hasNormalMap = (features & PBR_HAS_NORMAL_MAP) !== 0;\n const hasUV2 = (features2 & PBR2_HAS_UV2) !== 0 && (meshFeatures & MSH_HAS_UV2) !== 0;\n const hasVertexColor = (meshFeatures & MSH_HAS_VERTEX_COLOR) !== 0;\n const hasTI = (meshFeatures & MSH_HAS_THIN_INSTANCES) !== 0;\n const hasTIColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n\n let _lastWorldVersion = mesh.worldMatrixVersion;\n let _lastLightsCount = s.lights.length;\n const sortCenter = isTransparent || needsTaskRefraction ? ([mesh.worldMatrix[12]!, mesh.worldMatrix[13]!, mesh.worldMatrix[14]!] as [number, number, number]) : null;\n const _baseUpdate = (): void => {\n const worldVersion = mesh.worldMatrixVersion;\n if (worldVersion !== _lastWorldVersion || s.lights.length !== _lastLightsCount) {\n if (sortCenter) {\n sortCenter[0] = mesh.worldMatrix[12]!;\n sortCenter[1] = mesh.worldMatrix[13]!;\n sortCenter[2] = mesh.worldMatrix[14]!;\n }\n _packMeshWorld(meshUboData, mesh.worldMatrix, 0, 0);\n writeMeshLightSelection(mesh, s.lights, meshUboData);\n device.queue.writeBuffer(meshUBO, 0, meshUboData as Float32Array<ArrayBuffer>);\n _lastWorldVersion = worldVersion;\n _lastLightsCount = s.lights.length;\n }\n const uboVersion = mat._uboVersion;\n if (uboVersion !== _lastUboVersion) {\n _lastUboVersion = uboVersion;\n let data = materialScratch.get(materialSpec._totalBytes);\n if (!data) {\n data = new F32(materialSpec._totalBytes / 4);\n materialScratch.set(materialSpec._totalBytes, data);\n } else {\n data.fill(0);\n }\n _writeMaterialData(data, mat, materialSpec);\n device.queue.writeBuffer(materialUBO, 0, data.buffer, 0, data.byteLength);\n }\n // Upload any dirty thin-instance matrices/colors every frame (version-gated; see the\n // _syncThinInstanceGpuData declaration above). This is what makes per-frame animated\n // instance transforms (wind sway) actually reach the GPU despite the cached draw bundle.\n if (hasTI && syncThinInstanceGpuData) {\n const ti = mesh.thinInstances;\n if (ti) {\n syncThinInstanceGpuData(engine, ti, hasTIColor);\n }\n }\n };\n // FO-version wrapper applied only when the engine has floating-origin\n // on (see standard-renderable for the rationale).\n const _invalidate = (): void => {\n _lastWorldVersion = -1;\n };\n const update = engine._wrapRenderableForFO?.(_baseUpdate, s as SceneContext, _invalidate) ?? _baseUpdate;\n\n const drawWith = (\n pass: GPURenderPassEncoder | GPURenderBundleEncoder,\n materialBindGroup: GPUBindGroup,\n cullBinding?: import(\"../../mesh/thin-instance-cull-binding.js\").TiCullBinding\n ): number => {\n if (!isOverride && mesh.material !== materialInput) {\n return 0;\n }\n const gpu = mi._gpu;\n pass.setBindGroup(1, materialBindGroup);\n if (shadowBindGroup) {\n pass.setBindGroup(2, shadowBindGroup);\n }\n let slot = 0;\n // Interleaved meshes share one GPU buffer across attributes; the per-attribute\n // byte offset is baked into the pipeline vertex layout (attributes[].offset), so\n // every slot binds at offset 0. This matches Babylon.js WebGPU and avoids a\n // non-zero setVertexBuffer bind offset, which corrupts vertex fetch on some\n // AMD (Renoir) / Dawn paths (interleaved ClearCoatTest labels went black/garbage).\n pass.setVertexBuffer(slot++, gpu.positionBuffer);\n pass.setVertexBuffer(slot++, gpu.normalBuffer);\n if (hasNormalMap && gpu.tangentBuffer) {\n pass.setVertexBuffer(slot++, gpu.tangentBuffer);\n }\n pass.setVertexBuffer(slot++, gpu.uvBuffer);\n if (hasUV2 && gpu.uv2Buffer) {\n pass.setVertexBuffer(slot++, gpu.uv2Buffer);\n }\n if (hasVertexColor && gpu.colorBuffer) {\n pass.setVertexBuffer(slot++, gpu.colorBuffer);\n }\n // Skinning vertex buffers: live skeleton OR baked VAT (same field names, mutually exclusive).\n const skin = mesh.skeleton ?? mesh.vat;\n if (skin) {\n pass.setVertexBuffer(slot++, skin.jointsBuffer);\n pass.setVertexBuffer(slot++, skin.weightsBuffer);\n if (skin.joints1Buffer && skin.weights1Buffer) {\n pass.setVertexBuffer(slot++, skin.joints1Buffer);\n pass.setVertexBuffer(slot++, skin.weights1Buffer);\n }\n }\n\n const ti = hasTI ? mesh.thinInstances : null;\n if (ti && syncThinInstanceBuffers) {\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasTIColor, cullBinding?.cullDrawBufs);\n }\n\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n if (cullBinding) {\n cullBinding.draw(pass, gpu.indexCount, ti!.count);\n } else if (ti && ti.count > 0) {\n pass.drawIndexed(gpu.indexCount, ti.count);\n } else {\n pass.drawIndexed(gpu.indexCount);\n }\n return 1;\n };\n\n const r: Renderable = {\n order,\n isTransparent,\n _transmissive: needsTaskRefraction,\n mesh,\n bind(eng, sig) {\n const pipeline = getOrCreatePbrPipeline(eng as EngineContext, sig, bindings);\n const materialBindGroup = needsTaskRefraction\n ? createPbrMeshBindGroup(engine, bindings, composed, meshUBO, materialUBO, mat, envTextures ?? null, mesh, sig._transmissionTexture)\n : materialBindGroupStatic!;\n // Opaque-only GPU culling (opt-in): tryBind returns a per-binding lifecycle or undefined.\n const cb = _cull?.tryBind(r, s, mesh, engine, hasTIColor, isTransparent || needsTaskRefraction, update);\n return {\n renderable: r,\n pipeline,\n update: cb ? cb.update : update,\n draw: (pass) => drawWith(pass, materialBindGroup, cb),\n };\n },\n };\n if (sortCenter) {\n r._worldCenter = sortCenter;\n }\n let _lastUboVersion = mat._uboVersion;\n return r;\n };\n\n const renderables = meshes.map((m) => rebuildSingle(scene, m));\n\n // Stash the per-scene PBR context on the scene so the PBR geometry-renderer\n // path can reuse the same composer / env / shadow setup without re-running\n // the scene-wide scan above. Stored on the scene (not on pbrGroupBuilder)\n // to avoid a static cycle: pbrGroupBuilder lives in pbr-material.ts which\n // already dynamic-imports this module.\n (scene as SceneContext & { _pbrGeomContext?: _PbrGeometryContext })._pbrGeomContext = {\n _composePbr: composePbr,\n _sceneFeatures: sceneFeatures,\n _envTextures: envTextures ?? null,\n _shadowLights: shadowLights,\n _syncThinInstanceBuffers: _syncThinInstanceBuffers,\n };\n\n scene._disposables.push(\n () => clearPbrPipelineCache(),\n () => clearSamplerCache(engine)\n );\n\n return { renderables, rebuildSingle };\n}\n\n/** @internal Per-scene PBR context stashed on the singleton `pbrGroupBuilder`\n * after `buildPbrRenderables` runs. Consumed by the PBR geometry-renderer\n * module — the only way to reuse the per-scene `composePbr` closure (env,\n * shadows, lights, anisotropy, sub-features) without duplicating the heavy\n * scene-wide dep-gathering scan. Overwritten on each scene build, matching\n * the same pattern used for `_rebuildSingle`. */\nexport interface _PbrGeometryContext {\n /** @internal */\n readonly _composePbr: ReturnType<typeof createPbrComposer>;\n /** @internal */\n readonly _sceneFeatures: number;\n /** @internal */\n readonly _envTextures: EnvironmentTextures | null;\n /** @internal */\n readonly _shadowLights: readonly { readonly lightIndex: number; readonly shadowType: \"esm\" | \"pcf\" | \"csm\"; readonly gen: ShadowGenerator }[];\n /** @internal */\n readonly _syncThinInstanceBuffers:\n | ((engine: EngineContext, ti: ThinInstanceData, pass: GPURenderPassEncoder | GPURenderBundleEncoder, slot: number, hasColor: boolean) => number)\n | null;\n}\n\nfunction toSingleLightType(type: string): SingleLightType {\n return type === \"hemispheric\" || type === \"directional\" || type === \"spot\" ? type : \"point\";\n}\n\nfunction getPackedSingleLightType(lights: SceneContext[\"lights\"], packedIndex: number): SingleLightType {\n let packed = 0;\n for (const light of lights) {\n if (!light._writeLightUbo) {\n continue;\n }\n if (packed === packedIndex) {\n return toSingleLightType(light.lightType);\n }\n packed++;\n }\n return \"point\";\n}\n\nasync function importSingleLightWgsl(type: SingleLightType): Promise<SingleLightWgslModule> {\n if (type === \"hemispheric\") {\n return import(\"./fragments/singlelight-hemispheric-wgsl.js\");\n }\n if (type === \"directional\") {\n return import(\"./fragments/singlelight-directional-wgsl.js\");\n }\n if (type === \"spot\") {\n return import(\"./fragments/singlelight-spot-wgsl.js\");\n }\n return import(\"./fragments/singlelight-point-wgsl.js\");\n}\n\n/** @internal Write material properties into a pre-allocated Float32Array.\n * Core fields only; per-extension slices are contributed by registered\n * writers. Exported for the PBR geometry-renderer path. */\nexport function _writeMaterialData(data: Float32Array, material: PbrMaterialProps, spec: import(\"../../shader/fragment-types.js\").UboSpec): void {\n data[0] = material.environmentIntensity ?? 1.0;\n data[1] = material.directIntensity ?? 1.0;\n data[2] = material.reflectance ?? 0.04;\n data[3] = material.alpha ?? 1.0;\n const baseColorFactorOffset = spec._offsets.get(\"baseColorFactor\");\n if (baseColorFactorOffset !== undefined) {\n const off = baseColorFactorOffset / 4;\n const factor = material.baseColorFactor;\n data[off] = factor ? factor[0]! : 1.0;\n data[off + 1] = factor ? factor[1]! : 1.0;\n data[off + 2] = factor ? factor[2]! : 1.0;\n data[off + 3] = factor ? factor[3]! : 1.0;\n }\n if (spec._offsets.has(\"metallicFactor\")) {\n const off = spec._offsets.get(\"metallicFactor\")! / 4;\n data[off] = material.metallicFactor ?? 1.0;\n data[off + 1] = material.roughnessFactor ?? 1.0;\n data[off + 2] = material.normalTextureScale ?? 1.0;\n data[off + 3] = material.usePhysicalLightFalloff === false ? 0 : 1;\n }\n for (const ext of _getPbrExts().values()) {\n if (ext.writeUbo) {\n ext.writeUbo(data, material, spec._offsets);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pbr-renderable.js","sources":["../../../../src/material/pbr/pbr-renderable.ts"],"sourcesContent":["/** PBR mesh renderable — builds Renderables from glTF PBR meshes + environment.\n *\n * `buildPbrRenderables` does shared per-scene setup (extension/fragment imports,\n * shader composer, scene bind group, multi-light UBO), then delegates per-mesh\n * work to `buildSinglePbrRenderable`. Both initial build and material-swap\n * rebuilds go through the same single-mesh function. */\n\nimport { F32 } from \"../../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Mesh } from \"../../mesh/mesh.js\";\nimport type { PbrMaterialProps } from \"./pbr-material.js\";\nimport { collectPbrBoundTextures } from \"./pbr-material.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\n\nimport type { Renderable, MeshGroupBuildResult } from \"../../render/renderable.js\";\nimport type { ShaderFragment } from \"../../shader/fragment-types.js\";\nimport { acquireTexture, releaseTexture, clearSamplerCache } from \"../../resource/gpu-pool.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { getOrCreatePbrBindings, getOrCreatePbrPipeline, createPbrMeshBindGroup, clearPbrPipelineCache } from \"./pbr-pipeline.js\";\nimport {\n _registerPbrExt,\n _getPbrExts,\n PBR_HAS_NORMAL_MAP,\n PBR_HAS_ALPHA_BLEND,\n PBR2_NO_COLOR_OUTPUT,\n PBR2_HAS_REFRACTION,\n PBR2_HAS_UV2,\n PBR_HAS_ENV,\n PBR_HAS_TONEMAP,\n PBR_HAS_FOG,\n PBR2_ESM_SHADOW_OUTPUT,\n} from \"./pbr-flags.js\";\nimport type { PbrExt } from \"./pbr-flags.js\";\nimport { createPbrComposer } from \"./pbr-compose.js\";\nimport { _computePbrMaterialFeatures } from \"./pbr-material.js\";\nimport type { ShadowGenerator } from \"../../shadow/shadow-generator.js\";\nimport type { ThinInstanceData } from \"../../mesh/thin-instance.js\";\nimport type { PbrShadowLightSlot } from \"./fragments/pbr-shadow-fragment.js\";\nimport { writeMeshLightSelection } from \"../../render/lights-ubo.js\";\nimport type { PbrLightMode } from \"./pbr-compose.js\";\nimport type { Material, MaterialRenderFeatures } from \"../material.js\";\nimport { _computeMeshFeatures, MSH_HAS_INSTANCE_COLOR, MSH_HAS_THIN_INSTANCES, MSH_HAS_UV2, MSH_HAS_VERTEX_COLOR } from \"../mesh-features.js\";\nimport { packMat4IntoF32 } from \"../../math/pack-mat4-into-f32.js\";\n\ntype SingleLightType = \"hemispheric\" | \"directional\" | \"spot\" | \"point\";\ninterface SingleLightWgslModule {\n SINGLE_LIGHT_STRUCTS: string;\n getSingleLightBlock(): string;\n}\n\n/** Build PBR Renderable(s) + a SceneUniformUpdater from PBR meshes. */\nexport async function buildPbrRenderables(scene: SceneContext, meshes: Mesh[], envTextures: EnvironmentTextures | undefined): Promise<MeshGroupBuildResult> {\n const engine = scene.surface.engine;\n const device = engine._device;\n // Per-size scratch buffers for material UBO re-writes (zero allocation per frame).\n const materialScratch = new Map<number, Float32Array>();\n const hasEnv = !!envTextures;\n const shadowLights: { lightIndex: number; shadowType: \"esm\" | \"pcf\" | \"csm\"; gen: ShadowGenerator }[] = [];\n for (let i = 0; i < scene.lights.length; i++) {\n const sg = scene.lights[i]!.shadowGenerator;\n if (sg) {\n shadowLights.push({ lightIndex: i, shadowType: sg._shadowType, gen: sg });\n }\n }\n const hasSomeShadows = shadowLights.length > 0;\n let hasAnyAffectedLight = false;\n let needsSingleLightPath = false;\n let needsMultiLightPath = false;\n const singleLightTypes: SingleLightType[] = [];\n for (const mesh of meshes) {\n const lr = writeMeshLightSelection(mesh, scene.lights);\n const affectedCount = lr > 0 ? 1 : -lr;\n hasAnyAffectedLight ||= affectedCount > 0;\n if (affectedCount === 1 && !(mesh.receiveShadows && hasSomeShadows)) {\n needsSingleLightPath = true;\n const type = getPackedSingleLightType(scene.lights, lr - 1);\n if (!singleLightTypes.includes(type)) {\n singleLightTypes.push(type);\n }\n } else if (affectedCount > 0) {\n needsMultiLightPath = true;\n }\n }\n\n // ── Single O(N) scan over meshes for all scene-wide feature flags ──\n // Flags are plain locals (not an object return) so terser can mangle their names.\n // Replaces ~11 sequential meshes.some() loops (was O(11N)).\n let hasSkybox = false;\n let hasMetallicReflectance = false;\n let hasClearcoat = false;\n let hasSheen = false;\n let hasIridescence = false;\n let hasAnyAnisotropy = false;\n let hasAnySubsurface = false;\n let hasAlphaTest = false;\n let hasTransmissionRefraction = false;\n let needsEmissiveColor = false;\n let hasSomeSkeletons = false;\n let hasSomeMorphs = false;\n let hasSomeThinInstances = false;\n let hasCullingTI = false;\n let hasAnyUnlit = false;\n let hasAnyUvTransform = false;\n let hasAnyUv2 = false;\n let hasAnyVertexColor = false;\n let hasAnyFlatNormal = false;\n for (let i = 0; i < meshes.length; i++) {\n const m = meshes[i]!;\n const mat = m.material as PbrMaterialProps & { _hasReflExt?: boolean; _hasUvTx?: boolean };\n const refractionIntensity = mat.subsurface?.refraction?.intensity ?? 0;\n hasSkybox ||= !!mat.skyboxMode;\n hasMetallicReflectance ||= !!(mat.metallicReflectanceTexture || mat.reflectanceTexture || mat._hasReflExt);\n hasClearcoat ||= !!mat.clearCoat?.isEnabled;\n hasSheen ||= !!mat.sheen?.isEnabled;\n hasIridescence ||= !!mat.iridescence?.isEnabled;\n hasAnyAnisotropy ||= !!mat.anisotropy?.isEnabled;\n hasAnySubsurface ||= !!mat.subsurface?.translucency;\n hasAlphaTest ||= mat.alphaCutOff! > 0;\n hasTransmissionRefraction ||= refractionIntensity > 0 && !!mat.transmissive;\n needsEmissiveColor ||= !!mat.emissiveColor;\n hasSomeSkeletons ||= !!m.skeleton;\n hasSomeMorphs ||= !!m.morphTargets;\n hasSomeThinInstances ||= !!m.thinInstances;\n hasCullingTI ||= !!m.thinInstances?._gpuCullingEnabled;\n hasAnyUnlit ||= !!mat.unlit;\n hasAnyUvTransform ||= !!mat._hasUvTx;\n // UV2 only counts when occlusion samples texcoord 1.\n hasAnyUv2 ||= !!m._gpu.uv2Buffer && mat.occlusionTexCoord === 1;\n hasAnyVertexColor ||= !!m._gpu.colorBuffer;\n hasAnyFlatNormal ||= !!(m as { _flatNormal?: boolean })._flatNormal;\n }\n\n // ── Dynamically import fragment creators based on scene capabilities ──\n\n // IBL fragment.\n let _iblSkyboxCalc = \"\";\n if (hasEnv) {\n const mod = await import(\"./fragments/ibl-fragment.js\");\n _registerPbrExt(mod.pbrExt);\n if (hasSkybox) {\n // Skybox-mode WGSL is only loaded when at least one mesh in the scene needs it.\n const sky = await import(\"./fragments/ibl-skybox-wgsl.js\");\n _iblSkyboxCalc = sky.IBL_SKYBOX_CALCULATION;\n }\n }\n\n // Flat-normal WGSL is only loaded when at least one mesh lacks a NORMAL attribute\n // (glTF flat-shading) — normal-having scenes bundle zero bytes.\n let _flatNormalWgsl = \"\";\n if (hasAnyFlatNormal) {\n const flatNormal = await import(\"./fragments/flat-normal-wgsl.js\");\n _flatNormalWgsl = flatNormal.FLAT_NORMAL_WGSL;\n }\n\n // Light/shadow helpers stay dynamic so single-light and non-shadow bundles stay lean.\n let _createPbrShadowFragment: ((slots: PbrShadowLightSlot[]) => ShaderFragment) | null = null;\n let _singleLightWGSL = \"\";\n let _getSingleLightBlock: ((type: string) => string) | null = null;\n const singleLightBlocks: Partial<Record<SingleLightType, () => string>> = {};\n let _multiLightWGSL = \"\";\n let _multiLightLoop = \"\";\n if (needsSingleLightPath) {\n for (const type of singleLightTypes) {\n const single = await importSingleLightWgsl(type);\n _singleLightWGSL = single.SINGLE_LIGHT_STRUCTS;\n singleLightBlocks[type] = single.getSingleLightBlock;\n }\n _getSingleLightBlock = (type) => singleLightBlocks[toSingleLightType(type)]?.() ?? \"\";\n }\n if (needsMultiLightPath) {\n const wgslMod = await import(\"./fragments/multilight-wgsl.js\");\n _multiLightWGSL = wgslMod.MULTI_LIGHT_STRUCTS() + wgslMod.COMPUTE_PBR_LIGHT;\n _multiLightLoop = wgslMod.getMultiLightLoop();\n }\n if (hasAnyAffectedLight && hasSomeShadows) {\n const shadowMod = await import(\"./fragments/pbr-shadow-fragment.js\");\n _createPbrShadowFragment = shadowMod.createPbrShadowFragment;\n }\n\n // ── Per-mesh fragment creators (imported if any mesh needs them) ──\n // Each optional PBR fragment module exports a uniform `pbrExt`, so registration\n // collapses to a single data-driven loop over [flag, loader] pairs. The `import()`\n // specifiers stay literal (required for Vite code-splitting) and the shared\n // `_registerPbrExt((await load()).pbrExt)` glue is emitted once instead of per\n // feature, keeping this management layer small as features are added.\n // Registration order is the iteration order consumed by `_getPbrExts().values()`\n // on the hot paths (composePbr, writeMaterialData, collectPbrBoundTextures).\n type PbrExtLoad = () => Promise<{ pbrExt: PbrExt }>;\n const _drainPbrExts = async (loaders: Array<readonly [boolean, PbrExtLoad]>) => {\n for (const [flag, load] of loaders) {\n if (flag) {\n _registerPbrExt((await load()).pbrExt);\n }\n }\n };\n\n await _drainPbrExts([\n [hasAlphaTest, () => import(\"./fragments/alpha-test-fragment.js\")],\n [hasMetallicReflectance, () => import(\"./fragments/reflectance-fragment.js\")],\n [hasClearcoat, () => import(\"./fragments/clearcoat-fragment.js\")],\n [hasSheen, () => import(\"./fragments/sheen-fragment.js\")],\n [hasIridescence, () => import(\"./fragments/iridescence-fragment.js\")],\n [hasAnySubsurface, () => import(\"./fragments/subsurface-fragment.js\")],\n ]);\n if (hasTransmissionRefraction) {\n const mod = await import(\"./pbr-refraction.js\");\n await mod.registerPbrRefraction(scene as SceneContext, engine, _registerPbrExt);\n }\n await _drainPbrExts([\n [needsEmissiveColor, () => import(\"./fragments/emissive-fragment.js\")],\n [hasAnyUnlit, () => import(\"./fragments/unlit-fragment.js\")],\n [hasSomeSkeletons, () => import(\"./fragments/skeleton-fragment.js\")],\n [hasSomeMorphs, () => import(\"./fragments/morph-fragment.js\")],\n [hasAnyUvTransform, () => import(\"./fragments/uv-transform-fragment.js\")],\n ]);\n\n // Anisotropy needs its module reference retained (for ANISO_BRDF_FUNCTIONS /\n // makeAnisotropyTBBlock / ANISO_DIRECT_DG / ANISO_BENT_NORMAL strings consumed\n // by the template below), so it keeps the full module binding.\n let _anisoExt: typeof import(\"./fragments/anisotropy-fragment.js\") | null = null;\n if (hasAnyAnisotropy) {\n _anisoExt = await import(\"./fragments/anisotropy-fragment.js\");\n _registerPbrExt(_anisoExt.pbrExt);\n }\n\n // Lazy-load pbr-template-ext when any advanced features are present.\n // Scene1 has none of these, so it won't pay the ~1.5KB cost.\n let _createPbrTemplateExt: typeof import(\"./pbr-template-ext.js\").createPbrTemplateExt | null = null;\n if (hasAnyUvTransform || hasAnyVertexColor || hasAnyUv2) {\n const extMod = await import(\"./pbr-template-ext.js\");\n _createPbrTemplateExt = extMod.createPbrTemplateExt;\n }\n\n let _createThinInstanceFragment: ((hasColor: boolean) => ShaderFragment) | null = null;\n let _syncThinInstanceBuffers:\n | ((\n engine: EngineContext,\n ti: ThinInstanceData,\n pass: GPURenderPassEncoder | GPURenderBundleEncoder,\n slot: number,\n hasColor: boolean,\n drawBuffers?: import(\"../../mesh/thin-instance-gpu.js\").ThinInstanceDrawBuffers | null\n ) => number)\n | null = null;\n let _cull: typeof import(\"../../mesh/thin-instance-cull-binding.js\") | undefined;\n // Per-frame thin-instance matrix/color UPLOAD (no pass — just writeBuffer of the dirty range).\n // The bundle-recorded draw only re-binds the buffer; animated instances (e.g. wind-swayed flora)\n // mutate their matrices every frame, but the cached opaque bundle is NOT re-recorded each frame,\n // so the draw-time sync never runs on a steady frame. We therefore upload dirty thin-instance data\n // from the per-frame update() below (which always runs). It is version-gated, so static instances\n // cost nothing, and it never recreates the buffer for a same-capacity update — keeping the cached\n // bundle's setVertexBuffer reference valid.\n let _syncThinInstanceGpuData: ((engine: EngineContext, ti: ThinInstanceData, hasColor: boolean) => void) | null = null;\n if (hasSomeThinInstances) {\n const mod = await import(\"../../shader/fragments/thin-instance-fragment.js\");\n _createThinInstanceFragment = mod.createThinInstanceFragment;\n const gpuMod = await import(\"../../mesh/thin-instance-gpu.js\");\n _syncThinInstanceBuffers = gpuMod.syncThinInstanceBuffers;\n if (hasCullingTI) {\n _cull = await import(\"../../mesh/thin-instance-cull-binding.js\");\n }\n _syncThinInstanceGpuData = gpuMod.syncThinInstanceGpuData;\n }\n\n // ACES tonemap WGSL is dynamically imported only when requested (keeps standard-tonemap bundles lean).\n // Must be loaded before the composer is created so deps are fully resolved.\n let _acesHelpers = \"\";\n let _acesTonemapCall = \"\";\n const hasTonemap = scene.imageProcessing.toneMappingEnabled;\n if (hasTonemap && scene.imageProcessing.toneMappingType === \"aces\") {\n const acesMod = await import(\"./pbr-aces-wgsl.js\");\n _acesHelpers = acesMod.ACES_HELPERS_WGSL;\n _acesTonemapCall = acesMod.ACES_TONEMAP_CALL_WGSL;\n }\n\n // Fog WGSL is dynamically imported only when the scene has fog, so non-fog PBR scenes\n // bundle zero fog bytes (a static import would defeat tree-shaking — see pbr-fog-wgsl.ts).\n let _fogHelper = \"\";\n let _fogBlock = \"\";\n if (scene.fog) {\n const fogMod = await import(\"./pbr-fog-wgsl.js\");\n _fogHelper = fogMod.PBR_FOG_HELPER;\n _fogBlock = fogMod.PBR_FOG_BLOCK;\n }\n\n const composePbr = createPbrComposer({\n _singleLightWGSL,\n _getSingleLightBlock,\n _multiLightWGSL,\n _multiLightLoop,\n _acesHelpers,\n _acesTonemapCall,\n _fogHelper,\n _fogBlock,\n _createPbrTemplateExt,\n _anisoExt,\n _iblSkyboxCalc,\n _flatNormalWgsl,\n _createPbrShadowFragment,\n _shadowLights: shadowLights,\n _createThinInstanceFragment,\n });\n\n const sceneFeatures = (hasEnv ? PBR_HAS_ENV : 0) | (hasTonemap ? PBR_HAS_TONEMAP : 0) | (scene.fog ? PBR_HAS_FOG : 0);\n // Shadow bind group cache — within one scene build, all receiving meshes share the\n // same shadowLights array, so a BG keyed by shadowBGL alone is correct.\n const shadowBGCache = new Map<GPUBindGroupLayout, GPUBindGroup>();\n const syncThinInstanceBuffers = _syncThinInstanceBuffers;\n const syncThinInstanceGpuData = _syncThinInstanceGpuData;\n\n // Closure used both for the initial per-mesh build below AND for later\n // material-swap / per-pass-override rebuilds (set on pbrGroupBuilder._rebuildSingle).\n // Captures the per-scene context — no separate WeakMap needed.\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const materialInput = (materialOverride ?? mesh.material) as PbrMaterialProps;\n const mat = materialInput;\n const renderFeatures = (mat._renderFeatures ??= _computePbrMaterialFeatures(mat)) as MaterialRenderFeatures;\n const isOverride = materialOverride != null;\n const mi = mesh;\n\n const lr = writeMeshLightSelection(mesh, s.lights);\n const lightCount = lr > 0 ? 1 : -lr;\n const features = renderFeatures.features;\n const features2 = renderFeatures.features2 ?? 0;\n const shadowOutput = (features2 & (PBR2_NO_COLOR_OUTPUT | PBR2_ESM_SHADOW_OUTPUT)) !== 0;\n const receiveShadows = !shadowOutput && mesh.receiveShadows && hasSomeShadows;\n const lightMode: PbrLightMode = lightCount === 0 ? 0 : lightCount === 1 && !receiveShadows ? 1 : 2;\n const singleLightType = lightMode === 1 ? getPackedSingleLightType(s.lights, lr - 1) : \"\";\n const meshFeatures = _computeMeshFeatures(mesh, receiveShadows);\n const esmShadowDepthCode = (features2 & PBR2_ESM_SHADOW_OUTPUT) !== 0 ? (mat as PbrMaterialProps & { readonly _esmShadowDepthCode: string })._esmShadowDepthCode : \"\";\n\n // Genuine GPU interleaving. Tight meshes have `_vbLayout` undefined → vbKey \"\"\n // → composed shader, bindings, and pipeline cache keys are byte-identical to\n // today. Interleaved meshes carry a precomputed vbKey from the loader module.\n const vbLayout = mi._gpu._vbLayout;\n const vbKey = mi._gpu._vbKey ?? \"\";\n\n const composed = composePbr(features, features2, meshFeatures, sceneFeatures, lightMode, singleLightType, esmShadowDepthCode, vbLayout, vbKey);\n const bindings = getOrCreatePbrBindings(engine, features, features2, meshFeatures, sceneFeatures, composed, `${lightMode}:${singleLightType}${vbKey}`, mat.stencil ?? null);\n\n // Mesh UBO (world matrix at offset 0; spec.totalBytes covers any extra fields).\n const meshUboData = new F32(composed._meshUboSpec._totalBytes / 4);\n const _packMeshWorld = engine._makePackMeshWorld?.(s as SceneContext) ?? packMat4IntoF32;\n _packMeshWorld(meshUboData, mesh.worldMatrix, 0, 0);\n writeMeshLightSelection(mesh, s.lights, meshUboData);\n const meshUBO = createUniformBuffer(engine, meshUboData);\n\n // Material UBO.\n const materialSpec = composed._materialUboSpec!;\n const matInitData = new F32(materialSpec._totalBytes / 4);\n _writeMaterialData(matInitData, mat, materialSpec);\n const materialUBO = createUniformBuffer(engine, matInitData);\n\n const needsTaskRefraction = !!mat.transmissive && (features2 & PBR2_HAS_REFRACTION) !== 0;\n const materialBindGroupStatic = needsTaskRefraction ? null : createPbrMeshBindGroup(engine, bindings, composed, meshUBO, materialUBO, mat, envTextures ?? null, mesh);\n\n // Shadow bind group (group 2) — shared across receiving meshes via shadowBGCache.\n let shadowBindGroup: GPUBindGroup | null = null;\n const meshShadowLights = receiveShadows ? shadowLights : [];\n if (meshShadowLights.length > 0 && bindings._shadowBGL) {\n let cached = shadowBGCache.get(bindings._shadowBGL);\n if (!cached) {\n const entries: GPUBindGroupEntry[] = [];\n let b = 0;\n for (const sl of meshShadowLights) {\n const sg = sl.gen;\n entries.push({ binding: b++, resource: sg._depthTexture.createView() });\n entries.push({ binding: b++, resource: sg._depthSampler });\n entries.push({ binding: b++, resource: { buffer: sg._shadowUBO } });\n }\n cached = device.createBindGroup({ layout: bindings._shadowBGL, entries });\n shadowBGCache.set(bindings._shadowBGL, cached);\n }\n shadowBindGroup = cached;\n }\n\n const boundTextures = collectPbrBoundTextures(mat);\n for (const t of boundTextures) {\n acquireTexture(t);\n }\n s._meshDisposables.set(mesh, [\n () => {\n meshUBO.destroy();\n materialUBO.destroy();\n },\n () => {\n for (const t of boundTextures) {\n releaseTexture(t);\n }\n },\n ]);\n\n const isTransparent = (features2 & (PBR2_NO_COLOR_OUTPUT | PBR2_ESM_SHADOW_OUTPUT)) === 0 && (features & PBR_HAS_ALPHA_BLEND) !== 0;\n const order = mesh.renderOrder ?? (isTransparent || needsTaskRefraction ? 150 : 100);\n\n const hasNormalMap = (features & PBR_HAS_NORMAL_MAP) !== 0;\n const hasUV2 = (features2 & PBR2_HAS_UV2) !== 0 && (meshFeatures & MSH_HAS_UV2) !== 0;\n const hasVertexColor = (meshFeatures & MSH_HAS_VERTEX_COLOR) !== 0;\n const hasTI = (meshFeatures & MSH_HAS_THIN_INSTANCES) !== 0;\n const hasTIColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n\n let _lastWorldVersion = mesh.worldMatrixVersion;\n let _lastLightsCount = s.lights.length;\n const sortCenter = isTransparent || needsTaskRefraction ? ([mesh.worldMatrix[12]!, mesh.worldMatrix[13]!, mesh.worldMatrix[14]!] as [number, number, number]) : null;\n const _baseUpdate = (): void => {\n const worldVersion = mesh.worldMatrixVersion;\n if (worldVersion !== _lastWorldVersion || s.lights.length !== _lastLightsCount) {\n if (sortCenter) {\n sortCenter[0] = mesh.worldMatrix[12]!;\n sortCenter[1] = mesh.worldMatrix[13]!;\n sortCenter[2] = mesh.worldMatrix[14]!;\n }\n _packMeshWorld(meshUboData, mesh.worldMatrix, 0, 0);\n writeMeshLightSelection(mesh, s.lights, meshUboData);\n device.queue.writeBuffer(meshUBO, 0, meshUboData as Float32Array<ArrayBuffer>);\n _lastWorldVersion = worldVersion;\n _lastLightsCount = s.lights.length;\n }\n const uboVersion = mat._uboVersion;\n if (uboVersion !== _lastUboVersion) {\n _lastUboVersion = uboVersion;\n let data = materialScratch.get(materialSpec._totalBytes);\n if (!data) {\n data = new F32(materialSpec._totalBytes / 4);\n materialScratch.set(materialSpec._totalBytes, data);\n } else {\n data.fill(0);\n }\n _writeMaterialData(data, mat, materialSpec);\n device.queue.writeBuffer(materialUBO, 0, data.buffer, 0, data.byteLength);\n }\n // Upload any dirty thin-instance matrices/colors every frame (version-gated; see the\n // _syncThinInstanceGpuData declaration above). This is what makes per-frame animated\n // instance transforms (wind sway) actually reach the GPU despite the cached draw bundle.\n if (hasTI && syncThinInstanceGpuData) {\n const ti = mesh.thinInstances;\n if (ti) {\n syncThinInstanceGpuData(engine, ti, hasTIColor);\n }\n }\n };\n // FO-version wrapper applied only when the engine has floating-origin\n // on (see standard-renderable for the rationale).\n const _invalidate = (): void => {\n _lastWorldVersion = -1;\n };\n const update = engine._wrapRenderableForFO?.(_baseUpdate, s as SceneContext, _invalidate) ?? _baseUpdate;\n\n const drawWith = (\n pass: GPURenderPassEncoder | GPURenderBundleEncoder,\n materialBindGroup: GPUBindGroup,\n cullBinding?: import(\"../../mesh/thin-instance-cull-binding.js\").TiCullBinding\n ): number => {\n if (!isOverride && mesh.material !== materialInput) {\n return 0;\n }\n const gpu = mi._gpu;\n pass.setBindGroup(1, materialBindGroup);\n if (shadowBindGroup) {\n pass.setBindGroup(2, shadowBindGroup);\n }\n let slot = 0;\n // Interleaved meshes share one GPU buffer across attributes; the per-attribute\n // byte offset is baked into the pipeline vertex layout (attributes[].offset), so\n // every slot binds at offset 0. This matches Babylon.js WebGPU and avoids a\n // non-zero setVertexBuffer bind offset, which corrupts vertex fetch on some\n // AMD (Renoir) / Dawn paths (interleaved ClearCoatTest labels went black/garbage).\n pass.setVertexBuffer(slot++, gpu.positionBuffer);\n pass.setVertexBuffer(slot++, gpu.normalBuffer);\n if (hasNormalMap && gpu.tangentBuffer) {\n pass.setVertexBuffer(slot++, gpu.tangentBuffer);\n }\n pass.setVertexBuffer(slot++, gpu.uvBuffer);\n if (hasUV2 && gpu.uv2Buffer) {\n pass.setVertexBuffer(slot++, gpu.uv2Buffer);\n }\n if (hasVertexColor && gpu.colorBuffer) {\n pass.setVertexBuffer(slot++, gpu.colorBuffer);\n }\n // Skinning vertex buffers: live skeleton OR baked VAT (same field names, mutually exclusive).\n const skin = mesh.skeleton ?? mesh.vat;\n if (skin) {\n pass.setVertexBuffer(slot++, skin.jointsBuffer);\n pass.setVertexBuffer(slot++, skin.weightsBuffer);\n if (skin.joints1Buffer && skin.weights1Buffer) {\n pass.setVertexBuffer(slot++, skin.joints1Buffer);\n pass.setVertexBuffer(slot++, skin.weights1Buffer);\n }\n }\n\n const ti = hasTI ? mesh.thinInstances : null;\n if (ti && syncThinInstanceBuffers) {\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasTIColor, cullBinding?.cullDrawBufs);\n }\n\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n if (cullBinding) {\n cullBinding.draw(pass, gpu.indexCount, ti!.count);\n } else if (ti && ti.count > 0) {\n pass.drawIndexed(gpu.indexCount, ti.count);\n } else {\n pass.drawIndexed(gpu.indexCount);\n }\n return 1;\n };\n\n const r: Renderable = {\n order,\n isTransparent,\n _transmissive: needsTaskRefraction,\n mesh,\n bind(eng, sig) {\n const pipeline = getOrCreatePbrPipeline(eng as EngineContext, sig, bindings);\n const materialBindGroup = needsTaskRefraction\n ? createPbrMeshBindGroup(engine, bindings, composed, meshUBO, materialUBO, mat, envTextures ?? null, mesh, sig._transmissionTexture)\n : materialBindGroupStatic!;\n // Opaque-only GPU culling (opt-in): tryBind returns a per-binding lifecycle or undefined.\n const cb = _cull?.tryBind(r, s, mesh, engine, hasTIColor, isTransparent || needsTaskRefraction, update, sig);\n return {\n renderable: r,\n pipeline,\n update: cb ? cb.update : update,\n draw: (pass) => drawWith(pass, materialBindGroup, cb),\n };\n },\n };\n if (sortCenter) {\n r._worldCenter = sortCenter;\n }\n let _lastUboVersion = mat._uboVersion;\n return r;\n };\n\n const renderables = meshes.map((m) => rebuildSingle(scene, m));\n\n // Stash the per-scene PBR context on the scene so the PBR geometry-renderer\n // path can reuse the same composer / env / shadow setup without re-running\n // the scene-wide scan above. Stored on the scene (not on pbrGroupBuilder)\n // to avoid a static cycle: pbrGroupBuilder lives in pbr-material.ts which\n // already dynamic-imports this module.\n (scene as SceneContext & { _pbrGeomContext?: _PbrGeometryContext })._pbrGeomContext = {\n _composePbr: composePbr,\n _sceneFeatures: sceneFeatures,\n _envTextures: envTextures ?? null,\n _shadowLights: shadowLights,\n _syncThinInstanceBuffers: _syncThinInstanceBuffers,\n };\n\n scene._disposables.push(\n () => clearPbrPipelineCache(),\n () => clearSamplerCache(engine)\n );\n\n return { renderables, rebuildSingle };\n}\n\n/** @internal Per-scene PBR context stashed on the singleton `pbrGroupBuilder`\n * after `buildPbrRenderables` runs. Consumed by the PBR geometry-renderer\n * module — the only way to reuse the per-scene `composePbr` closure (env,\n * shadows, lights, anisotropy, sub-features) without duplicating the heavy\n * scene-wide dep-gathering scan. Overwritten on each scene build, matching\n * the same pattern used for `_rebuildSingle`. */\nexport interface _PbrGeometryContext {\n /** @internal */\n readonly _composePbr: ReturnType<typeof createPbrComposer>;\n /** @internal */\n readonly _sceneFeatures: number;\n /** @internal */\n readonly _envTextures: EnvironmentTextures | null;\n /** @internal */\n readonly _shadowLights: readonly { readonly lightIndex: number; readonly shadowType: \"esm\" | \"pcf\" | \"csm\"; readonly gen: ShadowGenerator }[];\n /** @internal */\n readonly _syncThinInstanceBuffers:\n | ((engine: EngineContext, ti: ThinInstanceData, pass: GPURenderPassEncoder | GPURenderBundleEncoder, slot: number, hasColor: boolean) => number)\n | null;\n}\n\nfunction toSingleLightType(type: string): SingleLightType {\n return type === \"hemispheric\" || type === \"directional\" || type === \"spot\" ? type : \"point\";\n}\n\nfunction getPackedSingleLightType(lights: SceneContext[\"lights\"], packedIndex: number): SingleLightType {\n let packed = 0;\n for (const light of lights) {\n if (!light._writeLightUbo) {\n continue;\n }\n if (packed === packedIndex) {\n return toSingleLightType(light.lightType);\n }\n packed++;\n }\n return \"point\";\n}\n\nasync function importSingleLightWgsl(type: SingleLightType): Promise<SingleLightWgslModule> {\n if (type === \"hemispheric\") {\n return import(\"./fragments/singlelight-hemispheric-wgsl.js\");\n }\n if (type === \"directional\") {\n return import(\"./fragments/singlelight-directional-wgsl.js\");\n }\n if (type === \"spot\") {\n return import(\"./fragments/singlelight-spot-wgsl.js\");\n }\n return import(\"./fragments/singlelight-point-wgsl.js\");\n}\n\n/** @internal Write material properties into a pre-allocated Float32Array.\n * Core fields only; per-extension slices are contributed by registered\n * writers. Exported for the PBR geometry-renderer path. */\nexport function _writeMaterialData(data: Float32Array, material: PbrMaterialProps, spec: import(\"../../shader/fragment-types.js\").UboSpec): void {\n data[0] = material.environmentIntensity ?? 1.0;\n data[1] = material.directIntensity ?? 1.0;\n data[2] = material.reflectance ?? 0.04;\n data[3] = material.alpha ?? 1.0;\n const baseColorFactorOffset = spec._offsets.get(\"baseColorFactor\");\n if (baseColorFactorOffset !== undefined) {\n const off = baseColorFactorOffset / 4;\n const factor = material.baseColorFactor;\n data[off] = factor ? factor[0]! : 1.0;\n data[off + 1] = factor ? factor[1]! : 1.0;\n data[off + 2] = factor ? factor[2]! : 1.0;\n data[off + 3] = factor ? factor[3]! : 1.0;\n }\n if (spec._offsets.has(\"metallicFactor\")) {\n const off = spec._offsets.get(\"metallicFactor\")! / 4;\n data[off] = material.metallicFactor ?? 1.0;\n data[off + 1] = material.roughnessFactor ?? 1.0;\n data[off + 2] = material.normalTextureScale ?? 1.0;\n data[off + 3] = material.usePhysicalLightFalloff === false ? 0 : 1;\n }\n for (const ext of _getPbrExts().values()) {\n if (ext.writeUbo) {\n ext.writeUbo(data, material, spec._offsets);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -190,7 +190,7 @@ function setShaderTexture(material, name, texture) {
|
|
|
190
190
|
throw new Error(`ShaderMaterial: sampler "${name}" was not declared.`);
|
|
191
191
|
}
|
|
192
192
|
if (texture) {
|
|
193
|
-
const expectsDepth = slot.decl.
|
|
193
|
+
const expectsDepth = slot.decl.comparison || slot.decl.sampleType === "depth";
|
|
194
194
|
const isDepthTexture = texture._sampleType === "depth";
|
|
195
195
|
if (expectsDepth && !isDepthTexture) {
|
|
196
196
|
throw new Error(`ShaderMaterial: sampler "${name}" expects a depth Texture2D.`);
|
|
@@ -199,16 +199,20 @@ function setShaderTexture(material, name, texture) {
|
|
|
199
199
|
throw new Error(`ShaderMaterial: sampler "${name}" cannot use a depth Texture2D.`);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
-
slot.current
|
|
203
|
-
|
|
202
|
+
if (slot.current !== texture) {
|
|
203
|
+
slot.current = texture;
|
|
204
|
+
material._resourceVersion++;
|
|
205
|
+
}
|
|
204
206
|
}
|
|
205
207
|
function setShaderStorageBuffer(material, name, buffer) {
|
|
206
208
|
const slot = material._storageBufferSlots.get(name);
|
|
207
209
|
if (!slot) {
|
|
208
210
|
throw new Error(`ShaderMaterial: storage buffer "${name}" was not declared.`);
|
|
209
211
|
}
|
|
210
|
-
slot.current
|
|
211
|
-
|
|
212
|
+
if (slot.current !== buffer) {
|
|
213
|
+
slot.current = buffer;
|
|
214
|
+
material._resourceVersion++;
|
|
215
|
+
}
|
|
212
216
|
}
|
|
213
217
|
function setShaderFloat(material, name, value) {
|
|
214
218
|
setShaderUniform(material, name, value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-material.js","sources":["../../../../src/material/shader/shader-material.ts"],"sourcesContent":["import { F32 } from \"../../engine/typed-arrays.js\";\nimport type { Material, StencilState } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport { getShaderGroupBuilder } from \"./shader-group-builder.js\";\n\n/** Vertex attribute names a ShaderMaterial can bind. */\nexport type ShaderAttributeName = \"position\" | \"normal\" | \"uv\" | \"uv2\" | \"tangent\" | \"color\";\n/** WGSL scalar/vector/matrix types supported for ShaderMaterial uniforms. */\nexport type ShaderUniformType = \"f32\" | \"u32\" | \"i32\" | \"vec2<f32>\" | \"vec3<f32>\" | \"vec4<f32>\" | \"mat4x4<f32>\";\n/** Built-in uniform names automatically populated by the renderer each frame\n * (transforms, camera position, screen size, alpha cutoff). */\nexport type ShaderSystemUniformName = \"world\" | \"view\" | \"projection\" | \"viewProjection\" | \"worldView\" | \"worldViewProjection\" | \"cameraPosition\" | \"screenSize\" | \"alphaCutoff\";\n/** A uniform entry: either a system uniform name or an explicit custom declaration. */\nexport type ShaderUniformOption = ShaderSystemUniformName | ShaderUniformDecl;\n/** Accepted value shape when setting a ShaderMaterial uniform. */\nexport type ShaderUniformValue = number | readonly number[] | Float32Array;\n/** A sampler entry: either a bare sampler name or an explicit declaration. */\nexport type ShaderSamplerOption = string | ShaderSamplerDecl;\n/** A storage-buffer entry: a read-only WGSL storage binding declaration. */\nexport type ShaderStorageBufferOption = ShaderStorageBufferDecl;\n/** Value of a WGSL preprocessor define — boolean toggle or numeric constant. */\nexport type ShaderDefineValue = boolean | number;\n/** Map of WGSL preprocessor define names to their values. */\nexport type ShaderDefineMap = Readonly<Record<string, ShaderDefineValue>>;\n\n/** Options describing a ShaderMaterial: WGSL sources, attributes, uniforms,\n * samplers, defines, and blend/depth state. Passed to `createShaderMaterial()`. */\nexport interface ShaderMaterialOptions {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniforms?: readonly ShaderUniformOption[];\n readonly samplers?: readonly ShaderSamplerOption[];\n readonly storageBuffers?: readonly ShaderStorageBufferOption[];\n readonly defines?: ShaderDefineMap;\n readonly needAlphaBlending?: boolean;\n /** Blend equation used when `needAlphaBlending` is set. \"alpha\" (default) is\n * standard src-over; \"additive\" adds the fragment's premultiplied-by-alpha\n * color to the framebuffer, which is the right choice for glows/light FX. */\n readonly blendMode?: \"alpha\" | \"additive\";\n /** Mark this surface as transmissive/refractive: the renderer grabs the opaque scene color\n * behind it just before it draws, so the fragment can sample what is *through* it (water,\n * glass). Requires `needAlphaBlending` (the surface composites over the grabbed scene\n * color). Enable the scene-color grab on the surface's render task with\n * `enableRenderTaskTransmission`, then bind the resulting texture via `setShaderTexture`.\n * Default false. */\n readonly transmissive?: boolean;\n readonly needAlphaTesting?: boolean;\n readonly backFaceCulling?: boolean;\n readonly depthWrite?: boolean;\n readonly depthCompare?: GPUCompareFunction;\n /** Compile/run the fragment stage even for depth-only render targets (no colour attachments).\n * Use for depth-only casters that need `discard` (alpha/clip masks). The fragment shader must not\n * declare colour outputs when drawn into a depth-only target. Default false. */\n readonly depthOnlyFragment?: boolean;\n /** Constant depth-bias added in the pipeline's depth-stencil state (units of the depth format's minimum\n * representable value). Lets a surface that hugs another (e.g. tiles overlapping a cone, decals) win the\n * depth test consistently and avoid z-fighting. Default 0 (no bias). */\n readonly depthBias?: number;\n /** Slope-scaled depth bias — extra bias proportional to the depth gradient, so steeply-angled (grazing)\n * surfaces get more bias. Pairs with `depthBias` to kill z-fighting at oblique angles. Default 0. */\n readonly depthBiasSlopeScale?: number;\n}\n\n/** A custom uniform declaration: WGSL identifier, type, and optional default. */\nexport interface ShaderUniformDecl {\n readonly name: string;\n readonly type: ShaderUniformType;\n readonly defaultValue?: number | readonly number[];\n}\n\n/** A sampler declaration: WGSL identifier and the bound texture's sample type. */\nexport interface ShaderSamplerDecl {\n readonly name: string;\n readonly sampleType?: \"float\" | \"unfilterable-float\" | \"depth\";\n /** Texture view dimension. Default \"2d\". Use \"2d-array\" for layered maps such as\n * cascaded-shadow (CSM) depth arrays. */\n readonly viewDimension?: \"2d\" | \"2d-array\";\n /** Bind a hardware comparison sampler (`sampler_comparison`) for depth compare / PCF\n * filtering. Implies a depth texture. Default false. */\n readonly comparison?: boolean;\n}\n\n/** A storage buffer declaration. `type` is the WGSL variable type, e.g. `array<vec4<f32>>`. */\nexport interface ShaderStorageBufferDecl {\n readonly name: string;\n readonly type: string;\n}\n\n/** A resolved WGSL preprocessor define (name + value). */\nexport interface ShaderDefine {\n readonly name: string;\n readonly value: ShaderDefineValue;\n}\n\nexport interface ShaderUniformSlot {\n readonly decl: ShaderUniformDecl;\n readonly value: Float32Array;\n}\n\nexport interface ShaderTextureSlot {\n readonly decl: ShaderSamplerDecl;\n current: Texture2D | null;\n}\n\nexport interface ShaderStorageBufferSlot {\n readonly decl: ShaderStorageBufferDecl;\n current: GPUBuffer | null;\n}\n\n/** A custom WGSL material: compiled from user-supplied vertex/fragment sources\n * with declared attributes, uniforms, samplers, and defines. Update its values\n * via `setShaderUniform()` / `setShaderTexture()` and friends. */\nexport interface ShaderMaterial extends Material {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniformDecls: readonly ShaderUniformDecl[];\n readonly samplerDecls: readonly ShaderSamplerDecl[];\n readonly storageBufferDecls: readonly ShaderStorageBufferDecl[];\n readonly defines: readonly ShaderDefine[];\n readonly needAlphaBlending: boolean;\n readonly blendMode: \"alpha\" | \"additive\";\n /** True for transmissive/refractive surfaces (see `ShaderMaterialOptions.transmissive`). */\n readonly transmissive: boolean;\n readonly needAlphaTesting: boolean;\n readonly backFaceCulling: boolean;\n readonly depthWrite: boolean;\n readonly depthCompare: GPUCompareFunction;\n readonly depthOnlyFragment: boolean;\n readonly depthBias: number;\n readonly depthBiasSlopeScale: number;\n /** Optional stencil-test state baked into the main-pass pipeline (mask write / discard). Set after\n * creation (`mat.stencil = { ... }`) and call `enableMaterialStencil()` before `registerScene`. Default\n * none. See `StencilState`. */\n stencil?: StencilState;\n /** @internal */\n _uniformValues: Map<string, ShaderUniformSlot>;\n /** @internal */\n _textureSlots: Map<string, ShaderTextureSlot>;\n /** @internal */\n _storageBufferSlots: Map<string, ShaderStorageBufferSlot>;\n /** @internal */\n _uniformVersion: number;\n /** @internal */\n _resourceVersion: number;\n}\n\nfunction isIdentifier(name: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n}\n\nfunction assertIdentifier(kind: string, name: string): void {\n if (!isIdentifier(name)) {\n throw new Error(`ShaderMaterial: ${kind} name \"${name}\" is not a valid WGSL identifier.`);\n }\n}\n\nfunction isSupportedAttribute(name: string): name is ShaderAttributeName {\n return name === \"position\" || name === \"normal\" || name === \"uv\" || name === \"uv2\" || name === \"tangent\" || name === \"color\";\n}\n\nfunction isSystemUniform(name: string): name is ShaderSystemUniformName {\n return (\n name === \"world\" ||\n name === \"view\" ||\n name === \"projection\" ||\n name === \"viewProjection\" ||\n name === \"worldView\" ||\n name === \"worldViewProjection\" ||\n name === \"cameraPosition\" ||\n name === \"screenSize\" ||\n name === \"alphaCutoff\"\n );\n}\n\nfunction systemUniformType(name: ShaderSystemUniformName): ShaderUniformType {\n if (name === \"cameraPosition\") {\n return \"vec3<f32>\";\n }\n if (name === \"screenSize\") {\n return \"vec2<f32>\";\n }\n if (name === \"alphaCutoff\") {\n return \"f32\";\n }\n return \"mat4x4<f32>\";\n}\n\nexport function _isShaderSystemUniform(name: string): name is ShaderSystemUniformName {\n return isSystemUniform(name);\n}\n\n/** Create a ShaderMaterial from WGSL sources and declarations, validating\n * attributes, uniforms, samplers, and defines.\n * @param options - Sources, attributes, uniforms, samplers, defines, and render state.\n * @returns The constructed `ShaderMaterial`. */\nexport function createShaderMaterial(options: ShaderMaterialOptions): ShaderMaterial {\n if (!options.vertexSource || !options.fragmentSource) {\n throw new Error(\"ShaderMaterial: vertexSource and fragmentSource must be non-empty WGSL strings.\");\n }\n const attributes: ShaderAttributeName[] = [];\n const seenAttributes = new Set<string>();\n for (const attr of options.attributes) {\n if (!isSupportedAttribute(attr)) {\n throw new Error(`ShaderMaterial: unsupported attribute \"${String(attr)}\". Supported attributes: position, normal, uv, uv2, tangent, color.`);\n }\n if (seenAttributes.has(attr)) {\n throw new Error(`ShaderMaterial: duplicate attribute \"${attr}\".`);\n }\n seenAttributes.add(attr);\n attributes.push(attr);\n }\n if (!seenAttributes.has(\"position\")) {\n throw new Error('ShaderMaterial: \"position\" attribute is required for mesh rendering.');\n }\n\n const uniformDecls: ShaderUniformDecl[] = [];\n const uniformValues = new Map<string, ShaderUniformSlot>();\n const usedNames = new Set<string>();\n for (const opt of options.uniforms ?? []) {\n const decl = typeof opt === \"string\" ? normalizeSystemUniform(opt) : normalizeCustomUniform(opt);\n assertUniqueName(usedNames, \"uniform\", decl.name);\n uniformDecls.push(decl);\n uniformValues.set(decl.name, { decl, value: normalizeUniformValue(decl, decl.defaultValue ?? defaultUniformValue(decl)) });\n }\n\n const samplerDecls: ShaderSamplerDecl[] = [];\n const textureSlots = new Map<string, ShaderTextureSlot>();\n for (const opt of options.samplers ?? []) {\n const decl: ShaderSamplerDecl =\n typeof opt === \"string\"\n ? { name: opt, sampleType: \"float\" }\n : {\n name: opt.name,\n sampleType: opt.sampleType ?? (opt.comparison ? \"depth\" : \"float\"),\n viewDimension: opt.viewDimension ?? \"2d\",\n comparison: opt.comparison ?? false,\n };\n assertIdentifier(\"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", `${decl.name}Sampler`);\n samplerDecls.push(decl);\n textureSlots.set(decl.name, { decl, current: null });\n }\n\n const storageBufferDecls: ShaderStorageBufferDecl[] = [];\n const storageBufferSlots = new Map<string, ShaderStorageBufferSlot>();\n for (const opt of options.storageBuffers ?? []) {\n assertIdentifier(\"storage buffer\", opt.name);\n assertUniqueName(usedNames, \"storage buffer\", opt.name);\n storageBufferDecls.push(opt);\n storageBufferSlots.set(opt.name, { decl: opt, current: null });\n }\n\n const defines: ShaderDefine[] = [];\n for (const [name, value] of Object.entries(options.defines ?? {})) {\n assertIdentifier(\"define\", name);\n assertUniqueName(usedNames, \"define\", name);\n if (typeof value !== \"boolean\" && typeof value !== \"number\") {\n throw new Error(`ShaderMaterial: define \"${name}\" must be a boolean or number.`);\n }\n defines.push({ name, value });\n }\n defines.sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.transmissive && !(options.needAlphaBlending ?? false)) {\n throw new Error(\"ShaderMaterial: `transmissive` requires `needAlphaBlending` (the surface composites over the grabbed opaque scene color).\");\n }\n\n return {\n name: options.name,\n vertexSource: options.vertexSource,\n fragmentSource: options.fragmentSource,\n attributes,\n uniformDecls,\n samplerDecls,\n storageBufferDecls,\n defines,\n needAlphaBlending: options.needAlphaBlending ?? false,\n blendMode: options.blendMode ?? \"alpha\",\n transmissive: options.transmissive ?? false,\n needAlphaTesting: options.needAlphaTesting ?? false,\n backFaceCulling: options.backFaceCulling ?? true,\n depthWrite: options.depthWrite ?? true,\n depthCompare: options.depthCompare ?? \"greater-equal\",\n depthOnlyFragment: options.depthOnlyFragment ?? false,\n depthBias: options.depthBias ?? 0,\n depthBiasSlopeScale: options.depthBiasSlopeScale ?? 0,\n _buildGroup: getShaderGroupBuilder(),\n _uboVersion: 0,\n _uniformValues: uniformValues,\n _textureSlots: textureSlots,\n _storageBufferSlots: storageBufferSlots,\n _uniformVersion: 0,\n _resourceVersion: 0,\n };\n}\n\nfunction normalizeSystemUniform(name: string): ShaderUniformDecl {\n if (!isSystemUniform(name)) {\n throw new Error(`ShaderMaterial: custom uniform \"${name}\" must use an explicit typed declaration.`);\n }\n return { name, type: systemUniformType(name) };\n}\n\nfunction normalizeCustomUniform(decl: ShaderUniformDecl): ShaderUniformDecl {\n assertIdentifier(\"uniform\", decl.name);\n if (!isUniformType(decl.type)) {\n throw new Error(`ShaderMaterial: unsupported uniform type \"${String(decl.type)}\" for \"${decl.name}\".`);\n }\n return decl;\n}\n\nfunction isUniformType(type: string): type is ShaderUniformType {\n return type === \"f32\" || type === \"u32\" || type === \"i32\" || type === \"vec2<f32>\" || type === \"vec3<f32>\" || type === \"vec4<f32>\" || type === \"mat4x4<f32>\";\n}\n\nfunction assertUniqueName(usedNames: Set<string>, kind: string, name: string): void {\n if (usedNames.has(name)) {\n throw new Error(`ShaderMaterial: duplicate generated identifier \"${name}\" while adding ${kind}.`);\n }\n usedNames.add(name);\n}\n\nfunction elementCount(type: ShaderUniformType): number {\n switch (type) {\n case \"f32\":\n case \"u32\":\n case \"i32\":\n return 1;\n case \"vec2<f32>\":\n return 2;\n case \"vec3<f32>\":\n return 3;\n case \"vec4<f32>\":\n return 4;\n case \"mat4x4<f32>\":\n return 16;\n }\n}\n\nfunction defaultUniformValue(decl: ShaderUniformDecl): ShaderUniformValue {\n if (decl.name === \"alphaCutoff\") {\n return 0.4;\n }\n const count = elementCount(decl.type);\n return count === 1 ? 0 : new Array(count).fill(0);\n}\n\nfunction normalizeUniformValue(decl: ShaderUniformDecl, value: ShaderUniformValue): Float32Array {\n const count = elementCount(decl.type);\n const arr = typeof value === \"number\" ? new F32([value]) : value instanceof F32 ? new F32(value) : new F32(value);\n if (arr.length !== count) {\n throw new Error(`ShaderMaterial: uniform \"${decl.name}\" of type ${decl.type} expects ${count} value(s), got ${arr.length}.`);\n }\n return arr;\n}\n\n/** Set a declared uniform's value, validating its element count against the\n * declared type and bumping the material's UBO version.\n * @param material - Target material.\n * @param name - Declared uniform name.\n * @param value - New value (scalar, array, or `Float32Array`). */\nexport function setShaderUniform(material: ShaderMaterial, name: string, value: ShaderUniformValue): void {\n const slot = material._uniformValues.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: uniform \"${name}\" was not declared.`);\n }\n slot.value.set(normalizeUniformValue(slot.decl, value));\n material._uniformVersion++;\n material._uboVersion = material._uniformVersion;\n}\n\n/** Bind (or clear) the texture for a declared sampler, enforcing that depth and\n * non-depth samplers receive a matching `Texture2D`.\n * @param material - Target material.\n * @param name - Declared sampler name.\n * @param texture - Texture to bind, or `null` to clear. */\nexport function setShaderTexture(material: ShaderMaterial, name: string, texture: Texture2D | null): void {\n const slot = material._textureSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" was not declared.`);\n }\n if (texture) {\n const expectsDepth = slot.decl.sampleType === \"depth\" || slot.decl.comparison === true;\n const isDepthTexture = texture._sampleType === \"depth\";\n if (expectsDepth && !isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" expects a depth Texture2D.`);\n }\n if (!expectsDepth && isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" cannot use a depth Texture2D.`);\n }\n }\n slot.current = texture;\n material._resourceVersion++;\n}\n\n/** Bind (or clear) a declared read-only storage buffer. */\nexport function setShaderStorageBuffer(material: ShaderMaterial, name: string, buffer: GPUBuffer | null): void {\n const slot = material._storageBufferSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: storage buffer \"${name}\" was not declared.`);\n }\n slot.current = buffer;\n material._resourceVersion++;\n}\n\n/** Set a declared `f32` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderFloat(material: ShaderMaterial, name: string, value: number): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `vec3<f32>` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderVector3(material: ShaderMaterial, name: string, value: readonly [number, number, number]): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `mat4x4<f32>` uniform. Convenience wrapper over `setShaderUniform()`.\n * Accepts a raw `Float32Array` or the engine's branded `Mat4` (e.g. the result of\n * `getViewProjectionMatrix()` / `mat4Invert()`), so camera/math matrices can be fed\n * straight into a matrix uniform without laundering through a typed array. */\nexport function setShaderMatrix(material: ShaderMaterial, name: string, value: Float32Array | Mat4): void {\n setShaderUniform(material, name, value instanceof Float32Array ? value : Array.from(value));\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shader-material.js","sources":["../../../../src/material/shader/shader-material.ts"],"sourcesContent":["import { F32 } from \"../../engine/typed-arrays.js\";\nimport type { Material, StencilState } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport { getShaderGroupBuilder } from \"./shader-group-builder.js\";\n\n/** Vertex attribute names a ShaderMaterial can bind. */\nexport type ShaderAttributeName = \"position\" | \"normal\" | \"uv\" | \"uv2\" | \"tangent\" | \"color\";\n/** WGSL scalar/vector/matrix types supported for ShaderMaterial uniforms. */\nexport type ShaderUniformType = \"f32\" | \"u32\" | \"i32\" | \"vec2<f32>\" | \"vec3<f32>\" | \"vec4<f32>\" | \"mat4x4<f32>\";\n/** Built-in uniform names automatically populated by the renderer each frame\n * (transforms, camera position, screen size, alpha cutoff). */\nexport type ShaderSystemUniformName = \"world\" | \"view\" | \"projection\" | \"viewProjection\" | \"worldView\" | \"worldViewProjection\" | \"cameraPosition\" | \"screenSize\" | \"alphaCutoff\";\n/** A uniform entry: either a system uniform name or an explicit custom declaration. */\nexport type ShaderUniformOption = ShaderSystemUniformName | ShaderUniformDecl;\n/** Accepted value shape when setting a ShaderMaterial uniform. */\nexport type ShaderUniformValue = number | readonly number[] | Float32Array;\n/** A sampler entry: either a bare sampler name or an explicit declaration. */\nexport type ShaderSamplerOption = string | ShaderSamplerDecl;\n/** A storage-buffer entry: a read-only WGSL storage binding declaration. */\nexport type ShaderStorageBufferOption = ShaderStorageBufferDecl;\n/** Value of a WGSL preprocessor define — boolean toggle or numeric constant. */\nexport type ShaderDefineValue = boolean | number;\n/** Map of WGSL preprocessor define names to their values. */\nexport type ShaderDefineMap = Readonly<Record<string, ShaderDefineValue>>;\n\n/** Options describing a ShaderMaterial: WGSL sources, attributes, uniforms,\n * samplers, defines, and blend/depth state. Passed to `createShaderMaterial()`. */\nexport interface ShaderMaterialOptions {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniforms?: readonly ShaderUniformOption[];\n readonly samplers?: readonly ShaderSamplerOption[];\n readonly storageBuffers?: readonly ShaderStorageBufferOption[];\n readonly defines?: ShaderDefineMap;\n readonly needAlphaBlending?: boolean;\n /** Blend equation used when `needAlphaBlending` is set. \"alpha\" (default) is\n * standard src-over; \"additive\" adds the fragment's premultiplied-by-alpha\n * color to the framebuffer, which is the right choice for glows/light FX. */\n readonly blendMode?: \"alpha\" | \"additive\";\n /** Mark this surface as transmissive/refractive: the renderer grabs the opaque scene color\n * behind it just before it draws, so the fragment can sample what is *through* it (water,\n * glass). Requires `needAlphaBlending` (the surface composites over the grabbed scene\n * color). Enable the scene-color grab on the surface's render task with\n * `enableRenderTaskTransmission`, then bind the resulting texture via `setShaderTexture`.\n * Default false. */\n readonly transmissive?: boolean;\n readonly needAlphaTesting?: boolean;\n readonly backFaceCulling?: boolean;\n readonly depthWrite?: boolean;\n readonly depthCompare?: GPUCompareFunction;\n /** Compile/run the fragment stage even for depth-only render targets (no colour attachments).\n * Use for depth-only casters that need `discard` (alpha/clip masks). The fragment shader must not\n * declare colour outputs when drawn into a depth-only target. Default false. */\n readonly depthOnlyFragment?: boolean;\n /** Constant depth-bias added in the pipeline's depth-stencil state (units of the depth format's minimum\n * representable value). Lets a surface that hugs another (e.g. tiles overlapping a cone, decals) win the\n * depth test consistently and avoid z-fighting. Default 0 (no bias). */\n readonly depthBias?: number;\n /** Slope-scaled depth bias — extra bias proportional to the depth gradient, so steeply-angled (grazing)\n * surfaces get more bias. Pairs with `depthBias` to kill z-fighting at oblique angles. Default 0. */\n readonly depthBiasSlopeScale?: number;\n}\n\n/** A custom uniform declaration: WGSL identifier, type, and optional default. */\nexport interface ShaderUniformDecl {\n readonly name: string;\n readonly type: ShaderUniformType;\n readonly defaultValue?: number | readonly number[];\n}\n\n/** A sampler declaration: WGSL identifier and the bound texture's sample type. */\nexport interface ShaderSamplerDecl {\n readonly name: string;\n readonly sampleType?: \"float\" | \"unfilterable-float\" | \"depth\";\n /** Texture view dimension. Default \"2d\". Use \"2d-array\" for layered maps such as\n * cascaded-shadow (CSM) depth arrays. */\n readonly viewDimension?: \"2d\" | \"2d-array\";\n /** Bind a hardware comparison sampler (`sampler_comparison`) for depth compare / PCF\n * filtering. Implies a depth texture. Default false. */\n readonly comparison?: boolean;\n}\n\n/** A storage buffer declaration. `type` is the WGSL variable type, e.g. `array<vec4<f32>>`. */\nexport interface ShaderStorageBufferDecl {\n readonly name: string;\n readonly type: string;\n}\n\n/** A resolved WGSL preprocessor define (name + value). */\nexport interface ShaderDefine {\n readonly name: string;\n readonly value: ShaderDefineValue;\n}\n\nexport interface ShaderUniformSlot {\n readonly decl: ShaderUniformDecl;\n readonly value: Float32Array;\n}\n\nexport interface ShaderTextureSlot {\n readonly decl: ShaderSamplerDecl;\n current: Texture2D | null;\n}\n\nexport interface ShaderStorageBufferSlot {\n readonly decl: ShaderStorageBufferDecl;\n current: GPUBuffer | null;\n}\n\n/** A custom WGSL material: compiled from user-supplied vertex/fragment sources\n * with declared attributes, uniforms, samplers, and defines. Update its values\n * via `setShaderUniform()` / `setShaderTexture()` and friends. */\nexport interface ShaderMaterial extends Material {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniformDecls: readonly ShaderUniformDecl[];\n readonly samplerDecls: readonly ShaderSamplerDecl[];\n readonly storageBufferDecls: readonly ShaderStorageBufferDecl[];\n readonly defines: readonly ShaderDefine[];\n readonly needAlphaBlending: boolean;\n readonly blendMode: \"alpha\" | \"additive\";\n /** True for transmissive/refractive surfaces (see `ShaderMaterialOptions.transmissive`). */\n readonly transmissive: boolean;\n readonly needAlphaTesting: boolean;\n readonly backFaceCulling: boolean;\n readonly depthWrite: boolean;\n readonly depthCompare: GPUCompareFunction;\n readonly depthOnlyFragment: boolean;\n readonly depthBias: number;\n readonly depthBiasSlopeScale: number;\n /** Optional stencil-test state baked into the main-pass pipeline (mask write / discard). Set after\n * creation (`mat.stencil = { ... }`) and call `enableMaterialStencil()` before `registerScene`. Default\n * none. See `StencilState`. */\n stencil?: StencilState;\n /** @internal */\n _uniformValues: Map<string, ShaderUniformSlot>;\n /** @internal */\n _textureSlots: Map<string, ShaderTextureSlot>;\n /** @internal */\n _storageBufferSlots: Map<string, ShaderStorageBufferSlot>;\n /** @internal */\n _uniformVersion: number;\n /** @internal */\n _resourceVersion: number;\n}\n\nfunction isIdentifier(name: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n}\n\nfunction assertIdentifier(kind: string, name: string): void {\n if (!isIdentifier(name)) {\n throw new Error(`ShaderMaterial: ${kind} name \"${name}\" is not a valid WGSL identifier.`);\n }\n}\n\nfunction isSupportedAttribute(name: string): name is ShaderAttributeName {\n return name === \"position\" || name === \"normal\" || name === \"uv\" || name === \"uv2\" || name === \"tangent\" || name === \"color\";\n}\n\nfunction isSystemUniform(name: string): name is ShaderSystemUniformName {\n return (\n name === \"world\" ||\n name === \"view\" ||\n name === \"projection\" ||\n name === \"viewProjection\" ||\n name === \"worldView\" ||\n name === \"worldViewProjection\" ||\n name === \"cameraPosition\" ||\n name === \"screenSize\" ||\n name === \"alphaCutoff\"\n );\n}\n\nfunction systemUniformType(name: ShaderSystemUniformName): ShaderUniformType {\n if (name === \"cameraPosition\") {\n return \"vec3<f32>\";\n }\n if (name === \"screenSize\") {\n return \"vec2<f32>\";\n }\n if (name === \"alphaCutoff\") {\n return \"f32\";\n }\n return \"mat4x4<f32>\";\n}\n\nexport function _isShaderSystemUniform(name: string): name is ShaderSystemUniformName {\n return isSystemUniform(name);\n}\n\n/** Create a ShaderMaterial from WGSL sources and declarations, validating\n * attributes, uniforms, samplers, and defines.\n * @param options - Sources, attributes, uniforms, samplers, defines, and render state.\n * @returns The constructed `ShaderMaterial`. */\nexport function createShaderMaterial(options: ShaderMaterialOptions): ShaderMaterial {\n if (!options.vertexSource || !options.fragmentSource) {\n throw new Error(\"ShaderMaterial: vertexSource and fragmentSource must be non-empty WGSL strings.\");\n }\n const attributes: ShaderAttributeName[] = [];\n const seenAttributes = new Set<string>();\n for (const attr of options.attributes) {\n if (!isSupportedAttribute(attr)) {\n throw new Error(`ShaderMaterial: unsupported attribute \"${String(attr)}\". Supported attributes: position, normal, uv, uv2, tangent, color.`);\n }\n if (seenAttributes.has(attr)) {\n throw new Error(`ShaderMaterial: duplicate attribute \"${attr}\".`);\n }\n seenAttributes.add(attr);\n attributes.push(attr);\n }\n if (!seenAttributes.has(\"position\")) {\n throw new Error('ShaderMaterial: \"position\" attribute is required for mesh rendering.');\n }\n\n const uniformDecls: ShaderUniformDecl[] = [];\n const uniformValues = new Map<string, ShaderUniformSlot>();\n const usedNames = new Set<string>();\n for (const opt of options.uniforms ?? []) {\n const decl = typeof opt === \"string\" ? normalizeSystemUniform(opt) : normalizeCustomUniform(opt);\n assertUniqueName(usedNames, \"uniform\", decl.name);\n uniformDecls.push(decl);\n uniformValues.set(decl.name, { decl, value: normalizeUniformValue(decl, decl.defaultValue ?? defaultUniformValue(decl)) });\n }\n\n const samplerDecls: ShaderSamplerDecl[] = [];\n const textureSlots = new Map<string, ShaderTextureSlot>();\n for (const opt of options.samplers ?? []) {\n const decl: ShaderSamplerDecl =\n typeof opt === \"string\"\n ? { name: opt, sampleType: \"float\" }\n : {\n name: opt.name,\n sampleType: opt.sampleType ?? (opt.comparison ? \"depth\" : \"float\"),\n viewDimension: opt.viewDimension ?? \"2d\",\n comparison: opt.comparison ?? false,\n };\n assertIdentifier(\"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", `${decl.name}Sampler`);\n samplerDecls.push(decl);\n textureSlots.set(decl.name, { decl, current: null });\n }\n\n const storageBufferDecls: ShaderStorageBufferDecl[] = [];\n const storageBufferSlots = new Map<string, ShaderStorageBufferSlot>();\n for (const opt of options.storageBuffers ?? []) {\n assertIdentifier(\"storage buffer\", opt.name);\n assertUniqueName(usedNames, \"storage buffer\", opt.name);\n storageBufferDecls.push(opt);\n storageBufferSlots.set(opt.name, { decl: opt, current: null });\n }\n\n const defines: ShaderDefine[] = [];\n for (const [name, value] of Object.entries(options.defines ?? {})) {\n assertIdentifier(\"define\", name);\n assertUniqueName(usedNames, \"define\", name);\n if (typeof value !== \"boolean\" && typeof value !== \"number\") {\n throw new Error(`ShaderMaterial: define \"${name}\" must be a boolean or number.`);\n }\n defines.push({ name, value });\n }\n defines.sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.transmissive && !(options.needAlphaBlending ?? false)) {\n throw new Error(\"ShaderMaterial: `transmissive` requires `needAlphaBlending` (the surface composites over the grabbed opaque scene color).\");\n }\n\n return {\n name: options.name,\n vertexSource: options.vertexSource,\n fragmentSource: options.fragmentSource,\n attributes,\n uniformDecls,\n samplerDecls,\n storageBufferDecls,\n defines,\n needAlphaBlending: options.needAlphaBlending ?? false,\n blendMode: options.blendMode ?? \"alpha\",\n transmissive: options.transmissive ?? false,\n needAlphaTesting: options.needAlphaTesting ?? false,\n backFaceCulling: options.backFaceCulling ?? true,\n depthWrite: options.depthWrite ?? true,\n depthCompare: options.depthCompare ?? \"greater-equal\",\n depthOnlyFragment: options.depthOnlyFragment ?? false,\n depthBias: options.depthBias ?? 0,\n depthBiasSlopeScale: options.depthBiasSlopeScale ?? 0,\n _buildGroup: getShaderGroupBuilder(),\n _uboVersion: 0,\n _uniformValues: uniformValues,\n _textureSlots: textureSlots,\n _storageBufferSlots: storageBufferSlots,\n _uniformVersion: 0,\n _resourceVersion: 0,\n };\n}\n\nfunction normalizeSystemUniform(name: string): ShaderUniformDecl {\n if (!isSystemUniform(name)) {\n throw new Error(`ShaderMaterial: custom uniform \"${name}\" must use an explicit typed declaration.`);\n }\n return { name, type: systemUniformType(name) };\n}\n\nfunction normalizeCustomUniform(decl: ShaderUniformDecl): ShaderUniformDecl {\n assertIdentifier(\"uniform\", decl.name);\n if (!isUniformType(decl.type)) {\n throw new Error(`ShaderMaterial: unsupported uniform type \"${String(decl.type)}\" for \"${decl.name}\".`);\n }\n return decl;\n}\n\nfunction isUniformType(type: string): type is ShaderUniformType {\n return type === \"f32\" || type === \"u32\" || type === \"i32\" || type === \"vec2<f32>\" || type === \"vec3<f32>\" || type === \"vec4<f32>\" || type === \"mat4x4<f32>\";\n}\n\nfunction assertUniqueName(usedNames: Set<string>, kind: string, name: string): void {\n if (usedNames.has(name)) {\n throw new Error(`ShaderMaterial: duplicate generated identifier \"${name}\" while adding ${kind}.`);\n }\n usedNames.add(name);\n}\n\nfunction elementCount(type: ShaderUniformType): number {\n switch (type) {\n case \"f32\":\n case \"u32\":\n case \"i32\":\n return 1;\n case \"vec2<f32>\":\n return 2;\n case \"vec3<f32>\":\n return 3;\n case \"vec4<f32>\":\n return 4;\n case \"mat4x4<f32>\":\n return 16;\n }\n}\n\nfunction defaultUniformValue(decl: ShaderUniformDecl): ShaderUniformValue {\n if (decl.name === \"alphaCutoff\") {\n return 0.4;\n }\n const count = elementCount(decl.type);\n return count === 1 ? 0 : new Array(count).fill(0);\n}\n\nfunction normalizeUniformValue(decl: ShaderUniformDecl, value: ShaderUniformValue): Float32Array {\n const count = elementCount(decl.type);\n const arr = typeof value === \"number\" ? new F32([value]) : value instanceof F32 ? new F32(value) : new F32(value);\n if (arr.length !== count) {\n throw new Error(`ShaderMaterial: uniform \"${decl.name}\" of type ${decl.type} expects ${count} value(s), got ${arr.length}.`);\n }\n return arr;\n}\n\n/** Set a declared uniform's value, validating its element count against the\n * declared type and bumping the material's UBO version.\n * @param material - Target material.\n * @param name - Declared uniform name.\n * @param value - New value (scalar, array, or `Float32Array`). */\nexport function setShaderUniform(material: ShaderMaterial, name: string, value: ShaderUniformValue): void {\n const slot = material._uniformValues.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: uniform \"${name}\" was not declared.`);\n }\n slot.value.set(normalizeUniformValue(slot.decl, value));\n material._uniformVersion++;\n material._uboVersion = material._uniformVersion;\n}\n\n/** Bind (or clear) the texture for a declared sampler, enforcing that depth and\n * non-depth samplers receive a matching `Texture2D`.\n * @param material - Target material.\n * @param name - Declared sampler name.\n * @param texture - Texture to bind, or `null` to clear. */\nexport function setShaderTexture(material: ShaderMaterial, name: string, texture: Texture2D | null): void {\n const slot = material._textureSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" was not declared.`);\n }\n if (texture) {\n const expectsDepth = slot.decl.comparison || slot.decl.sampleType === \"depth\";\n const isDepthTexture = texture._sampleType === \"depth\";\n if (expectsDepth && !isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" expects a depth Texture2D.`);\n }\n if (!expectsDepth && isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" cannot use a depth Texture2D.`);\n }\n }\n // Only invalidate the cached bind groups when the bound texture HANDLE actually changes. The bind group\n // references the texture's view + sampler (see createShaderBindGroup), so re-binding the SAME Texture2D (the\n // common \"keep my shadow map / scene-depth bound every frame\" pattern) leaves those identical. Bumping the\n // resource version unconditionally therefore forced a BRAND-NEW bind group every frame (per material, for every\n // packet using it), churning the D3D12 descriptor heap until it OOMed on content-heavy scenes (e.g. reloading\n // a big save). A texture's CONTENTS can change freely without a new bind group (the bound view is live), so\n // identity comparison is correct.\n if (slot.current !== texture) {\n slot.current = texture;\n material._resourceVersion++;\n }\n}\n\n/** Bind (or clear) a declared read-only storage buffer. */\nexport function setShaderStorageBuffer(material: ShaderMaterial, name: string, buffer: GPUBuffer | null): void {\n const slot = material._storageBufferSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: storage buffer \"${name}\" was not declared.`);\n }\n // See setShaderTexture: only invalidate the bind groups when the bound buffer HANDLE changes; re-binding the\n // same GPUBuffer is a no-op (contents update live), so an unconditional bump churned the descriptor heap.\n if (slot.current !== buffer) {\n slot.current = buffer;\n material._resourceVersion++;\n }\n}\n\n/** Set a declared `f32` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderFloat(material: ShaderMaterial, name: string, value: number): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `vec3<f32>` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderVector3(material: ShaderMaterial, name: string, value: readonly [number, number, number]): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `mat4x4<f32>` uniform. Convenience wrapper over `setShaderUniform()`.\n * Accepts a raw `Float32Array` or the engine's branded `Mat4` (e.g. the result of\n * `getViewProjectionMatrix()` / `mat4Invert()`), so camera/math matrices can be fed\n * straight into a matrix uniform without laundering through a typed array. */\nexport function setShaderMatrix(material: ShaderMaterial, name: string, value: Float32Array | Mat4): void {\n setShaderUniform(material, name, value instanceof Float32Array ? value : Array.from(value));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -95,7 +95,7 @@ function createShaderInstancedRenderable(scene, material, packet, isOverride, h,
|
|
|
95
95
|
const bindings = h.getOrCreateShaderPipelineBindings(eng, material);
|
|
96
96
|
const vertexBuffers = [...bindings.vertexBuffers, ...instanceLayouts];
|
|
97
97
|
const pipeline = h.getOrCreateShaderPipeline(eng, sig, material, bindings, variantKey, vertexBuffers, instanceAttrs);
|
|
98
|
-
const cb = cull?.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update);
|
|
98
|
+
const cb = cull?.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update, sig);
|
|
99
99
|
return {
|
|
100
100
|
renderable: r,
|
|
101
101
|
pipeline,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-thin-instance.js","sources":["../../../../src/material/shader/shader-thin-instance.ts"],"sourcesContent":["/** ShaderMaterial thin-instance support — dynamically imported ONLY when a\n * ShaderMaterial scene actually uses thin instances, so non-instanced scenes pull\n * in zero extra bytes and the shared `shader-renderable.ts` / `shader-pipeline.ts`\n * chunks stay identical to their non-instanced form.\n *\n * The renderable helpers this module needs (packet create/update, attribute\n * buffers, pipeline builders, the plain-mesh builder) are passed in as positional\n * arguments by `buildShaderGroup`, NOT imported. Importing them would force the\n * shared chunk to export them, which de-mangles their names and grows every\n * ShaderMaterial scene's bundle. As parameters they keep their mangled identity in\n * the shared chunk and are only named here, in this culling/instancing-only chunk.\n *\n * The instance buffer layout MUST match the buffers produced by\n * `thin-instance-gpu.ts` (matrix buffer arrayStride 64, 4x float32x4 at offsets\n * 0/16/32/48; color buffer arrayStride 16, float32x4 at offset 0). */\n\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Material } from \"../material.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { DrawUpdateContext, MeshGroupBuildResult, Renderable } from \"../../render/renderable.js\";\nimport type { ShaderAttributeName, ShaderMaterial } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport type { ShaderPacket, ShaderRenderPass } from \"./shader-renderable.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\ntype CullModule = typeof import(\"../../mesh/thin-instance-cull-binding.js\");\n\n/** The shader-renderable helpers handed in positionally by `buildShaderGroup`. */\ninterface ShaderHelpers {\n buildPlain: (scene: SceneContext, meshes: Mesh[]) => MeshGroupBuildResult;\n createPacket: (scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh) => ShaderPacket;\n updatePacket: (scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext) => void;\n updateCustomUbo: (engine: EngineContext, material: ShaderMaterial) => void;\n getAttrBuffer: (engine: EngineContext, gpu: MeshGPU, name: ShaderAttributeName) => GPUBuffer;\n getOrCreateShaderPipeline: (\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey?: string,\n vertexBuffers?: readonly GPUVertexBufferLayout[],\n instanceAttrs?: string\n ) => GPURenderPipeline;\n getOrCreateShaderPipelineBindings: (engine: EngineContext, material: ShaderMaterial) => ShaderPipelineBindings;\n}\n\n/** Instance vertex buffer layouts. `baseLocation` is the first free shader\n * location after the material's own attributes. */\nfunction instanceVertexLayouts(baseLocation: number, hasColor: boolean): GPUVertexBufferLayout[] {\n const layouts: GPUVertexBufferLayout[] = [\n {\n arrayStride: 64,\n stepMode: \"instance\",\n attributes: [\n { shaderLocation: baseLocation, offset: 0, format: \"float32x4\" },\n { shaderLocation: baseLocation + 1, offset: 16, format: \"float32x4\" },\n { shaderLocation: baseLocation + 2, offset: 32, format: \"float32x4\" },\n { shaderLocation: baseLocation + 3, offset: 48, format: \"float32x4\" },\n ],\n },\n ];\n if (hasColor) {\n layouts.push({\n arrayStride: 16,\n stepMode: \"instance\",\n attributes: [{ shaderLocation: baseLocation + 4, offset: 0, format: \"float32x4\" }],\n });\n }\n return layouts;\n}\n\n/** WGSL lines appended inside `VertexInput` for instanced variants. */\nfunction instancePreludeAttributes(baseLocation: number, hasColor: boolean): string {\n let wgsl = `@location(${baseLocation}) world0: vec4<f32>,\n@location(${baseLocation + 1}) world1: vec4<f32>,\n@location(${baseLocation + 2}) world2: vec4<f32>,\n@location(${baseLocation + 3}) world3: vec4<f32>,\n`;\n if (hasColor) {\n wgsl += `@location(${baseLocation + 4}) instanceColor: vec4<f32>,\n`;\n }\n return wgsl;\n}\n\n/** Build ONE thin-instance renderable for a ShaderMaterial mesh (opaque or\n * transparent). Marked `_direct` so instance buffers are re-bound fresh each\n * frame; this also prepares the renderable for opaque-only GPU culling. */\nfunction createShaderInstancedRenderable(\n scene: SceneContext,\n material: ShaderMaterial,\n packet: ShaderPacket,\n isOverride: boolean,\n h: ShaderHelpers,\n cull?: CullModule\n): Renderable {\n const isTransparent = material.needAlphaBlending;\n const mesh = packet.mesh;\n const ti = mesh.thinInstances!;\n const hasColor = !!ti.colors;\n const baseLocation = material.attributes.length;\n const instanceLayouts = instanceVertexLayouts(baseLocation, hasColor);\n const instanceAttrs = instancePreludeAttributes(baseLocation, hasColor);\n const variantKey = `|ti1c${hasColor ? 1 : 0}`;\n const wm = mesh.worldMatrix as unknown as ArrayLike<number>;\n const sortCenter: [number, number, number] = [wm[12]!, wm[13]!, wm[14]!];\n const update = (context: DrawUpdateContext): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && mesh.material !== material) {\n return;\n }\n h.updateCustomUbo(scene.surface.engine, material);\n h.updatePacket(scene, material, packet, context);\n if (isTransparent) {\n const m = mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext, cullBinding?: import(\"../../mesh/thin-instance-cull-binding.js\").TiCullBinding): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && mesh.material !== material) {\n return 0;\n }\n if (ti.count <= 0) {\n return 0;\n }\n const gpu = mesh._gpu;\n let slot = 0;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(slot++, h.getAttrBuffer(engine, gpu, material.attributes[i]!));\n }\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, cullBinding?.cullDrawBufs);\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n if (cullBinding) {\n cullBinding.draw(pass, gpu.indexCount, ti.count);\n } else {\n pass.drawIndexed(gpu.indexCount, ti.count);\n }\n return 1;\n };\n const r: Renderable = {\n order: mesh.renderOrder ?? (isTransparent ? 200 : 100),\n isTransparent,\n mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = h.getOrCreateShaderPipelineBindings(eng, material);\n const vertexBuffers = [...bindings.vertexBuffers, ...instanceLayouts];\n const pipeline = h.getOrCreateShaderPipeline(eng, sig, material, bindings, variantKey, vertexBuffers, instanceAttrs);\n const cb = cull?.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update);\n return {\n renderable: r,\n pipeline,\n update: cb ? cb.update : update,\n draw: (pass) => draw(pass, eng, cb),\n };\n },\n };\n (r as { _direct?: boolean })._direct = true;\n return r;\n}\n\n/** Build one instanced renderable for `mesh` (used by the combined `rebuildSingle`). */\nfunction buildInstancedSingle(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean, h: ShaderHelpers, cull?: CullModule): Renderable {\n const bindings = h.getOrCreateShaderPipelineBindings(scene.surface.engine, material);\n const packet = h.createPacket(scene, material, bindings.systemSpec, mesh);\n return createShaderInstancedRenderable(scene, material, packet, isOverride, h, cull);\n}\n\n/** Group entry point used whenever a ShaderMaterial scene has at least one\n * thin-instanced mesh. Plain meshes flow through the passed-in `buildPlain`\n * (`buildShaderMaterialRenderables`); instanced meshes get a dedicated renderable. */\nexport function buildShaderRenderablesWithInstancing(\n scene: SceneContext,\n meshes: Mesh[],\n buildPlain: ShaderHelpers[\"buildPlain\"],\n createPacket: ShaderHelpers[\"createPacket\"],\n updatePacket: ShaderHelpers[\"updatePacket\"],\n updateCustomUbo: ShaderHelpers[\"updateCustomUbo\"],\n getAttrBuffer: ShaderHelpers[\"getAttrBuffer\"],\n getOrCreateShaderPipeline: ShaderHelpers[\"getOrCreateShaderPipeline\"],\n getOrCreateShaderPipelineBindings: ShaderHelpers[\"getOrCreateShaderPipelineBindings\"],\n cull?: CullModule\n): MeshGroupBuildResult {\n const h: ShaderHelpers = { buildPlain, createPacket, updatePacket, updateCustomUbo, getAttrBuffer, getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings };\n const instanced: Mesh[] = [];\n const plain: Mesh[] = [];\n for (const mesh of meshes) {\n if (mesh.thinInstances) {\n instanced.push(mesh);\n } else {\n plain.push(mesh);\n }\n }\n\n const renderables: Renderable[] = [];\n let plainRebuild: MeshGroupBuildResult[\"rebuildSingle\"] | undefined;\n if (plain.length > 0) {\n const plainResult = buildPlain(scene, plain);\n renderables.push(...plainResult.renderables);\n plainRebuild = plainResult.rebuildSingle;\n }\n for (const mesh of instanced) {\n renderables.push(buildInstancedSingle(scene, mesh, mesh.material as ShaderMaterial, false, h, cull));\n }\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const material = (materialOverride ?? mesh.material) as ShaderMaterial;\n if (mesh.thinInstances) {\n return buildInstancedSingle(s, mesh, material, materialOverride != null, h, cull);\n }\n if (plainRebuild) {\n return plainRebuild(s, mesh, materialOverride);\n }\n return buildPlain(s, [mesh]).rebuildSingle(s, mesh, materialOverride);\n };\n\n return { renderables, rebuildSingle };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shader-thin-instance.js","sources":["../../../../src/material/shader/shader-thin-instance.ts"],"sourcesContent":["/** ShaderMaterial thin-instance support — dynamically imported ONLY when a\n * ShaderMaterial scene actually uses thin instances, so non-instanced scenes pull\n * in zero extra bytes and the shared `shader-renderable.ts` / `shader-pipeline.ts`\n * chunks stay identical to their non-instanced form.\n *\n * The renderable helpers this module needs (packet create/update, attribute\n * buffers, pipeline builders, the plain-mesh builder) are passed in as positional\n * arguments by `buildShaderGroup`, NOT imported. Importing them would force the\n * shared chunk to export them, which de-mangles their names and grows every\n * ShaderMaterial scene's bundle. As parameters they keep their mangled identity in\n * the shared chunk and are only named here, in this culling/instancing-only chunk.\n *\n * The instance buffer layout MUST match the buffers produced by\n * `thin-instance-gpu.ts` (matrix buffer arrayStride 64, 4x float32x4 at offsets\n * 0/16/32/48; color buffer arrayStride 16, float32x4 at offset 0). */\n\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Material } from \"../material.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { DrawUpdateContext, MeshGroupBuildResult, Renderable } from \"../../render/renderable.js\";\nimport type { ShaderAttributeName, ShaderMaterial } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport type { ShaderPacket, ShaderRenderPass } from \"./shader-renderable.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\ntype CullModule = typeof import(\"../../mesh/thin-instance-cull-binding.js\");\n\n/** The shader-renderable helpers handed in positionally by `buildShaderGroup`. */\ninterface ShaderHelpers {\n buildPlain: (scene: SceneContext, meshes: Mesh[]) => MeshGroupBuildResult;\n createPacket: (scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh) => ShaderPacket;\n updatePacket: (scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext) => void;\n updateCustomUbo: (engine: EngineContext, material: ShaderMaterial) => void;\n getAttrBuffer: (engine: EngineContext, gpu: MeshGPU, name: ShaderAttributeName) => GPUBuffer;\n getOrCreateShaderPipeline: (\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey?: string,\n vertexBuffers?: readonly GPUVertexBufferLayout[],\n instanceAttrs?: string\n ) => GPURenderPipeline;\n getOrCreateShaderPipelineBindings: (engine: EngineContext, material: ShaderMaterial) => ShaderPipelineBindings;\n}\n\n/** Instance vertex buffer layouts. `baseLocation` is the first free shader\n * location after the material's own attributes. */\nfunction instanceVertexLayouts(baseLocation: number, hasColor: boolean): GPUVertexBufferLayout[] {\n const layouts: GPUVertexBufferLayout[] = [\n {\n arrayStride: 64,\n stepMode: \"instance\",\n attributes: [\n { shaderLocation: baseLocation, offset: 0, format: \"float32x4\" },\n { shaderLocation: baseLocation + 1, offset: 16, format: \"float32x4\" },\n { shaderLocation: baseLocation + 2, offset: 32, format: \"float32x4\" },\n { shaderLocation: baseLocation + 3, offset: 48, format: \"float32x4\" },\n ],\n },\n ];\n if (hasColor) {\n layouts.push({\n arrayStride: 16,\n stepMode: \"instance\",\n attributes: [{ shaderLocation: baseLocation + 4, offset: 0, format: \"float32x4\" }],\n });\n }\n return layouts;\n}\n\n/** WGSL lines appended inside `VertexInput` for instanced variants. */\nfunction instancePreludeAttributes(baseLocation: number, hasColor: boolean): string {\n let wgsl = `@location(${baseLocation}) world0: vec4<f32>,\n@location(${baseLocation + 1}) world1: vec4<f32>,\n@location(${baseLocation + 2}) world2: vec4<f32>,\n@location(${baseLocation + 3}) world3: vec4<f32>,\n`;\n if (hasColor) {\n wgsl += `@location(${baseLocation + 4}) instanceColor: vec4<f32>,\n`;\n }\n return wgsl;\n}\n\n/** Build ONE thin-instance renderable for a ShaderMaterial mesh (opaque or\n * transparent). Marked `_direct` so instance buffers are re-bound fresh each\n * frame; this also prepares the renderable for opaque-only GPU culling. */\nfunction createShaderInstancedRenderable(\n scene: SceneContext,\n material: ShaderMaterial,\n packet: ShaderPacket,\n isOverride: boolean,\n h: ShaderHelpers,\n cull?: CullModule\n): Renderable {\n const isTransparent = material.needAlphaBlending;\n const mesh = packet.mesh;\n const ti = mesh.thinInstances!;\n const hasColor = !!ti.colors;\n const baseLocation = material.attributes.length;\n const instanceLayouts = instanceVertexLayouts(baseLocation, hasColor);\n const instanceAttrs = instancePreludeAttributes(baseLocation, hasColor);\n const variantKey = `|ti1c${hasColor ? 1 : 0}`;\n const wm = mesh.worldMatrix as unknown as ArrayLike<number>;\n const sortCenter: [number, number, number] = [wm[12]!, wm[13]!, wm[14]!];\n const update = (context: DrawUpdateContext): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && mesh.material !== material) {\n return;\n }\n h.updateCustomUbo(scene.surface.engine, material);\n h.updatePacket(scene, material, packet, context);\n if (isTransparent) {\n const m = mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext, cullBinding?: import(\"../../mesh/thin-instance-cull-binding.js\").TiCullBinding): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && mesh.material !== material) {\n return 0;\n }\n if (ti.count <= 0) {\n return 0;\n }\n const gpu = mesh._gpu;\n let slot = 0;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(slot++, h.getAttrBuffer(engine, gpu, material.attributes[i]!));\n }\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, cullBinding?.cullDrawBufs);\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n if (cullBinding) {\n cullBinding.draw(pass, gpu.indexCount, ti.count);\n } else {\n pass.drawIndexed(gpu.indexCount, ti.count);\n }\n return 1;\n };\n const r: Renderable = {\n order: mesh.renderOrder ?? (isTransparent ? 200 : 100),\n isTransparent,\n mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = h.getOrCreateShaderPipelineBindings(eng, material);\n const vertexBuffers = [...bindings.vertexBuffers, ...instanceLayouts];\n const pipeline = h.getOrCreateShaderPipeline(eng, sig, material, bindings, variantKey, vertexBuffers, instanceAttrs);\n const cb = cull?.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update, sig);\n return {\n renderable: r,\n pipeline,\n update: cb ? cb.update : update,\n draw: (pass) => draw(pass, eng, cb),\n };\n },\n };\n (r as { _direct?: boolean })._direct = true;\n return r;\n}\n\n/** Build one instanced renderable for `mesh` (used by the combined `rebuildSingle`). */\nfunction buildInstancedSingle(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean, h: ShaderHelpers, cull?: CullModule): Renderable {\n const bindings = h.getOrCreateShaderPipelineBindings(scene.surface.engine, material);\n const packet = h.createPacket(scene, material, bindings.systemSpec, mesh);\n return createShaderInstancedRenderable(scene, material, packet, isOverride, h, cull);\n}\n\n/** Group entry point used whenever a ShaderMaterial scene has at least one\n * thin-instanced mesh. Plain meshes flow through the passed-in `buildPlain`\n * (`buildShaderMaterialRenderables`); instanced meshes get a dedicated renderable. */\nexport function buildShaderRenderablesWithInstancing(\n scene: SceneContext,\n meshes: Mesh[],\n buildPlain: ShaderHelpers[\"buildPlain\"],\n createPacket: ShaderHelpers[\"createPacket\"],\n updatePacket: ShaderHelpers[\"updatePacket\"],\n updateCustomUbo: ShaderHelpers[\"updateCustomUbo\"],\n getAttrBuffer: ShaderHelpers[\"getAttrBuffer\"],\n getOrCreateShaderPipeline: ShaderHelpers[\"getOrCreateShaderPipeline\"],\n getOrCreateShaderPipelineBindings: ShaderHelpers[\"getOrCreateShaderPipelineBindings\"],\n cull?: CullModule\n): MeshGroupBuildResult {\n const h: ShaderHelpers = { buildPlain, createPacket, updatePacket, updateCustomUbo, getAttrBuffer, getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings };\n const instanced: Mesh[] = [];\n const plain: Mesh[] = [];\n for (const mesh of meshes) {\n if (mesh.thinInstances) {\n instanced.push(mesh);\n } else {\n plain.push(mesh);\n }\n }\n\n const renderables: Renderable[] = [];\n let plainRebuild: MeshGroupBuildResult[\"rebuildSingle\"] | undefined;\n if (plain.length > 0) {\n const plainResult = buildPlain(scene, plain);\n renderables.push(...plainResult.renderables);\n plainRebuild = plainResult.rebuildSingle;\n }\n for (const mesh of instanced) {\n renderables.push(buildInstancedSingle(scene, mesh, mesh.material as ShaderMaterial, false, h, cull));\n }\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const material = (materialOverride ?? mesh.material) as ShaderMaterial;\n if (mesh.thinInstances) {\n return buildInstancedSingle(s, mesh, material, materialOverride != null, h, cull);\n }\n if (plainRebuild) {\n return plainRebuild(s, mesh, materialOverride);\n }\n return buildPlain(s, [mesh]).rebuildSingle(s, mesh, materialOverride);\n };\n\n return { renderables, rebuildSingle };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -175,7 +175,7 @@ function buildStandardMeshRenderables(scene, meshes, factories) {
|
|
|
175
175
|
mesh,
|
|
176
176
|
bind(eng, sig) {
|
|
177
177
|
const pipeline = getOrCreateStandardPipeline(eng, sig, bindings);
|
|
178
|
-
const cb = cull?.tryBind(r, s, mesh, engine, hasInstanceColor, isTransparent, update);
|
|
178
|
+
const cb = cull?.tryBind(r, s, mesh, engine, hasInstanceColor, isTransparent, update, sig);
|
|
179
179
|
return {
|
|
180
180
|
renderable: r,
|
|
181
181
|
pipeline,
|