@babylonjs/lite 1.6.0 → 1.7.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 +284 -279
- package/dist/index.js.map +1 -1
- package/index.d.ts +17 -2
- package/lib/engine/engine.js +1 -1
- package/lib/frame-graph/depth-resolve-task.js +117 -0
- package/lib/frame-graph/depth-resolve-task.js.map +1 -0
- package/lib/frame-graph/transmission.js +4 -3
- package/lib/frame-graph/transmission.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/material/shader/shader-material.js +4 -2
- package/lib/material/shader/shader-material.js.map +1 -1
- package/lib/material/shader/shader-pipeline.js +10 -0
- package/lib/material/shader/shader-pipeline.js.map +1 -1
- package/lib/material/shader/shader-renderable.js +19 -6
- package/lib/material/shader/shader-renderable.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/scene/scene-core.js +5 -2
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/shadow/csm-shadow-task-hooks.js +14 -6
- package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
- package/lib/shadow/pcf-shadow-task-hooks.js +6 -0
- package/lib/shadow/pcf-shadow-task-hooks.js.map +1 -1
- package/package.json +3 -3
|
@@ -138,7 +138,12 @@ function attributeLayout(name, shaderLocation) {
|
|
|
138
138
|
return { arrayStride: 8, attributes: [{ shaderLocation, offset: 0, format: "float32x2" }] };
|
|
139
139
|
case "tangent":
|
|
140
140
|
case "color":
|
|
141
|
+
case "weights":
|
|
142
|
+
case "weights1":
|
|
141
143
|
return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: "float32x4" }] };
|
|
144
|
+
case "joints":
|
|
145
|
+
case "joints1":
|
|
146
|
+
return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: "uint32x4" }] };
|
|
142
147
|
}
|
|
143
148
|
}
|
|
144
149
|
function buildShaderPrelude(material, systemSpec, customSpec, instanceAttrs = "") {
|
|
@@ -204,7 +209,12 @@ function attributeWgslType(name) {
|
|
|
204
209
|
return "vec2<f32>";
|
|
205
210
|
case "tangent":
|
|
206
211
|
case "color":
|
|
212
|
+
case "weights":
|
|
213
|
+
case "weights1":
|
|
207
214
|
return "vec4<f32>";
|
|
215
|
+
case "joints":
|
|
216
|
+
case "joints1":
|
|
217
|
+
return "vec4<u32>";
|
|
208
218
|
}
|
|
209
219
|
}
|
|
210
220
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-pipeline.js","sources":["../../../../src/material/shader/shader-pipeline.ts"],"sourcesContent":["import { SS } from \"../../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { computeUboLayout } from \"../../shader/ubo-layout.js\";\nimport type { UboField, UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderSamplerDecl, ShaderUniformDecl } from \"./shader-material.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\nimport type { ResolvedStencil } from \"../stencil-state.js\";\nimport type { StencilState } from \"../material.js\";\n\n/** Stencil resolver, installed only by `enableMaterialStencil`. Module-local with a single exported setter:\n * when `enableMaterialStencil` is absent from the bundle the setter tree-shakes, the bundler proves this is\n * always null, and every stencil branch below folds away — stencil-free Shader scenes stay byte-identical. */\nlet _stencilResolver: ((stencil: StencilState) => ResolvedStencil) | null = null;\n/** @internal Install the stencil resolver into the Shader pipeline (called by `enableMaterialStencil`). */\nexport function _installShaderStencilResolver(resolve: (stencil: StencilState) => ResolvedStencil): void {\n _stencilResolver = resolve;\n}\n\nexport interface ShaderPipelineBindings {\n readonly group1BGL: GPUBindGroupLayout;\n readonly systemSpec: UboSpec;\n readonly customSpec: UboSpec | null;\n readonly vertexBuffers: readonly GPUVertexBufferLayout[];\n readonly pipelines: Map<string, GPURenderPipeline>;\n}\n\ninterface ShaderMaterialPipelineState extends ShaderMaterial {\n _shaderDevice?: GPUDevice;\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\nconst SHADER_STAGE_ALL = SS.VERTEX | SS.FRAGMENT;\n\nexport function getOrCreateShaderPipelineBindings(engine: EngineContext, material: ShaderMaterial): ShaderPipelineBindings {\n const state = material as ShaderMaterialPipelineState;\n if (state._shaderBindings && state._shaderDevice === engine._device) {\n return state._shaderBindings;\n }\n\n state._shaderDevice = engine._device;\n const systemFields = material.uniformDecls.filter((u) => _isShaderSystemUniform(u.name)).map(toUboField);\n const customFields = material.uniformDecls.filter((u) => !_isShaderSystemUniform(u.name)).map(toUboField);\n const systemSpec = computeUboLayout(systemFields.length > 0 ? systemFields : [{ _name: \"_pad\", _type: \"vec4<f32>\" }]);\n const customSpec = customFields.length > 0 ? computeUboLayout(customFields) : null;\n const group1BGL = engine._device.createBindGroupLayout({\n label: \"shader-material-group1\",\n entries: buildBindGroupLayoutEntries(material.samplerDecls, material.storageBufferDecls, customSpec !== null),\n });\n const bindings: ShaderPipelineBindings = {\n group1BGL,\n systemSpec,\n customSpec,\n vertexBuffers: material.attributes.map(attributeLayout),\n pipelines: new Map(),\n };\n state._shaderBindings = bindings;\n state._shaderCustomSpec = customSpec;\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = -1;\n return bindings;\n}\n\nexport function getOrCreateShaderPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey = \"\",\n vertexBuffers: readonly GPUVertexBufferLayout[] = bindings.vertexBuffers,\n instanceAttrs = \"\"\n): GPURenderPipeline {\n // `variantKey`, `vertexBuffers` and `instanceAttrs` default to the\n // non-instanced pipeline — byte-for-byte identical behaviour to before\n // instancing existed. The dynamically-imported thin-instance module is the\n // only caller that passes non-default values, so no instancing logic runs\n // for non-instanced scenes.\n const key = `${targetSignatureKey(sig)}${variantKey}`;\n const cached = bindings.pipelines.get(key);\n if (cached) {\n return cached;\n }\n const stencil = material.stencil && _stencilResolver ? _stencilResolver(material.stencil) : null;\n const device = engine._device;\n const prelude = buildShaderPrelude(material, bindings.systemSpec, bindings.customSpec, instanceAttrs);\n const vertModule = device.createShaderModule({ label: `${material.name ?? \"shader\"}-vertex`, code: `${prelude}\\n${material.vertexSource}` });\n const wantsFragment = !!sig._colorFormat || material.depthOnlyFragment;\n const fragModule = wantsFragment ? device.createShaderModule({ label: `${material.name ?? \"shader\"}-fragment`, code: `${prelude}\\n${material.fragmentSource}` }) : null;\n const colorTarget: GPUColorTargetState | null = sig._colorFormat\n ? {\n format: sig._colorFormat,\n ...(material.needAlphaBlending\n ? {\n blend:\n material.blendMode === \"additive\"\n ? ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one\", operation: \"add\" },\n } satisfies GPUBlendState)\n : ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n } satisfies GPUBlendState),\n }\n : {}),\n }\n : null;\n\n const pipeline = device.createRenderPipeline({\n label: `${material.name ?? \"shader\"}-pipeline`,\n layout: device.createPipelineLayout({ bindGroupLayouts: [getSceneBindGroupLayout(engine), bindings.group1BGL] }),\n vertex: { module: vertModule, entryPoint: \"mainVertex\", buffers: vertexBuffers as GPUVertexBufferLayout[] },\n ...(fragModule ? { fragment: { module: fragModule, entryPoint: \"mainFragment\", targets: colorTarget ? [colorTarget] : [] } } : {}),\n ...(sig._depthStencilFormat\n ? {\n depthStencil: {\n format: sig._depthStencilFormat,\n // The target's declared depth convention wins over the material default: a depth-only\n // caster authored for the forward-Z shadow map (\"less-equal\") must still depth-test\n // correctly when drawn into a reverse-Z camera depth prepass that declares\n // \"greater-equal\" — otherwise every fragment fails against the 0-cleared buffer.\n depthCompare: sig._depthCompare ?? material.depthCompare,\n depthWriteEnabled: material.needAlphaBlending ? false : material.depthWrite,\n ...(material.depthBias ? { depthBias: material.depthBias } : {}),\n ...(material.depthBiasSlopeScale ? { depthBiasSlopeScale: material.depthBiasSlopeScale } : {}),\n // Pre-baked stencil sub-fields, resolved through the opt-in `_stencilResolver` hook above;\n // applied only on a stencil-capable target — a material reused in the depth32float\n // shadow/depth pass keeps plain depth state (no stencil → no format mismatch). `stencil`\n // is a local const that folds to null in stencil-free bundles, so this branch disappears.\n ...(stencil && sig._depthStencilFormat.includes(\"stencil\") ? stencil._desc : {}),\n },\n }\n : {}),\n multisample: { count: sig._sampleCount },\n primitive: { topology: \"triangle-list\", cullMode: material.backFaceCulling ? \"back\" : \"none\", frontFace: \"ccw\" },\n });\n bindings.pipelines.set(key, pipeline);\n return pipeline;\n}\n\nfunction toUboField(decl: ShaderUniformDecl): UboField {\n return { _name: decl.name, _type: decl.type };\n}\n\nfunction buildBindGroupLayoutEntries(\n samplers: readonly ShaderSamplerDecl[],\n storageBuffers: readonly { name: string; type: string }[],\n hasCustomUbo: boolean\n): GPUBindGroupLayoutEntry[] {\n const entries: GPUBindGroupLayoutEntry[] = [{ binding: 0, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } }];\n let nextBinding = 1;\n if (hasCustomUbo) {\n entries.push({ binding: nextBinding++, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } });\n }\n for (const sampler of samplers) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const sampleType = sampler.comparison === true ? \"depth\" : (sampler.sampleType ?? \"float\");\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n texture: {\n sampleType,\n viewDimension: isArray ? \"2d-array\" : \"2d\",\n },\n });\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n sampler: { type: sampler.comparison === true ? \"comparison\" : sampleType === \"float\" ? \"filtering\" : \"non-filtering\" },\n });\n }\n for (const _storage of storageBuffers) {\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n buffer: { type: \"read-only-storage\" },\n });\n }\n return entries;\n}\n\nfunction attributeLayout(name: ShaderAttributeName, shaderLocation: number): GPUVertexBufferLayout {\n switch (name) {\n case \"position\":\n case \"normal\":\n return { arrayStride: 12, attributes: [{ shaderLocation, offset: 0, format: \"float32x3\" }] };\n case \"uv\":\n case \"uv2\":\n return { arrayStride: 8, attributes: [{ shaderLocation, offset: 0, format: \"float32x2\" }] };\n case \"tangent\":\n case \"color\":\n return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: \"float32x4\" }] };\n }\n}\n\nfunction buildShaderPrelude(material: ShaderMaterial, systemSpec: UboSpec, customSpec: UboSpec | null, instanceAttrs = \"\"): string {\n let wgsl = `${SCENE_UBO_WGSL}\nstruct ShaderSystemUniforms {\n${systemSpec._structBody}\n}\n@group(1) @binding(0) var<uniform> shaderSystem: ShaderSystemUniforms;\n`;\n if (customSpec) {\n wgsl += `struct ShaderUniforms {\n${customSpec._structBody}\n}\n@group(1) @binding(1) var<uniform> shaderUniforms: ShaderUniforms;\n`;\n }\n let nextBinding = customSpec ? 2 : 1;\n for (const sampler of material.samplerDecls) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const isDepth = sampler.comparison === true || sampler.sampleType === \"depth\";\n const texType = isDepth ? (isArray ? \"texture_depth_2d_array\" : \"texture_depth_2d\") : isArray ? \"texture_2d_array<f32>\" : \"texture_2d<f32>\";\n const samplerType = sampler.comparison === true ? \"sampler_comparison\" : \"sampler\";\n wgsl += `@group(1) @binding(${nextBinding++}) var ${sampler.name}: ${texType};\n@group(1) @binding(${nextBinding++}) var ${sampler.name}Sampler: ${samplerType};\n`;\n }\n for (const storage of material.storageBufferDecls) {\n wgsl += `@group(1) @binding(${nextBinding++}) var<storage, read> ${storage.name}: ${storage.type};\n`;\n }\n for (const define of material.defines) {\n wgsl += `const ${define.name}: ${typeof define.value === \"boolean\" ? \"bool\" : \"f32\"} = ${formatDefineValue(define.value)};\n`;\n }\n wgsl += `struct VertexInput {\n`;\n for (let i = 0; i < material.attributes.length; i++) {\n const attr = material.attributes[i]!;\n wgsl += `@location(${i}) ${attr}: ${attributeWgslType(attr)},\n`;\n }\n wgsl += instanceAttrs;\n wgsl += `};\n`;\n return wgsl;\n}\n\nfunction formatDefineValue(value: boolean | number): string {\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Number.isInteger(value)) {\n return `${value}.0`;\n }\n return String(value);\n}\n\nfunction attributeWgslType(name: ShaderAttributeName): string {\n switch (name) {\n case \"position\":\n case \"normal\":\n return \"vec3<f32>\";\n case \"uv\":\n case \"uv2\":\n return \"vec2<f32>\";\n case \"tangent\":\n case \"color\":\n return \"vec4<f32>\";\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shader-pipeline.js","sources":["../../../../src/material/shader/shader-pipeline.ts"],"sourcesContent":["import { SS } from \"../../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { computeUboLayout } from \"../../shader/ubo-layout.js\";\nimport type { UboField, UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderSamplerDecl, ShaderUniformDecl } from \"./shader-material.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\nimport type { ResolvedStencil } from \"../stencil-state.js\";\nimport type { StencilState } from \"../material.js\";\n\n/** Stencil resolver, installed only by `enableMaterialStencil`. Module-local with a single exported setter:\n * when `enableMaterialStencil` is absent from the bundle the setter tree-shakes, the bundler proves this is\n * always null, and every stencil branch below folds away — stencil-free Shader scenes stay byte-identical. */\nlet _stencilResolver: ((stencil: StencilState) => ResolvedStencil) | null = null;\n/** @internal Install the stencil resolver into the Shader pipeline (called by `enableMaterialStencil`). */\nexport function _installShaderStencilResolver(resolve: (stencil: StencilState) => ResolvedStencil): void {\n _stencilResolver = resolve;\n}\n\nexport interface ShaderPipelineBindings {\n readonly group1BGL: GPUBindGroupLayout;\n readonly systemSpec: UboSpec;\n readonly customSpec: UboSpec | null;\n readonly vertexBuffers: readonly GPUVertexBufferLayout[];\n readonly pipelines: Map<string, GPURenderPipeline>;\n}\n\ninterface ShaderMaterialPipelineState extends ShaderMaterial {\n _shaderDevice?: GPUDevice;\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\nconst SHADER_STAGE_ALL = SS.VERTEX | SS.FRAGMENT;\n\nexport function getOrCreateShaderPipelineBindings(engine: EngineContext, material: ShaderMaterial): ShaderPipelineBindings {\n const state = material as ShaderMaterialPipelineState;\n if (state._shaderBindings && state._shaderDevice === engine._device) {\n return state._shaderBindings;\n }\n\n state._shaderDevice = engine._device;\n const systemFields = material.uniformDecls.filter((u) => _isShaderSystemUniform(u.name)).map(toUboField);\n const customFields = material.uniformDecls.filter((u) => !_isShaderSystemUniform(u.name)).map(toUboField);\n const systemSpec = computeUboLayout(systemFields.length > 0 ? systemFields : [{ _name: \"_pad\", _type: \"vec4<f32>\" }]);\n const customSpec = customFields.length > 0 ? computeUboLayout(customFields) : null;\n const group1BGL = engine._device.createBindGroupLayout({\n label: \"shader-material-group1\",\n entries: buildBindGroupLayoutEntries(material.samplerDecls, material.storageBufferDecls, customSpec !== null),\n });\n const bindings: ShaderPipelineBindings = {\n group1BGL,\n systemSpec,\n customSpec,\n vertexBuffers: material.attributes.map(attributeLayout),\n pipelines: new Map(),\n };\n state._shaderBindings = bindings;\n state._shaderCustomSpec = customSpec;\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = -1;\n return bindings;\n}\n\nexport function getOrCreateShaderPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey = \"\",\n vertexBuffers: readonly GPUVertexBufferLayout[] = bindings.vertexBuffers,\n instanceAttrs = \"\"\n): GPURenderPipeline {\n // `variantKey`, `vertexBuffers` and `instanceAttrs` default to the\n // non-instanced pipeline — byte-for-byte identical behaviour to before\n // instancing existed. The dynamically-imported thin-instance module is the\n // only caller that passes non-default values, so no instancing logic runs\n // for non-instanced scenes.\n const key = `${targetSignatureKey(sig)}${variantKey}`;\n const cached = bindings.pipelines.get(key);\n if (cached) {\n return cached;\n }\n const stencil = material.stencil && _stencilResolver ? _stencilResolver(material.stencil) : null;\n const device = engine._device;\n const prelude = buildShaderPrelude(material, bindings.systemSpec, bindings.customSpec, instanceAttrs);\n const vertModule = device.createShaderModule({ label: `${material.name ?? \"shader\"}-vertex`, code: `${prelude}\\n${material.vertexSource}` });\n const wantsFragment = !!sig._colorFormat || material.depthOnlyFragment;\n const fragModule = wantsFragment ? device.createShaderModule({ label: `${material.name ?? \"shader\"}-fragment`, code: `${prelude}\\n${material.fragmentSource}` }) : null;\n const colorTarget: GPUColorTargetState | null = sig._colorFormat\n ? {\n format: sig._colorFormat,\n ...(material.needAlphaBlending\n ? {\n blend:\n material.blendMode === \"additive\"\n ? ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one\", operation: \"add\" },\n } satisfies GPUBlendState)\n : ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n } satisfies GPUBlendState),\n }\n : {}),\n }\n : null;\n\n const pipeline = device.createRenderPipeline({\n label: `${material.name ?? \"shader\"}-pipeline`,\n layout: device.createPipelineLayout({ bindGroupLayouts: [getSceneBindGroupLayout(engine), bindings.group1BGL] }),\n vertex: { module: vertModule, entryPoint: \"mainVertex\", buffers: vertexBuffers as GPUVertexBufferLayout[] },\n ...(fragModule ? { fragment: { module: fragModule, entryPoint: \"mainFragment\", targets: colorTarget ? [colorTarget] : [] } } : {}),\n ...(sig._depthStencilFormat\n ? {\n depthStencil: {\n format: sig._depthStencilFormat,\n // The target's declared depth convention wins over the material default: a depth-only\n // caster authored for the forward-Z shadow map (\"less-equal\") must still depth-test\n // correctly when drawn into a reverse-Z camera depth prepass that declares\n // \"greater-equal\" — otherwise every fragment fails against the 0-cleared buffer.\n depthCompare: sig._depthCompare ?? material.depthCompare,\n depthWriteEnabled: material.needAlphaBlending ? false : material.depthWrite,\n ...(material.depthBias ? { depthBias: material.depthBias } : {}),\n ...(material.depthBiasSlopeScale ? { depthBiasSlopeScale: material.depthBiasSlopeScale } : {}),\n // Pre-baked stencil sub-fields, resolved through the opt-in `_stencilResolver` hook above;\n // applied only on a stencil-capable target — a material reused in the depth32float\n // shadow/depth pass keeps plain depth state (no stencil → no format mismatch). `stencil`\n // is a local const that folds to null in stencil-free bundles, so this branch disappears.\n ...(stencil && sig._depthStencilFormat.includes(\"stencil\") ? stencil._desc : {}),\n },\n }\n : {}),\n multisample: { count: sig._sampleCount },\n primitive: { topology: \"triangle-list\", cullMode: material.backFaceCulling ? \"back\" : \"none\", frontFace: \"ccw\" },\n });\n bindings.pipelines.set(key, pipeline);\n return pipeline;\n}\n\nfunction toUboField(decl: ShaderUniformDecl): UboField {\n return { _name: decl.name, _type: decl.type };\n}\n\nfunction buildBindGroupLayoutEntries(\n samplers: readonly ShaderSamplerDecl[],\n storageBuffers: readonly { name: string; type: string }[],\n hasCustomUbo: boolean\n): GPUBindGroupLayoutEntry[] {\n const entries: GPUBindGroupLayoutEntry[] = [{ binding: 0, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } }];\n let nextBinding = 1;\n if (hasCustomUbo) {\n entries.push({ binding: nextBinding++, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } });\n }\n for (const sampler of samplers) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const sampleType = sampler.comparison === true ? \"depth\" : (sampler.sampleType ?? \"float\");\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n texture: {\n sampleType,\n viewDimension: isArray ? \"2d-array\" : \"2d\",\n },\n });\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n sampler: { type: sampler.comparison === true ? \"comparison\" : sampleType === \"float\" ? \"filtering\" : \"non-filtering\" },\n });\n }\n for (const _storage of storageBuffers) {\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n buffer: { type: \"read-only-storage\" },\n });\n }\n return entries;\n}\n\nfunction attributeLayout(name: ShaderAttributeName, shaderLocation: number): GPUVertexBufferLayout {\n switch (name) {\n case \"position\":\n case \"normal\":\n return { arrayStride: 12, attributes: [{ shaderLocation, offset: 0, format: \"float32x3\" }] };\n case \"uv\":\n case \"uv2\":\n return { arrayStride: 8, attributes: [{ shaderLocation, offset: 0, format: \"float32x2\" }] };\n case \"tangent\":\n case \"color\":\n case \"weights\":\n case \"weights1\":\n return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: \"float32x4\" }] };\n case \"joints\":\n case \"joints1\":\n return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: \"uint32x4\" }] };\n }\n}\n\nfunction buildShaderPrelude(material: ShaderMaterial, systemSpec: UboSpec, customSpec: UboSpec | null, instanceAttrs = \"\"): string {\n let wgsl = `${SCENE_UBO_WGSL}\nstruct ShaderSystemUniforms {\n${systemSpec._structBody}\n}\n@group(1) @binding(0) var<uniform> shaderSystem: ShaderSystemUniforms;\n`;\n if (customSpec) {\n wgsl += `struct ShaderUniforms {\n${customSpec._structBody}\n}\n@group(1) @binding(1) var<uniform> shaderUniforms: ShaderUniforms;\n`;\n }\n let nextBinding = customSpec ? 2 : 1;\n for (const sampler of material.samplerDecls) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const isDepth = sampler.comparison === true || sampler.sampleType === \"depth\";\n const texType = isDepth ? (isArray ? \"texture_depth_2d_array\" : \"texture_depth_2d\") : isArray ? \"texture_2d_array<f32>\" : \"texture_2d<f32>\";\n const samplerType = sampler.comparison === true ? \"sampler_comparison\" : \"sampler\";\n wgsl += `@group(1) @binding(${nextBinding++}) var ${sampler.name}: ${texType};\n@group(1) @binding(${nextBinding++}) var ${sampler.name}Sampler: ${samplerType};\n`;\n }\n for (const storage of material.storageBufferDecls) {\n wgsl += `@group(1) @binding(${nextBinding++}) var<storage, read> ${storage.name}: ${storage.type};\n`;\n }\n for (const define of material.defines) {\n wgsl += `const ${define.name}: ${typeof define.value === \"boolean\" ? \"bool\" : \"f32\"} = ${formatDefineValue(define.value)};\n`;\n }\n wgsl += `struct VertexInput {\n`;\n for (let i = 0; i < material.attributes.length; i++) {\n const attr = material.attributes[i]!;\n wgsl += `@location(${i}) ${attr}: ${attributeWgslType(attr)},\n`;\n }\n wgsl += instanceAttrs;\n wgsl += `};\n`;\n return wgsl;\n}\n\nfunction formatDefineValue(value: boolean | number): string {\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Number.isInteger(value)) {\n return `${value}.0`;\n }\n return String(value);\n}\n\nfunction attributeWgslType(name: ShaderAttributeName): string {\n switch (name) {\n case \"position\":\n case \"normal\":\n return \"vec3<f32>\";\n case \"uv\":\n case \"uv2\":\n return \"vec2<f32>\";\n case \"tangent\":\n case \"color\":\n case \"weights\":\n case \"weights1\":\n return \"vec4<f32>\";\n case \"joints\":\n case \"joints1\":\n return \"vec4<u32>\";\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -169,22 +169,23 @@ function updatePacket(scene, material, packet, context) {
|
|
|
169
169
|
writeSystemUniforms(packet.systemData, state._shaderBindings.systemSpec, material, packet.mesh, context._camera ?? scene.camera, context.targetWidth, context.targetHeight);
|
|
170
170
|
engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData);
|
|
171
171
|
if (packet._lastResourceVersion !== material._resourceVersion) {
|
|
172
|
+
const newTextures = collectShaderTextures(material);
|
|
173
|
+
for (const tex of newTextures) {
|
|
174
|
+
acquireTexture(tex);
|
|
175
|
+
}
|
|
172
176
|
for (const tex of packet._boundTextures) {
|
|
173
177
|
releaseTexture(tex);
|
|
174
178
|
}
|
|
175
179
|
packet._bindGroup = createShaderBindGroup(engine, material, packet.systemUBO);
|
|
176
|
-
packet._boundTextures =
|
|
180
|
+
packet._boundTextures = newTextures;
|
|
177
181
|
packet._boundStorageBuffers = collectShaderStorageBuffers(material);
|
|
178
|
-
for (const tex of packet._boundTextures) {
|
|
179
|
-
acquireTexture(tex);
|
|
180
|
-
}
|
|
181
182
|
packet._lastResourceVersion = material._resourceVersion;
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
function drawPacket(pass, engine, material, packet) {
|
|
185
186
|
const gpu = packet.mesh._gpu;
|
|
186
187
|
for (let i = 0; i < material.attributes.length; i++) {
|
|
187
|
-
pass.setVertexBuffer(i, getAttrBuffer(engine,
|
|
188
|
+
pass.setVertexBuffer(i, getAttrBuffer(engine, packet.mesh, material.attributes[i]));
|
|
188
189
|
}
|
|
189
190
|
pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);
|
|
190
191
|
pass.setBindGroup(1, packet._bindGroup);
|
|
@@ -387,7 +388,11 @@ function getZeroAttrBuffer(engine, gpu, name) {
|
|
|
387
388
|
cache.set(name, buffer);
|
|
388
389
|
return buffer;
|
|
389
390
|
}
|
|
390
|
-
function
|
|
391
|
+
function getSkinBuffer(mesh, field) {
|
|
392
|
+
return mesh.vat?.[field] ?? mesh.skeleton?.[field] ?? null;
|
|
393
|
+
}
|
|
394
|
+
function getAttrBuffer(engine, mesh, name) {
|
|
395
|
+
const gpu = mesh._gpu;
|
|
391
396
|
switch (name) {
|
|
392
397
|
case "position":
|
|
393
398
|
return gpu.positionBuffer;
|
|
@@ -401,6 +406,14 @@ function getAttrBuffer(engine, gpu, name) {
|
|
|
401
406
|
return gpu.tangentBuffer ?? getZeroAttrBuffer(engine, gpu, "tangent");
|
|
402
407
|
case "color":
|
|
403
408
|
return gpu.colorBuffer ?? getZeroAttrBuffer(engine, gpu, "color");
|
|
409
|
+
case "joints":
|
|
410
|
+
return getSkinBuffer(mesh, "jointsBuffer") ?? getZeroAttrBuffer(engine, gpu, "joints");
|
|
411
|
+
case "weights":
|
|
412
|
+
return getSkinBuffer(mesh, "weightsBuffer") ?? getZeroAttrBuffer(engine, gpu, "weights");
|
|
413
|
+
case "joints1":
|
|
414
|
+
return getSkinBuffer(mesh, "joints1Buffer") ?? getZeroAttrBuffer(engine, gpu, "joints1");
|
|
415
|
+
case "weights1":
|
|
416
|
+
return getSkinBuffer(mesh, "weights1Buffer") ?? getZeroAttrBuffer(engine, gpu, "weights1");
|
|
404
417
|
}
|
|
405
418
|
}
|
|
406
419
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-renderable.js","sources":["../../../../src/material/shader/shader-renderable.ts"],"sourcesContent":["import { F32, U32, I32, U8 } from \"../../engine/typed-arrays.js\";\nimport { BU } from \"../../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuildResult, Renderable, DrawUpdateContext } from \"../../render/renderable.js\";\nimport type { Material } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport { createEmptyUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport { getEffectiveAspectRatio, getProjectionMatrix, getViewMatrix, getViewProjectionMatrix } from \"../../camera/camera.js\";\nimport type { Camera } from \"../../camera/camera.js\";\nimport { mat4MultiplyInto } from \"../../math/mat4-multiply-into.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderUniformType } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\nimport { getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings } from \"./shader-pipeline.js\";\n\n/** @internal Exported as a type only (zero runtime bytes) for the dynamically-imported\n * thin-instance builder. */\nexport interface ShaderPacket {\n readonly mesh: Mesh;\n readonly systemUBO: GPUBuffer;\n readonly systemData: Float32Array;\n /** @internal */\n _bindGroup: GPUBindGroup;\n /** @internal */\n _lastResourceVersion: number;\n /** @internal */\n _boundTextures: Texture2D[];\n /** @internal */\n _boundStorageBuffers: GPUBuffer[];\n /** @internal Set when the owning mesh is removed and this packet's GPU resources are\n * destroyed. A combined (multi-mesh) renderable keeps every packet in its\n * closure, so update()/draw() must skip disposed packets to avoid writing to\n * or submitting an already-destroyed systemUBO / vertex buffer. */\n _disposed?: boolean;\n /** @internal Back-reference to the combined renderable's packet array, so disposal can\n * splice this packet out and stop retaining/iterating dead chunk state every\n * frame (set only for merged opaque renderables). */\n _owner?: ShaderPacket[];\n}\n\ninterface ShaderMaterialRenderState extends ShaderMaterial {\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\n/** @internal */\nexport type ShaderRenderPass = GPURenderPassEncoder | GPURenderBundleEncoder;\n\nexport function buildShaderMaterialRenderables(scene: SceneContext, meshes: Mesh[]): MeshGroupBuildResult {\n const renderables: Renderable[] = [];\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable =>\n buildSingleShaderRenderable(s, mesh, (materialOverride ?? mesh.material) as ShaderMaterial, materialOverride != null);\n\n const byMaterial = new Map<ShaderMaterial, Mesh[]>();\n for (const mesh of meshes) {\n const material = mesh.material as ShaderMaterial;\n let list = byMaterial.get(material);\n if (!list) {\n list = [];\n byMaterial.set(material, list);\n }\n list.push(mesh);\n }\n\n for (const [material, matMeshes] of byMaterial) {\n const built = buildMaterialRenderables(scene, material, matMeshes);\n renderables.push(...built);\n }\n\n return { renderables, rebuildSingle };\n}\n\n/** Async group entry point. Non-instanced ShaderMaterial scenes (the common case)\n * take the synchronous fast path and pull in zero instancing code. When at least\n * one mesh uses thin instances, the instancing module is dynamically imported and\n * the renderable helpers it needs are handed to it as positional arguments — NOT\n * module exports — so those helpers keep their mangled names in this chunk (an\n * export would de-mangle them, growing every ShaderMaterial scene's bundle). */\nexport async function buildShaderGroup(scene: SceneContext, meshes: Mesh[]): Promise<MeshGroupBuildResult> {\n if (!meshes.some((m) => !!m.thinInstances)) {\n return buildShaderMaterialRenderables(scene, meshes);\n }\n const mod = await import(\"./shader-thin-instance.js\");\n const cull = meshes.some((m) => !!m.thinInstances?._gpuCullingEnabled) ? await import(\"../../mesh/thin-instance-cull-binding.js\") : undefined;\n return mod.buildShaderRenderablesWithInstancing(\n scene,\n meshes,\n buildShaderMaterialRenderables,\n createPacket,\n updatePacket,\n updateCustomUbo,\n getAttrBuffer,\n getOrCreateShaderPipeline,\n getOrCreateShaderPipelineBindings,\n cull\n );\n}\n\nfunction buildSingleShaderRenderable(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean): Renderable {\n return buildMaterialRenderables(scene, material, [mesh], isOverride)[0]!;\n}\n\nfunction buildMaterialRenderables(scene: SceneContext, material: ShaderMaterial, meshes: readonly Mesh[], isOverride = false): Renderable[] {\n const engine = scene.surface.engine;\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n ensureCustomUbo(engine, material, bindings.customSpec);\n const packets = meshes.map((mesh) => createPacket(scene, material, bindings.systemSpec, mesh));\n const isTransparent = material.needAlphaBlending;\n if (isTransparent) {\n return packets.map((packet) => createTransparentRenderable(scene, material, packet, isOverride));\n }\n return [createOpaqueRenderable(scene, material, packets, isOverride)];\n}\n\nfunction createPacket(scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh): ShaderPacket {\n const engine = scene.surface.engine;\n const systemUBO = createEmptyUniformBuffer(engine, systemSpec._totalBytes, \"shader-system-ubo\");\n const systemData = new F32(systemSpec._totalBytes / 4);\n writeSystemUniforms(systemData, systemSpec, material, mesh, scene.camera, engine.canvas.width || 1, engine.canvas.height || 1);\n engine._device.queue.writeBuffer(systemUBO, 0, systemData);\n const packet: ShaderPacket = {\n mesh,\n systemUBO,\n systemData,\n _bindGroup: createShaderBindGroup(engine, material, systemUBO),\n _lastResourceVersion: material._resourceVersion,\n _boundTextures: collectShaderTextures(material),\n _boundStorageBuffers: collectShaderStorageBuffers(material),\n };\n for (const tex of packet._boundTextures) {\n acquireTexture(tex);\n }\n registerMeshTextureDisposer(scene, mesh, packet);\n return packet;\n}\n\nfunction createOpaqueRenderable(scene: SceneContext, material: ShaderMaterial, packets: readonly ShaderPacket[], isOverride: boolean): Renderable {\n // Only merged renderables (>1 mesh) can outlive an individual packet's mesh,\n // so give those packets a back-reference enabling disposal-time compaction.\n if (packets.length > 1) {\n for (const packet of packets) {\n packet._owner = packets as ShaderPacket[];\n }\n }\n const update = (context: DrawUpdateContext): void => {\n updateCustomUbo(scene.surface.engine, material);\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n updatePacket(scene, material, packet, context);\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n let draws = 0;\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n drawPacket(pass, engine, material, packet);\n draws++;\n }\n return draws;\n };\n const r: Renderable = {\n order: packets.length === 1 ? (packets[0]!.mesh.renderOrder ?? 100) : Math.min(...packets.map((p) => p.mesh.renderOrder ?? 100)),\n isTransparent: false,\n mesh: packets.length === 1 ? packets[0]!.mesh : undefined,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction createTransparentRenderable(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, isOverride: boolean): Renderable {\n const wm = packet.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 && packet.mesh.material !== material) {\n return;\n }\n updateCustomUbo(scene.surface.engine, material);\n updatePacket(scene, material, packet, context);\n const m = packet.mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return 0;\n }\n drawPacket(pass, engine, material, packet);\n return 1;\n };\n const r: Renderable = {\n order: packet.mesh.renderOrder ?? 200,\n isTransparent: true,\n _transmissive: material.transmissive,\n mesh: packet.mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction updatePacket(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext): void {\n const engine = scene.surface.engine;\n const state = material as ShaderMaterialRenderState;\n writeSystemUniforms(packet.systemData, state._shaderBindings!.systemSpec, material, packet.mesh, context._camera ?? scene.camera, context.targetWidth, context.targetHeight);\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n if (packet._lastResourceVersion !== material._resourceVersion) {\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._bindGroup = createShaderBindGroup(engine, material, packet.systemUBO);\n packet._boundTextures = collectShaderTextures(material);\n packet._boundStorageBuffers = collectShaderStorageBuffers(material);\n for (const tex of packet._boundTextures) {\n acquireTexture(tex);\n }\n packet._lastResourceVersion = material._resourceVersion;\n }\n}\n\nfunction drawPacket(pass: ShaderRenderPass, engine: EngineContext, material: ShaderMaterial, packet: ShaderPacket): void {\n const gpu = packet.mesh._gpu;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(i, getAttrBuffer(engine, gpu, material.attributes[i]!));\n }\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n pass.drawIndexed(gpu.indexCount);\n}\n\nfunction ensureCustomUbo(engine: EngineContext, material: ShaderMaterial, customSpec: UboSpec | null): void {\n const state = material as ShaderMaterialRenderState;\n if (!customSpec) {\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = material._uniformVersion;\n return;\n }\n if (state._shaderCustomUbo && state._shaderCustomData) {\n updateCustomUbo(engine, material);\n return;\n }\n state._shaderCustomUbo = createEmptyUniformBuffer(engine, customSpec._totalBytes, \"shader-custom-ubo\");\n state._shaderCustomData = new ArrayBuffer(customSpec._totalBytes);\n state._shaderCustomVersion = -1;\n updateCustomUbo(engine, material);\n}\n\nfunction updateCustomUbo(engine: EngineContext, material: ShaderMaterial): void {\n const state = material as ShaderMaterialRenderState;\n const customSpec = state._shaderCustomSpec;\n const customUbo = state._shaderCustomUbo;\n const customData = state._shaderCustomData;\n if (!customSpec || !customUbo || !customData || state._shaderCustomVersion === material._uniformVersion) {\n return;\n }\n const bytes = new U8(customData);\n bytes.fill(0);\n for (const [name, slot] of material._uniformValues) {\n if (_isShaderSystemUniform(name)) {\n continue;\n }\n const offset = customSpec._offsets.get(name);\n if (offset !== undefined) {\n writeTypedValue(customData, offset, slot.decl.type, slot.value);\n }\n }\n engine._device.queue.writeBuffer(customUbo, 0, bytes);\n state._shaderCustomVersion = material._uniformVersion;\n}\n\nfunction writeTypedValue(data: ArrayBuffer, offset: number, type: ShaderUniformType, value: Float32Array): void {\n if (type === \"u32\") {\n new U32(data, offset, 1)[0] = value[0]!;\n return;\n }\n if (type === \"i32\") {\n new I32(data, offset, 1)[0] = value[0]!;\n return;\n }\n new F32(data, offset, value.length).set(value);\n}\n\nfunction createShaderBindGroup(engine: EngineContext, material: ShaderMaterial, systemUBO: GPUBuffer): GPUBindGroup {\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n const entries: GPUBindGroupEntry[] = [{ binding: 0, resource: { buffer: systemUBO } }];\n let nextBinding = 1;\n if (bindings.customSpec) {\n ensureCustomUbo(engine, material, bindings.customSpec);\n entries.push({ binding: nextBinding++, resource: { buffer: (material as ShaderMaterialRenderState)._shaderCustomUbo! } });\n }\n for (const sampler of material.samplerDecls) {\n const slot = material._textureSlots.get(sampler.name);\n const tex = slot?.current;\n if (!tex) {\n throw new Error(`ShaderMaterial: sampler \"${sampler.name}\" has no Texture2D. Call setShaderTexture() before rendering.`);\n }\n entries.push({ binding: nextBinding++, resource: tex.view }, { binding: nextBinding++, resource: tex.sampler });\n }\n for (const storage of material.storageBufferDecls) {\n const slot = material._storageBufferSlots.get(storage.name);\n const buffer = slot?.current;\n if (!buffer) {\n throw new Error(`ShaderMaterial: storage buffer \"${storage.name}\" has no GPUBuffer. Call setShaderStorageBuffer() before rendering.`);\n }\n entries.push({ binding: nextBinding++, resource: { buffer } });\n }\n return engine._device.createBindGroup({ label: \"shader-material-bg\", layout: bindings.group1BGL, entries });\n}\n\nfunction collectShaderTextures(material: ShaderMaterial): Texture2D[] {\n const textures: Texture2D[] = [];\n for (const slot of material._textureSlots.values()) {\n if (slot.current) {\n textures.push(slot.current);\n }\n }\n return textures;\n}\n\nfunction collectShaderStorageBuffers(material: ShaderMaterial): GPUBuffer[] {\n const buffers: GPUBuffer[] = [];\n for (const slot of material._storageBufferSlots.values()) {\n if (slot.current) {\n buffers.push(slot.current);\n }\n }\n return buffers;\n}\n\nfunction registerMeshTextureDisposer(scene: SceneContext, mesh: Mesh, packet: ShaderPacket): void {\n const list = scene._meshDisposables.get(mesh) ?? [];\n list.push(() => {\n packet._disposed = true;\n if (packet._owner) {\n const oi = packet._owner.indexOf(packet);\n if (oi >= 0) {\n packet._owner.splice(oi, 1);\n }\n packet._owner = undefined;\n }\n packet.systemUBO.destroy();\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._boundTextures = [];\n packet._boundStorageBuffers = [];\n });\n scene._meshDisposables.set(mesh, list);\n}\n\nfunction writeSystemUniforms(data: Float32Array, spec: UboSpec, material: ShaderMaterial, mesh: Mesh, camera: Camera | null, targetWidth: number, targetHeight: number): void {\n data.fill(0);\n const world = mesh.worldMatrix as unknown as Float32Array;\n const aspect = camera ? getEffectiveAspectRatio(camera, targetWidth, targetHeight) : 1;\n const view = camera ? (getViewMatrix(camera) as unknown as Float32Array) : null;\n const projection = camera ? (getProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n const viewProjection = camera ? (getViewProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n for (const uniform of material.uniformDecls) {\n if (!_isShaderSystemUniform(uniform.name)) {\n continue;\n }\n const offset = spec._offsets.get(uniform.name);\n if (offset === undefined) {\n continue;\n }\n const f = offset / 4;\n switch (uniform.name) {\n case \"world\":\n data.set(world, f);\n break;\n case \"view\":\n if (view) {\n data.set(view, f);\n }\n break;\n case \"projection\":\n if (projection) {\n data.set(projection, f);\n }\n break;\n case \"viewProjection\":\n if (viewProjection) {\n data.set(viewProjection, f);\n }\n break;\n case \"worldView\":\n if (view) {\n mat4MultiplyInto(data, f, view, 0, world, 0);\n }\n break;\n case \"worldViewProjection\":\n if (viewProjection) {\n mat4MultiplyInto(data, f, viewProjection, 0, world, 0);\n }\n break;\n case \"cameraPosition\":\n if (camera) {\n const wm = camera.worldMatrix as unknown as ArrayLike<number>;\n data[f] = wm[12]!;\n data[f + 1] = wm[13]!;\n data[f + 2] = wm[14]!;\n }\n break;\n case \"screenSize\":\n data[f] = targetWidth;\n data[f + 1] = targetHeight;\n break;\n case \"alphaCutoff\":\n data[f] = material._uniformValues.get(\"alphaCutoff\")?.value[0] ?? 0.4;\n break;\n }\n }\n}\n\nlet zeroAttrCache: WeakMap<object, Map<string, GPUBuffer>> | null = null;\n\nfunction getZeroAttrBuffer(engine: EngineContext, gpu: MeshGPU, name: string): GPUBuffer {\n if (!zeroAttrCache) {\n zeroAttrCache = new WeakMap();\n }\n let cache = zeroAttrCache.get(gpu as unknown as object);\n if (!cache) {\n cache = new Map();\n zeroAttrCache.set(gpu as unknown as object, cache);\n }\n const existing = cache.get(name);\n if (existing) {\n return existing;\n }\n const vertexCount = gpu.positionBuffer.size / 12;\n const stride = name === \"uv\" || name === \"uv2\" ? 8 : name === \"normal\" ? 12 : 16;\n const buffer = engine._device.createBuffer({ label: `shader-zero-${name}`, size: vertexCount * stride, usage: BU.VERTEX | BU.COPY_DST });\n cache.set(name, buffer);\n return buffer;\n}\n\nfunction getAttrBuffer(engine: EngineContext, gpu: MeshGPU, name: ShaderAttributeName): GPUBuffer {\n switch (name) {\n case \"position\":\n return gpu.positionBuffer;\n case \"normal\":\n return gpu.normalBuffer ?? getZeroAttrBuffer(engine, gpu, \"normal\");\n case \"uv\":\n return gpu.uvBuffer ?? getZeroAttrBuffer(engine, gpu, \"uv\");\n case \"uv2\":\n return gpu.uv2Buffer ?? getZeroAttrBuffer(engine, gpu, \"uv2\");\n case \"tangent\":\n return gpu.tangentBuffer ?? getZeroAttrBuffer(engine, gpu, \"tangent\");\n case \"color\":\n return gpu.colorBuffer ?? getZeroAttrBuffer(engine, gpu, \"color\");\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shader-renderable.js","sources":["../../../../src/material/shader/shader-renderable.ts"],"sourcesContent":["import { F32, U32, I32, U8 } from \"../../engine/typed-arrays.js\";\nimport { BU } from \"../../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuildResult, Renderable, DrawUpdateContext } from \"../../render/renderable.js\";\nimport type { Material } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport { createEmptyUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport { getEffectiveAspectRatio, getProjectionMatrix, getViewMatrix, getViewProjectionMatrix } from \"../../camera/camera.js\";\nimport type { Camera } from \"../../camera/camera.js\";\nimport { mat4MultiplyInto } from \"../../math/mat4-multiply-into.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderUniformType } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\nimport { getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings } from \"./shader-pipeline.js\";\n\n/** @internal Exported as a type only (zero runtime bytes) for the dynamically-imported\n * thin-instance builder. */\nexport interface ShaderPacket {\n readonly mesh: Mesh;\n readonly systemUBO: GPUBuffer;\n readonly systemData: Float32Array;\n /** @internal */\n _bindGroup: GPUBindGroup;\n /** @internal */\n _lastResourceVersion: number;\n /** @internal */\n _boundTextures: Texture2D[];\n /** @internal */\n _boundStorageBuffers: GPUBuffer[];\n /** @internal Set when the owning mesh is removed and this packet's GPU resources are\n * destroyed. A combined (multi-mesh) renderable keeps every packet in its\n * closure, so update()/draw() must skip disposed packets to avoid writing to\n * or submitting an already-destroyed systemUBO / vertex buffer. */\n _disposed?: boolean;\n /** @internal Back-reference to the combined renderable's packet array, so disposal can\n * splice this packet out and stop retaining/iterating dead chunk state every\n * frame (set only for merged opaque renderables). */\n _owner?: ShaderPacket[];\n}\n\ninterface ShaderMaterialRenderState extends ShaderMaterial {\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\n/** @internal */\nexport type ShaderRenderPass = GPURenderPassEncoder | GPURenderBundleEncoder;\n\nexport function buildShaderMaterialRenderables(scene: SceneContext, meshes: Mesh[]): MeshGroupBuildResult {\n const renderables: Renderable[] = [];\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable =>\n buildSingleShaderRenderable(s, mesh, (materialOverride ?? mesh.material) as ShaderMaterial, materialOverride != null);\n\n const byMaterial = new Map<ShaderMaterial, Mesh[]>();\n for (const mesh of meshes) {\n const material = mesh.material as ShaderMaterial;\n let list = byMaterial.get(material);\n if (!list) {\n list = [];\n byMaterial.set(material, list);\n }\n list.push(mesh);\n }\n\n for (const [material, matMeshes] of byMaterial) {\n const built = buildMaterialRenderables(scene, material, matMeshes);\n renderables.push(...built);\n }\n\n return { renderables, rebuildSingle };\n}\n\n/** Async group entry point. Non-instanced ShaderMaterial scenes (the common case)\n * take the synchronous fast path and pull in zero instancing code. When at least\n * one mesh uses thin instances, the instancing module is dynamically imported and\n * the renderable helpers it needs are handed to it as positional arguments — NOT\n * module exports — so those helpers keep their mangled names in this chunk (an\n * export would de-mangle them, growing every ShaderMaterial scene's bundle). */\nexport async function buildShaderGroup(scene: SceneContext, meshes: Mesh[]): Promise<MeshGroupBuildResult> {\n if (!meshes.some((m) => !!m.thinInstances)) {\n return buildShaderMaterialRenderables(scene, meshes);\n }\n const mod = await import(\"./shader-thin-instance.js\");\n const cull = meshes.some((m) => !!m.thinInstances?._gpuCullingEnabled) ? await import(\"../../mesh/thin-instance-cull-binding.js\") : undefined;\n return mod.buildShaderRenderablesWithInstancing(\n scene,\n meshes,\n buildShaderMaterialRenderables,\n createPacket,\n updatePacket,\n updateCustomUbo,\n getAttrBuffer,\n getOrCreateShaderPipeline,\n getOrCreateShaderPipelineBindings,\n cull\n );\n}\n\nfunction buildSingleShaderRenderable(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean): Renderable {\n return buildMaterialRenderables(scene, material, [mesh], isOverride)[0]!;\n}\n\nfunction buildMaterialRenderables(scene: SceneContext, material: ShaderMaterial, meshes: readonly Mesh[], isOverride = false): Renderable[] {\n const engine = scene.surface.engine;\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n ensureCustomUbo(engine, material, bindings.customSpec);\n const packets = meshes.map((mesh) => createPacket(scene, material, bindings.systemSpec, mesh));\n const isTransparent = material.needAlphaBlending;\n if (isTransparent) {\n return packets.map((packet) => createTransparentRenderable(scene, material, packet, isOverride));\n }\n return [createOpaqueRenderable(scene, material, packets, isOverride)];\n}\n\nfunction createPacket(scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh): ShaderPacket {\n const engine = scene.surface.engine;\n const systemUBO = createEmptyUniformBuffer(engine, systemSpec._totalBytes, \"shader-system-ubo\");\n const systemData = new F32(systemSpec._totalBytes / 4);\n writeSystemUniforms(systemData, systemSpec, material, mesh, scene.camera, engine.canvas.width || 1, engine.canvas.height || 1);\n engine._device.queue.writeBuffer(systemUBO, 0, systemData);\n const packet: ShaderPacket = {\n mesh,\n systemUBO,\n systemData,\n _bindGroup: createShaderBindGroup(engine, material, systemUBO),\n _lastResourceVersion: material._resourceVersion,\n _boundTextures: collectShaderTextures(material),\n _boundStorageBuffers: collectShaderStorageBuffers(material),\n };\n for (const tex of packet._boundTextures) {\n acquireTexture(tex);\n }\n registerMeshTextureDisposer(scene, mesh, packet);\n return packet;\n}\n\nfunction createOpaqueRenderable(scene: SceneContext, material: ShaderMaterial, packets: readonly ShaderPacket[], isOverride: boolean): Renderable {\n // Only merged renderables (>1 mesh) can outlive an individual packet's mesh,\n // so give those packets a back-reference enabling disposal-time compaction.\n if (packets.length > 1) {\n for (const packet of packets) {\n packet._owner = packets as ShaderPacket[];\n }\n }\n const update = (context: DrawUpdateContext): void => {\n updateCustomUbo(scene.surface.engine, material);\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n updatePacket(scene, material, packet, context);\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n let draws = 0;\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n drawPacket(pass, engine, material, packet);\n draws++;\n }\n return draws;\n };\n const r: Renderable = {\n order: packets.length === 1 ? (packets[0]!.mesh.renderOrder ?? 100) : Math.min(...packets.map((p) => p.mesh.renderOrder ?? 100)),\n isTransparent: false,\n mesh: packets.length === 1 ? packets[0]!.mesh : undefined,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction createTransparentRenderable(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, isOverride: boolean): Renderable {\n const wm = packet.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 && packet.mesh.material !== material) {\n return;\n }\n updateCustomUbo(scene.surface.engine, material);\n updatePacket(scene, material, packet, context);\n const m = packet.mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return 0;\n }\n drawPacket(pass, engine, material, packet);\n return 1;\n };\n const r: Renderable = {\n order: packet.mesh.renderOrder ?? 200,\n isTransparent: true,\n _transmissive: material.transmissive,\n mesh: packet.mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction updatePacket(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext): void {\n const engine = scene.surface.engine;\n const state = material as ShaderMaterialRenderState;\n writeSystemUniforms(packet.systemData, state._shaderBindings!.systemSpec, material, packet.mesh, context._camera ?? scene.camera, context.targetWidth, context.targetHeight);\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n if (packet._lastResourceVersion !== material._resourceVersion) {\n // Acquire the NEW bound textures BEFORE releasing the old set: a texture present in both (e.g. a material\n // that only swapped ONE of its textures) must never transiently drop to ref-count 0, or releaseTexture\n // would destroy a GPUTexture that the new bind group still uses. (Releasing first destroys a unique\n // ref-count-1 texture — exposed by a custom material binding a per-material texture nothing else shares.)\n const newTextures = collectShaderTextures(material);\n for (const tex of newTextures) {\n acquireTexture(tex);\n }\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._bindGroup = createShaderBindGroup(engine, material, packet.systemUBO);\n packet._boundTextures = newTextures;\n packet._boundStorageBuffers = collectShaderStorageBuffers(material);\n packet._lastResourceVersion = material._resourceVersion;\n }\n}\n\nfunction drawPacket(pass: ShaderRenderPass, engine: EngineContext, material: ShaderMaterial, packet: ShaderPacket): void {\n const gpu = packet.mesh._gpu;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(i, getAttrBuffer(engine, packet.mesh, material.attributes[i]!));\n }\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n pass.drawIndexed(gpu.indexCount);\n}\n\nfunction ensureCustomUbo(engine: EngineContext, material: ShaderMaterial, customSpec: UboSpec | null): void {\n const state = material as ShaderMaterialRenderState;\n if (!customSpec) {\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = material._uniformVersion;\n return;\n }\n if (state._shaderCustomUbo && state._shaderCustomData) {\n updateCustomUbo(engine, material);\n return;\n }\n state._shaderCustomUbo = createEmptyUniformBuffer(engine, customSpec._totalBytes, \"shader-custom-ubo\");\n state._shaderCustomData = new ArrayBuffer(customSpec._totalBytes);\n state._shaderCustomVersion = -1;\n updateCustomUbo(engine, material);\n}\n\nfunction updateCustomUbo(engine: EngineContext, material: ShaderMaterial): void {\n const state = material as ShaderMaterialRenderState;\n const customSpec = state._shaderCustomSpec;\n const customUbo = state._shaderCustomUbo;\n const customData = state._shaderCustomData;\n if (!customSpec || !customUbo || !customData || state._shaderCustomVersion === material._uniformVersion) {\n return;\n }\n const bytes = new U8(customData);\n bytes.fill(0);\n for (const [name, slot] of material._uniformValues) {\n if (_isShaderSystemUniform(name)) {\n continue;\n }\n const offset = customSpec._offsets.get(name);\n if (offset !== undefined) {\n writeTypedValue(customData, offset, slot.decl.type, slot.value);\n }\n }\n engine._device.queue.writeBuffer(customUbo, 0, bytes);\n state._shaderCustomVersion = material._uniformVersion;\n}\n\nfunction writeTypedValue(data: ArrayBuffer, offset: number, type: ShaderUniformType, value: Float32Array): void {\n if (type === \"u32\") {\n new U32(data, offset, 1)[0] = value[0]!;\n return;\n }\n if (type === \"i32\") {\n new I32(data, offset, 1)[0] = value[0]!;\n return;\n }\n new F32(data, offset, value.length).set(value);\n}\n\nfunction createShaderBindGroup(engine: EngineContext, material: ShaderMaterial, systemUBO: GPUBuffer): GPUBindGroup {\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n const entries: GPUBindGroupEntry[] = [{ binding: 0, resource: { buffer: systemUBO } }];\n let nextBinding = 1;\n if (bindings.customSpec) {\n ensureCustomUbo(engine, material, bindings.customSpec);\n entries.push({ binding: nextBinding++, resource: { buffer: (material as ShaderMaterialRenderState)._shaderCustomUbo! } });\n }\n for (const sampler of material.samplerDecls) {\n const slot = material._textureSlots.get(sampler.name);\n const tex = slot?.current;\n if (!tex) {\n throw new Error(`ShaderMaterial: sampler \"${sampler.name}\" has no Texture2D. Call setShaderTexture() before rendering.`);\n }\n entries.push({ binding: nextBinding++, resource: tex.view }, { binding: nextBinding++, resource: tex.sampler });\n }\n for (const storage of material.storageBufferDecls) {\n const slot = material._storageBufferSlots.get(storage.name);\n const buffer = slot?.current;\n if (!buffer) {\n throw new Error(`ShaderMaterial: storage buffer \"${storage.name}\" has no GPUBuffer. Call setShaderStorageBuffer() before rendering.`);\n }\n entries.push({ binding: nextBinding++, resource: { buffer } });\n }\n return engine._device.createBindGroup({ label: \"shader-material-bg\", layout: bindings.group1BGL, entries });\n}\n\nfunction collectShaderTextures(material: ShaderMaterial): Texture2D[] {\n const textures: Texture2D[] = [];\n for (const slot of material._textureSlots.values()) {\n if (slot.current) {\n textures.push(slot.current);\n }\n }\n return textures;\n}\n\nfunction collectShaderStorageBuffers(material: ShaderMaterial): GPUBuffer[] {\n const buffers: GPUBuffer[] = [];\n for (const slot of material._storageBufferSlots.values()) {\n if (slot.current) {\n buffers.push(slot.current);\n }\n }\n return buffers;\n}\n\nfunction registerMeshTextureDisposer(scene: SceneContext, mesh: Mesh, packet: ShaderPacket): void {\n const list = scene._meshDisposables.get(mesh) ?? [];\n list.push(() => {\n packet._disposed = true;\n if (packet._owner) {\n const oi = packet._owner.indexOf(packet);\n if (oi >= 0) {\n packet._owner.splice(oi, 1);\n }\n packet._owner = undefined;\n }\n packet.systemUBO.destroy();\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._boundTextures = [];\n packet._boundStorageBuffers = [];\n });\n scene._meshDisposables.set(mesh, list);\n}\n\nfunction writeSystemUniforms(data: Float32Array, spec: UboSpec, material: ShaderMaterial, mesh: Mesh, camera: Camera | null, targetWidth: number, targetHeight: number): void {\n data.fill(0);\n const world = mesh.worldMatrix as unknown as Float32Array;\n const aspect = camera ? getEffectiveAspectRatio(camera, targetWidth, targetHeight) : 1;\n const view = camera ? (getViewMatrix(camera) as unknown as Float32Array) : null;\n const projection = camera ? (getProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n const viewProjection = camera ? (getViewProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n for (const uniform of material.uniformDecls) {\n if (!_isShaderSystemUniform(uniform.name)) {\n continue;\n }\n const offset = spec._offsets.get(uniform.name);\n if (offset === undefined) {\n continue;\n }\n const f = offset / 4;\n switch (uniform.name) {\n case \"world\":\n data.set(world, f);\n break;\n case \"view\":\n if (view) {\n data.set(view, f);\n }\n break;\n case \"projection\":\n if (projection) {\n data.set(projection, f);\n }\n break;\n case \"viewProjection\":\n if (viewProjection) {\n data.set(viewProjection, f);\n }\n break;\n case \"worldView\":\n if (view) {\n mat4MultiplyInto(data, f, view, 0, world, 0);\n }\n break;\n case \"worldViewProjection\":\n if (viewProjection) {\n mat4MultiplyInto(data, f, viewProjection, 0, world, 0);\n }\n break;\n case \"cameraPosition\":\n if (camera) {\n const wm = camera.worldMatrix as unknown as ArrayLike<number>;\n data[f] = wm[12]!;\n data[f + 1] = wm[13]!;\n data[f + 2] = wm[14]!;\n }\n break;\n case \"screenSize\":\n data[f] = targetWidth;\n data[f + 1] = targetHeight;\n break;\n case \"alphaCutoff\":\n data[f] = material._uniformValues.get(\"alphaCutoff\")?.value[0] ?? 0.4;\n break;\n }\n }\n}\n\nlet zeroAttrCache: WeakMap<object, Map<string, GPUBuffer>> | null = null;\n\nfunction getZeroAttrBuffer(engine: EngineContext, gpu: MeshGPU, name: string): GPUBuffer {\n if (!zeroAttrCache) {\n zeroAttrCache = new WeakMap();\n }\n let cache = zeroAttrCache.get(gpu as unknown as object);\n if (!cache) {\n cache = new Map();\n zeroAttrCache.set(gpu as unknown as object, cache);\n }\n const existing = cache.get(name);\n if (existing) {\n return existing;\n }\n const vertexCount = gpu.positionBuffer.size / 12;\n const stride = name === \"uv\" || name === \"uv2\" ? 8 : name === \"normal\" ? 12 : 16;\n const buffer = engine._device.createBuffer({ label: `shader-zero-${name}`, size: vertexCount * stride, usage: BU.VERTEX | BU.COPY_DST });\n cache.set(name, buffer);\n return buffer;\n}\n\n/** Skinning vertex buffers live on the mesh's `skeleton` (live skinning) or `vat` (baked vertex\n * animation, which moves them off the dropped skeleton) — not on `MeshGPU`. */\nfunction getSkinBuffer(mesh: Mesh, field: \"jointsBuffer\" | \"weightsBuffer\" | \"joints1Buffer\" | \"weights1Buffer\"): GPUBuffer | null {\n return mesh.vat?.[field] ?? mesh.skeleton?.[field] ?? null;\n}\n\nfunction getAttrBuffer(engine: EngineContext, mesh: Mesh, name: ShaderAttributeName): GPUBuffer {\n const gpu = mesh._gpu;\n switch (name) {\n case \"position\":\n return gpu.positionBuffer;\n case \"normal\":\n return gpu.normalBuffer ?? getZeroAttrBuffer(engine, gpu, \"normal\");\n case \"uv\":\n return gpu.uvBuffer ?? getZeroAttrBuffer(engine, gpu, \"uv\");\n case \"uv2\":\n return gpu.uv2Buffer ?? getZeroAttrBuffer(engine, gpu, \"uv2\");\n case \"tangent\":\n return gpu.tangentBuffer ?? getZeroAttrBuffer(engine, gpu, \"tangent\");\n case \"color\":\n return gpu.colorBuffer ?? getZeroAttrBuffer(engine, gpu, \"color\");\n case \"joints\":\n return getSkinBuffer(mesh, \"jointsBuffer\") ?? getZeroAttrBuffer(engine, gpu, \"joints\");\n case \"weights\":\n return getSkinBuffer(mesh, \"weightsBuffer\") ?? getZeroAttrBuffer(engine, gpu, \"weights\");\n case \"joints1\":\n return getSkinBuffer(mesh, \"joints1Buffer\") ?? getZeroAttrBuffer(engine, gpu, \"joints1\");\n case \"weights1\":\n return getSkinBuffer(mesh, \"weights1Buffer\") ?? getZeroAttrBuffer(engine, gpu, \"weights1\");\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -74,7 +74,7 @@ function createShaderInstancedRenderable(scene, material, packet, isOverride, h,
|
|
|
74
74
|
const gpu = mesh._gpu;
|
|
75
75
|
let slot = 0;
|
|
76
76
|
for (let i = 0; i < material.attributes.length; i++) {
|
|
77
|
-
pass.setVertexBuffer(slot++, h.getAttrBuffer(engine,
|
|
77
|
+
pass.setVertexBuffer(slot++, h.getAttrBuffer(engine, mesh, material.attributes[i]));
|
|
78
78
|
}
|
|
79
79
|
slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, cullBinding?.cullDrawBufs);
|
|
80
80
|
pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);
|
|
@@ -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, 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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"}
|
|
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 } 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, mesh: Mesh, 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, mesh, 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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"}
|
package/lib/scene/scene-core.js
CHANGED
|
@@ -33,6 +33,7 @@ function createSceneContext(surface, options) {
|
|
|
33
33
|
_renderableVersion: 0,
|
|
34
34
|
_materialEpoch: 0,
|
|
35
35
|
_built: false,
|
|
36
|
+
_builtGroups: /* @__PURE__ */ new Set(),
|
|
36
37
|
_drawCallsPre: 0,
|
|
37
38
|
_update() {
|
|
38
39
|
if (eng.useFloatingOrigin && ctx.camera && !ctx.camera._useFloatingOrigin) {
|
|
@@ -138,10 +139,11 @@ function addToScene(scene, entity) {
|
|
|
138
139
|
if (result.updater) {
|
|
139
140
|
ctx._uniformUpdaters.push(result.updater);
|
|
140
141
|
}
|
|
142
|
+
ctx._builtGroups.add(build);
|
|
141
143
|
});
|
|
142
144
|
}
|
|
143
145
|
group.push(mesh);
|
|
144
|
-
if (ctx._built) {
|
|
146
|
+
if (ctx._built || ctx._builtGroups.has(build)) {
|
|
145
147
|
enqueueMaterialSwap(ctx, mesh);
|
|
146
148
|
}
|
|
147
149
|
}
|
|
@@ -189,12 +191,13 @@ function disposeScene(scene) {
|
|
|
189
191
|
}
|
|
190
192
|
async function buildScene(scene) {
|
|
191
193
|
const ctx = scene;
|
|
194
|
+
ctx._materialSwapQueue.length = 0;
|
|
192
195
|
while (ctx._deferredBuilders.length > 0) {
|
|
193
196
|
const builders = [...ctx._deferredBuilders];
|
|
194
197
|
ctx._deferredBuilders = [];
|
|
195
198
|
await Promise.all(builders.map(async (b) => b()));
|
|
196
199
|
}
|
|
197
|
-
ctx
|
|
200
|
+
processMaterialSwaps(ctx);
|
|
198
201
|
ctx._renderableVersion++;
|
|
199
202
|
ctx._built = true;
|
|
200
203
|
}
|