@babylonjs/lite 1.7.0 → 1.8.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/CHANGELOG.md +735 -0
- package/README.md +26 -1
- package/THIRD_PARTY_NOTICES.txt +139 -0
- package/dist/index.js +292 -277
- package/dist/index.js.map +1 -1
- package/index.d.ts +277 -11
- package/lib/_chunks/vendor/{manifold-Sh8xE2da.js → manifold-DtI3BJoR.js} +2 -2
- package/lib/_chunks/vendor/{manifold-Sh8xE2da.js.map → manifold-DtI3BJoR.js.map} +1 -1
- package/lib/animation/animation-group-task.js +1 -1
- package/lib/animation/animation-group-task.js.map +1 -1
- package/lib/animation/animation-group.js +20 -15
- package/lib/animation/animation-group.js.map +1 -1
- package/lib/animation/animation-tick.js +10 -0
- package/lib/animation/animation-tick.js.map +1 -0
- package/lib/animation/property-animation.js +2 -1
- package/lib/animation/property-animation.js.map +1 -1
- package/lib/animation/weighted-gltf-mixer.js +1 -1
- package/lib/animation/weighted-gltf-mixer.js.map +1 -1
- package/lib/animation/weighted-pointer-mixer.js +1 -1
- package/lib/animation/weighted-pointer-mixer.js.map +1 -1
- package/lib/engine/device-lost-recovery.js +1 -0
- package/lib/engine/device-lost-recovery.js.map +1 -1
- package/lib/engine/engine.js +1 -1
- package/lib/engine/null-engine.js +29 -0
- package/lib/engine/null-engine.js.map +1 -0
- package/lib/frame-graph/depth-pyramid.js +158 -0
- package/lib/frame-graph/depth-pyramid.js.map +1 -0
- package/lib/frame-graph/frame-graph-actions.js +10 -1
- package/lib/frame-graph/frame-graph-actions.js.map +1 -1
- package/lib/frame-graph/render-task.js +7 -0
- package/lib/frame-graph/render-task.js.map +1 -1
- package/lib/frame-graph/transmission-depth-grab.js +88 -0
- package/lib/frame-graph/transmission-depth-grab.js.map +1 -0
- package/lib/frame-graph/transmission.js +30 -1
- package/lib/frame-graph/transmission.js.map +1 -1
- package/lib/gizmo/bounding-box-gizmo.js +1 -1
- package/lib/index.js +8 -6
- package/lib/index.js.map +1 -1
- package/lib/loader-gltf/gltf-feature-gpu-instancing.js +1 -1
- package/lib/loader-gltf/gltf-interleave.js +1 -1
- package/lib/loader-gltf/load-gltf.js +1 -1
- package/lib/material/shader/shader-pipeline.js +1 -1
- package/lib/material/shader/shader-pipeline.js.map +1 -1
- package/lib/material/shader/shader-renderable.js +23 -8
- package/lib/material/shader/shader-renderable.js.map +1 -1
- package/lib/math/aabb.js +1 -1
- package/lib/math/compute-aabb.js +63 -1
- package/lib/math/compute-aabb.js.map +1 -1
- package/lib/math/index.js +1 -1
- package/lib/mesh/csg2.js +3 -2
- package/lib/mesh/csg2.js.map +1 -1
- package/lib/mesh/mesh-factories.js +1 -1
- package/lib/mesh/thin-instance-gpu-culling.js +4 -2
- package/lib/mesh/thin-instance-gpu-culling.js.map +1 -1
- package/lib/mesh/thin-instance.js +8 -1
- package/lib/mesh/thin-instance.js.map +1 -1
- package/lib/navigation/index.js +1 -1
- package/lib/navigation/navigation.js +9 -1
- package/lib/navigation/navigation.js.map +1 -1
- package/lib/physics/character-controller.js +2 -2
- package/lib/physics/character-controller.js.map +1 -1
- package/lib/physics/havok-floating-origin.js +2 -2
- package/lib/physics/havok-floating-origin.js.map +1 -1
- package/lib/physics/havok.js +40 -13
- package/lib/physics/havok.js.map +1 -1
- package/lib/picking/gpu-picker.js +16 -2
- package/lib/picking/gpu-picker.js.map +1 -1
- package/lib/scene/scene-core.js +9 -3
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/scene/scene-remove.js +8 -0
- package/lib/scene/scene-remove.js.map +1 -1
- package/lib/texture/pixels-texture.js +31 -1
- package/lib/texture/pixels-texture.js.map +1 -1
- package/lib/vat/vat-baker.js +41 -2
- package/lib/vat/vat-baker.js.map +1 -1
- package/package.json +15 -3
- package/lib/_chunks/__vite-browser-external-BFTKbDcV.js +0 -68
- package/lib/_chunks/__vite-browser-external-BFTKbDcV.js.map +0 -1
|
@@ -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 // 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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"}
|
|
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 /** @internal Inputs of the last system-UBO write, used to skip redundant recompute + writeBuffer\n * (see updatePacket). Undefined until the first per-pass update. */\n _lastCamera?: Camera | null;\n /** @internal */\n _lastCameraVersion?: number;\n /** @internal */\n _lastMeshWmVersion?: number;\n /** @internal */\n _lastTargetWidth?: number;\n /** @internal */\n _lastTargetHeight?: number;\n /** @internal Effective camera aspect (getEffectiveAspectRatio) at the last write — a `camera.viewport`\n * change can alter the aspect (hence projection/viewProjection) while target size stays the same. */\n _lastAspect?: number;\n /** @internal */\n _lastAlphaCutoff?: number;\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 // `isOverride` marks an AUX view packet (a material-override registered into an explicit task, e.g. a\n // depth/SSAO no-colour view) — route its disposer to `_meshAuxDisposables` so a MAIN-material swap of this\n // same mesh does not tear it down out from under that task.\n const packets = meshes.map((mesh) => createPacket(scene, material, bindings.systemSpec, mesh, isOverride));\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, aux = false): 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, aux);\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 // Skip the system-UBO recompute + writeBuffer when EVERY input is unchanged since this packet's last\n // write: same camera (identity + worldMatrixVersion — the same change key the view/projection caches\n // already rely on), same mesh world-matrix version, same target size and same material uniform version\n // (alphaCutoff). A packet is updated once per PASS per frame, and most packets are static meshes under\n // a camera that only moves some frames — these per-packet writeBuffers dominate CPU frame time in\n // large scenes, and the skipped ones are byte-identical rewrites of what the UBO already holds.\n const camera = context._camera ?? scene.camera;\n const cameraVersion = camera ? camera.worldMatrixVersion : -1;\n const meshWmVersion = packet.mesh.worldMatrixVersion;\n // alphaCutoff is compared by VALUE, not by the material's uniform version: animated materials bump\n // that version every frame (time uniforms and the like live in the CUSTOM ubo, which has its own\n // version gate), and keying on it would defeat this skip for exactly the materials that dominate.\n const alphaCutoff = material._uniformValues.get(\"alphaCutoff\")?.value[0] ?? 0.4;\n // Effective aspect keys the view/projection uniforms: getEffectiveAspectRatio folds in the camera's\n // normalized viewport, which can change (altering projection) with target size and worldMatrixVersion\n // both unchanged, so targetWidth/Height alone would not catch it.\n const aspect = camera ? getEffectiveAspectRatio(camera, context.targetWidth, context.targetHeight) : 1;\n if (\n packet._lastCamera !== camera ||\n packet._lastCameraVersion !== cameraVersion ||\n packet._lastMeshWmVersion !== meshWmVersion ||\n packet._lastTargetWidth !== context.targetWidth ||\n packet._lastTargetHeight !== context.targetHeight ||\n packet._lastAspect !== aspect ||\n packet._lastAlphaCutoff !== alphaCutoff\n ) {\n writeSystemUniforms(packet.systemData, state._shaderBindings!.systemSpec, material, packet.mesh, camera, context.targetWidth, context.targetHeight);\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n packet._lastCamera = camera;\n packet._lastCameraVersion = cameraVersion;\n packet._lastMeshWmVersion = meshWmVersion;\n packet._lastTargetWidth = context.targetWidth;\n packet._lastTargetHeight = context.targetHeight;\n packet._lastAspect = aspect;\n packet._lastAlphaCutoff = alphaCutoff;\n }\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, aux = false): void {\n // Aux (override) view packets go in `_meshAuxDisposables` so a main-material swap leaves them alone; main\n // packets stay in `_meshDisposables` (torn down + rebuilt by the swap drain). Both are drained on real removal.\n const map = aux ? scene._meshAuxDisposables : scene._meshDisposables;\n const list = map.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 map.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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"}
|
package/lib/math/aabb.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { computeAabb } from './compute-aabb.js';
|
|
2
2
|
//# sourceMappingURL=aabb.js.map
|
package/lib/math/compute-aabb.js
CHANGED
|
@@ -1,2 +1,64 @@
|
|
|
1
|
-
|
|
1
|
+
function computeAabb(positions, world) {
|
|
2
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
3
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
4
|
+
if (world) {
|
|
5
|
+
const m0 = world[0], m1 = world[1], m2 = world[2], m4 = world[4], m5 = world[5], m6 = world[6], m8 = world[8], m9 = world[9], m10 = world[10], m12 = world[12], m13 = world[13], m14 = world[14];
|
|
6
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
7
|
+
const lx = positions[i];
|
|
8
|
+
const ly = positions[i + 1];
|
|
9
|
+
const lz = positions[i + 2];
|
|
10
|
+
const x = m0 * lx + m4 * ly + m8 * lz + m12;
|
|
11
|
+
const y = m1 * lx + m5 * ly + m9 * lz + m13;
|
|
12
|
+
const z = m2 * lx + m6 * ly + m10 * lz + m14;
|
|
13
|
+
if (x < minX) {
|
|
14
|
+
minX = x;
|
|
15
|
+
}
|
|
16
|
+
if (x > maxX) {
|
|
17
|
+
maxX = x;
|
|
18
|
+
}
|
|
19
|
+
if (y < minY) {
|
|
20
|
+
minY = y;
|
|
21
|
+
}
|
|
22
|
+
if (y > maxY) {
|
|
23
|
+
maxY = y;
|
|
24
|
+
}
|
|
25
|
+
if (z < minZ) {
|
|
26
|
+
minZ = z;
|
|
27
|
+
}
|
|
28
|
+
if (z > maxZ) {
|
|
29
|
+
maxZ = z;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
34
|
+
const x = positions[i];
|
|
35
|
+
const y = positions[i + 1];
|
|
36
|
+
const z = positions[i + 2];
|
|
37
|
+
if (x < minX) {
|
|
38
|
+
minX = x;
|
|
39
|
+
}
|
|
40
|
+
if (x > maxX) {
|
|
41
|
+
maxX = x;
|
|
42
|
+
}
|
|
43
|
+
if (y < minY) {
|
|
44
|
+
minY = y;
|
|
45
|
+
}
|
|
46
|
+
if (y > maxY) {
|
|
47
|
+
maxY = y;
|
|
48
|
+
}
|
|
49
|
+
if (z < minZ) {
|
|
50
|
+
minZ = z;
|
|
51
|
+
}
|
|
52
|
+
if (z > maxZ) {
|
|
53
|
+
maxZ = z;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return [
|
|
58
|
+
[minX, minY, minZ],
|
|
59
|
+
[maxX, maxY, maxZ]
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { computeAabb };
|
|
2
64
|
//# sourceMappingURL=compute-aabb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute-aabb.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"compute-aabb.js","sources":["../../../src/math/compute-aabb.ts"],"sourcesContent":["/** Axis-aligned bounding box helpers. */\n\nimport type { Aabb } from \"./aabb.js\";\nimport type { Mat4 } from \"./types.js\";\n\n/** Compute an AABB by folding XYZ min/max over a positions buffer.\n *\n * When `world` is provided each position is transformed by it before being\n * folded (column-major Mat4: m[col*4+row]). Otherwise the AABB is computed\n * in the positions' own space.\n *\n * Returns `[[+Inf,+Inf,+Inf],[-Inf,-Inf,-Inf]]` for empty input — callers\n * that care can check `isFinite(min[0])`. */\nexport function computeAabb(positions: Float32Array, world?: Mat4): Aabb {\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n\n if (world) {\n const m0 = world[0]!,\n m1 = world[1]!,\n m2 = world[2]!,\n m4 = world[4]!,\n m5 = world[5]!,\n m6 = world[6]!,\n m8 = world[8]!,\n m9 = world[9]!,\n m10 = world[10]!,\n m12 = world[12]!,\n m13 = world[13]!,\n m14 = world[14]!;\n for (let i = 0; i < positions.length; i += 3) {\n const lx = positions[i]!;\n const ly = positions[i + 1]!;\n const lz = positions[i + 2]!;\n const x = m0 * lx + m4 * ly + m8 * lz + m12;\n const y = m1 * lx + m5 * ly + m9 * lz + m13;\n const z = m2 * lx + m6 * ly + m10 * lz + m14;\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n } else {\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i]!;\n const y = positions[i + 1]!;\n const z = positions[i + 2]!;\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n }\n\n return [\n [minX, minY, minZ],\n [maxX, maxY, maxZ],\n ];\n}\n"],"names":[],"mappings":"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"}
|
package/lib/math/index.js
CHANGED
|
@@ -25,7 +25,7 @@ export { mat4FromQuat } from './mat4-from-quat.js';
|
|
|
25
25
|
export { mat4Compose } from './mat4-compose.js';
|
|
26
26
|
export { mat4ComposeInto } from './mat4-compose-into.js';
|
|
27
27
|
export { mat4MultiplyInto } from './mat4-multiply-into.js';
|
|
28
|
-
export {
|
|
28
|
+
export { computeAabb } from './compute-aabb.js';
|
|
29
29
|
export { ObservableVec3 } from './observable-vec3.js';
|
|
30
30
|
export { ObservableQuat } from './observable-quat.js';
|
|
31
31
|
export { packMat4IntoF32 } from './pack-mat4-into-f32.js';
|
package/lib/mesh/csg2.js
CHANGED
|
@@ -20,9 +20,10 @@ async function getRuntimeAsync() {
|
|
|
20
20
|
return csg2RuntimePromise;
|
|
21
21
|
}
|
|
22
22
|
csg2RuntimePromise = (async () => {
|
|
23
|
-
const [module, wasm] = await Promise.all([import('../_chunks/vendor/manifold-
|
|
23
|
+
const [module, wasm] = await Promise.all([import('../_chunks/vendor/manifold-DtI3BJoR.js').then(n => n.m), import('../_chunks/vendor/manifold-DtI3BJoR.js').then(n => n.a)]);
|
|
24
|
+
const moduleUrl = import.meta.url;
|
|
24
25
|
const manifoldModule = await module.default({
|
|
25
|
-
locateFile: () => new URL(wasm.default,
|
|
26
|
+
locateFile: () => new URL(wasm.default, moduleUrl).href
|
|
26
27
|
});
|
|
27
28
|
manifoldModule.setup();
|
|
28
29
|
const runtime = {
|
package/lib/mesh/csg2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csg2.js","sources":["../../../src/mesh/csg2.ts"],"sourcesContent":["import { F32, U32 } from \"../engine/typed-arrays.js\";\nimport type { Manifold, ManifoldToplevel, Mesh as ManifoldMesh } from \"manifold-3d\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Material } from \"../material/material.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh } from \"./mesh.js\";\nimport { mat4Invert } from \"../math/mat4-invert.js\";\nimport { normalizeVec3 } from \"../math/normalize-vec3.js\";\nimport { createMeshFromData } from \"./mesh-factories.js\";\n\ndeclare const csg2SolidBrand: unique symbol;\n\nconst MATERIAL_ID_RESERVE_COUNT = 65536;\n\n/** A manifold-3d backed CSG solid for high-precision boolean mesh operations. */\nexport interface Csg2Solid {\n readonly [csg2SolidBrand]: true;\n /** @internal */\n _manifold: Manifold | null;\n /** @internal */\n readonly _numProp: number;\n}\n\ninterface Csg2Runtime {\n readonly Manifold: typeof Manifold;\n readonly Mesh: typeof ManifoldMesh;\n readonly firstMaterialId: number;\n}\n\ninterface GeometryBuffers {\n readonly positions: Float32Array;\n readonly normals: Float32Array;\n readonly indices: Uint32Array;\n readonly uvs: Float32Array | undefined;\n}\n\nlet csg2Runtime: Csg2Runtime | null = null;\nlet csg2RuntimePromise: Promise<Csg2Runtime> | null = null;\n\n/** Returns whether the manifold-3d runtime has finished loading and CSG2 is usable. */\nexport function isCsg2Ready(): boolean {\n return csg2Runtime !== null;\n}\n\n/** Loads the manifold-3d WASM runtime. Must be awaited once before any CSG2 operation. */\nexport async function initializeCsg2Async(): Promise<void> {\n await getRuntimeAsync();\n}\n\nasync function getRuntimeAsync(): Promise<Csg2Runtime> {\n if (csg2Runtime) {\n return csg2Runtime;\n }\n if (csg2RuntimePromise) {\n return csg2RuntimePromise;\n }\n\n csg2RuntimePromise = (async () => {\n const [module, wasm] = await Promise.all([import(\"manifold-3d\"), import(\"manifold-3d/manifold.wasm?url\")]);\n const manifoldModule: ManifoldToplevel = await module.default({\n locateFile: () => new URL(wasm.default, import.meta.url).href,\n });\n manifoldModule.setup();\n const runtime = {\n Manifold: manifoldModule.Manifold,\n Mesh: manifoldModule.Mesh,\n firstMaterialId: manifoldModule.Manifold.reserveIDs(MATERIAL_ID_RESERVE_COUNT),\n };\n csg2Runtime = runtime;\n return runtime;\n })();\n\n return csg2RuntimePromise;\n}\n\nfunction requireRuntime(): Csg2Runtime {\n if (!csg2Runtime) {\n throw new Error(\"CSG2 is not initialized. Call and await initializeCsg2Async() before using CSG2 operations.\");\n }\n return csg2Runtime;\n}\n\nfunction requireSolidManifold(solid: Csg2Solid, operation: string): Manifold {\n const manifold = solid._manifold;\n if (!manifold) {\n throw new Error(`${operation} cannot use a disposed CSG2 solid.`);\n }\n return manifold;\n}\n\nfunction solidFromManifold(manifold: Manifold, numProp: number): Csg2Solid {\n return { _manifold: manifold, _numProp: numProp } as unknown as Csg2Solid;\n}\n\nfunction transformPoint(m: Mat4, x: number, y: number, z: number): [number, number, number] {\n return [m[0]! * x + m[4]! * y + m[8]! * z + m[12]!, m[1]! * x + m[5]! * y + m[9]! * z + m[13]!, m[2]! * x + m[6]! * y + m[10]! * z + m[14]!];\n}\n\nfunction transformNormal(m: Mat4, inv: Mat4 | null, x: number, y: number, z: number): [number, number, number] {\n if (inv) {\n return normalizeVec3(inv[0]! * x + inv[1]! * y + inv[2]! * z, inv[4]! * x + inv[5]! * y + inv[6]! * z, inv[8]! * x + inv[9]! * y + inv[10]! * z, 1e-20);\n }\n return normalizeVec3(m[0]! * x + m[4]! * y + m[8]! * z, m[1]! * x + m[5]! * y + m[9]! * z, m[2]! * x + m[6]! * y + m[10]! * z, 1e-20);\n}\n\nfunction requireCpuGeometry(mesh: Mesh): GeometryBuffers {\n if (!mesh._cpuPositions) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU positions. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n if (!mesh._cpuIndices) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU indices. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n if (!mesh._cpuNormals) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU normals. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n return {\n positions: mesh._cpuPositions,\n normals: mesh._cpuNormals,\n indices: mesh._cpuIndices,\n uvs: mesh._cpuUvs,\n };\n}\n\n/**\n * Builds a {@link Csg2Solid} from a mesh's CPU geometry, baking its world transform.\n * @param mesh - Source mesh; must retain CPU positions, normals, and indices.\n * @param materialSlot - Material slot index (0 to 65535) tagged onto the solid's triangles.\n * @returns A CSG2 solid; call {@link disposeCsg2} when finished to free WASM memory.\n */\nexport function createCsg2FromMesh(mesh: Mesh, materialSlot = 0): Csg2Solid {\n const runtime = requireRuntime();\n if (materialSlot < 0 || materialSlot >= MATERIAL_ID_RESERVE_COUNT || !Number.isInteger(materialSlot)) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") materialSlot must be an integer from 0 to ${MATERIAL_ID_RESERVE_COUNT - 1}.`);\n }\n\n const geometry = requireCpuGeometry(mesh);\n const vertexCount = geometry.positions.length / 3;\n const numProp = 8;\n const vertProperties = new F32(vertexCount * numProp);\n const world = mesh.worldMatrix;\n const invWorld = mat4Invert(world);\n\n for (let i = 0; i < vertexCount; i++) {\n const p = i * 3;\n const uv = i * 2;\n const out = i * numProp;\n const [x, y, z] = transformPoint(world, geometry.positions[p]!, geometry.positions[p + 1]!, geometry.positions[p + 2]!);\n const [nx, ny, nz] = transformNormal(world, invWorld, geometry.normals[p]!, geometry.normals[p + 1]!, geometry.normals[p + 2]!);\n vertProperties[out] = x;\n vertProperties[out + 1] = y;\n vertProperties[out + 2] = z;\n vertProperties[out + 3] = nx;\n vertProperties[out + 4] = ny;\n vertProperties[out + 5] = nz;\n vertProperties[out + 6] = geometry.uvs?.[uv] ?? 0;\n vertProperties[out + 7] = geometry.uvs?.[uv + 1] ?? 0;\n }\n\n const triVerts = new U32(geometry.indices.length);\n for (let i = 0; i < geometry.indices.length; i += 3) {\n triVerts[i] = geometry.indices[i + 2]!;\n triVerts[i + 1] = geometry.indices[i + 1]!;\n triVerts[i + 2] = geometry.indices[i]!;\n }\n\n const manifoldMesh = new runtime.Mesh({\n numProp,\n vertProperties,\n triVerts,\n runIndex: new U32([0]),\n runOriginalID: new U32([runtime.firstMaterialId + materialSlot]),\n });\n manifoldMesh.merge();\n\n try {\n // manifold-3d's `setup()` replaces `Manifold` with a factory function,\n // `function (mesh) { const m = new ManifoldCtor(mesh); …; return m; }`, that has no\n // `this` reference. A downstream esbuild/terser minifier (the dist build, or any\n // consumer bundling `build/lib`) rewrites such a function expression into an arrow\n // function, which is NOT constructable — so `new runtime.Manifold(mesh)` throws\n // \"Manifold is not a constructor\". The wrapper returns the solid whether invoked with\n // or without `new`, so call it as a plain factory to stay robust under minification.\n const manifoldFactory = runtime.Manifold as unknown as (mesh: ManifoldMesh) => Manifold;\n return solidFromManifold(manifoldFactory(manifoldMesh), numProp);\n } catch (err) {\n throw new Error(`Error while creating CSG2 from mesh \"${mesh.name}\".`, { cause: err });\n }\n}\n\nfunction runBooleanOperation(operation: \"difference\" | \"intersection\" | \"union\", a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n const runtime = requireRuntime();\n if (a._numProp !== b._numProp) {\n throw new Error(\"CSG2 operations require solids with the same vertex property layout.\");\n }\n return solidFromManifold(runtime.Manifold[operation](requireSolidManifold(a, `csg2 ${operation}`), requireSolidManifold(b, `csg2 ${operation}`)), a._numProp);\n}\n\n/** Returns the boolean difference (`a` − `b`) of two solids as a new solid. */\nexport function csg2Subtract(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"difference\", a, b);\n}\n\n/** Returns the boolean intersection (`a` ∩ `b`) of two solids as a new solid. */\nexport function csg2Intersect(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"intersection\", a, b);\n}\n\n/** Returns the boolean union (`a` ∪ `b`) of two solids as a new solid. */\nexport function csg2Add(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"union\", a, b);\n}\n\n/** Frees the WASM memory backing a solid. The solid must not be used afterwards. */\nexport function disposeCsg2(solid: Csg2Solid): void {\n if (solid._manifold) {\n solid._manifold.delete();\n solid._manifold = null;\n }\n}\n\nfunction materialSlotFromOriginalId(runtime: Csg2Runtime, originalId: number, name: string): number {\n const materialSlot = originalId - runtime.firstMaterialId;\n if (materialSlot < 0 || materialSlot >= MATERIAL_ID_RESERVE_COUNT) {\n throw new Error(`createMeshesFromCsg2(\"${name}\") received an unknown Manifold material original ID ${originalId}.`);\n }\n return materialSlot;\n}\n\nfunction appendTriangle(\n output: { positions: number[]; normals: number[]; uvs: number[]; indices: number[] },\n mesh: ManifoldMesh,\n triVerts: Uint32Array,\n numProp: number,\n triIndex: number\n): void {\n const base = output.positions.length / 3;\n for (let corner = 2; corner >= 0; corner--) {\n const vertexIndex = triVerts[triIndex + corner]!;\n const prop = vertexIndex * numProp;\n output.positions.push(mesh.vertProperties[prop]!, mesh.vertProperties[prop + 1]!, mesh.vertProperties[prop + 2]!);\n output.normals.push(mesh.vertProperties[prop + 3]!, mesh.vertProperties[prop + 4]!, mesh.vertProperties[prop + 5]!);\n output.uvs.push(mesh.vertProperties[prop + 6]!, mesh.vertProperties[prop + 7]!);\n output.indices.push(base + (2 - corner));\n }\n}\n\nfunction createMeshFromOutput(engine: EngineContext, name: string, output: { positions: number[]; normals: number[]; uvs: number[]; indices: number[] }): Mesh {\n if (output.positions.length === 0) {\n throw new Error(`Unable to build CSG2 mesh \"${name}\". Manifold has 0 vertices for this output.`);\n }\n return createMeshFromData(engine, name, new F32(output.positions), new F32(output.normals), new U32(output.indices), new F32(output.uvs));\n}\n\n/**\n * Triangulates a {@link Csg2Solid} into a single renderable mesh.\n * @param name - Name for the created mesh.\n */\nexport function createMeshFromCsg2(engine: EngineContext, solid: Csg2Solid, name = \"csg2\"): Mesh {\n requireRuntime();\n const mesh = requireSolidManifold(solid, `createMeshFromCsg2(\"${name}\")`).getMesh();\n const output = { positions: [] as number[], normals: [] as number[], uvs: [] as number[], indices: [] as number[] };\n for (let i = 0; i < mesh.triVerts.length; i += 3) {\n appendTriangle(output, mesh, mesh.triVerts, solid._numProp, i);\n }\n return createMeshFromOutput(engine, name, output);\n}\n\n/**\n * Triangulates a {@link Csg2Solid} into one mesh per material slot.\n * @param materials - Materials indexed by the material slots assigned during construction.\n * @param name - Base name; each sub-mesh is suffixed with its slot index.\n * @returns One mesh per distinct material slot, each assigned its corresponding material.\n */\nexport function createMeshesFromCsg2(engine: EngineContext, solid: Csg2Solid, materials: readonly Material[], name = \"csg2\"): Mesh[] {\n const runtime = requireRuntime();\n const mesh = requireSolidManifold(solid, `createMeshesFromCsg2(\"${name}\")`).getMesh();\n const outputs: Array<{ materialSlot: number; positions: number[]; normals: number[]; uvs: number[]; indices: number[] }> = [];\n\n for (let run = 0; run < mesh.numRun; run++) {\n const originalId = mesh.runOriginalID[run]!;\n const materialSlot = materialSlotFromOriginalId(runtime, originalId, name);\n let output = outputs.find((entry) => entry.materialSlot === materialSlot);\n if (!output) {\n output = { materialSlot, positions: [], normals: [], uvs: [], indices: [] };\n outputs.push(output);\n }\n\n const start = mesh.runIndex[run] ?? 0;\n const end = mesh.runIndex[run + 1] ?? mesh.triVerts.length;\n for (let i = start; i < end; i += 3) {\n appendTriangle(output, mesh, mesh.triVerts, solid._numProp, i);\n }\n }\n\n outputs.sort((a, b) => a.materialSlot - b.materialSlot);\n return outputs.map((output) => {\n const material = materials[output.materialSlot];\n if (!material) {\n throw new Error(`createMeshesFromCsg2(\"${name}\") missing material for CSG2 material slot ${output.materialSlot}.`);\n }\n const result = createMeshFromOutput(engine, `${name}_sub${output.materialSlot}`, output);\n result.material = material;\n return result;\n });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"csg2.js","sources":["../../../src/mesh/csg2.ts"],"sourcesContent":["import { F32, U32 } from \"../engine/typed-arrays.js\";\nimport type { Manifold, ManifoldToplevel, Mesh as ManifoldMesh } from \"manifold-3d\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Material } from \"../material/material.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh } from \"./mesh.js\";\nimport { mat4Invert } from \"../math/mat4-invert.js\";\nimport { normalizeVec3 } from \"../math/normalize-vec3.js\";\nimport { createMeshFromData } from \"./mesh-factories.js\";\n\ndeclare const csg2SolidBrand: unique symbol;\n\nconst MATERIAL_ID_RESERVE_COUNT = 65536;\n\n/** A manifold-3d backed CSG solid for high-precision boolean mesh operations. */\nexport interface Csg2Solid {\n readonly [csg2SolidBrand]: true;\n /** @internal */\n _manifold: Manifold | null;\n /** @internal */\n readonly _numProp: number;\n}\n\ninterface Csg2Runtime {\n readonly Manifold: typeof Manifold;\n readonly Mesh: typeof ManifoldMesh;\n readonly firstMaterialId: number;\n}\n\ninterface GeometryBuffers {\n readonly positions: Float32Array;\n readonly normals: Float32Array;\n readonly indices: Uint32Array;\n readonly uvs: Float32Array | undefined;\n}\n\nlet csg2Runtime: Csg2Runtime | null = null;\nlet csg2RuntimePromise: Promise<Csg2Runtime> | null = null;\n\n/** Returns whether the manifold-3d runtime has finished loading and CSG2 is usable. */\nexport function isCsg2Ready(): boolean {\n return csg2Runtime !== null;\n}\n\n/** Loads the manifold-3d WASM runtime. Must be awaited once before any CSG2 operation. */\nexport async function initializeCsg2Async(): Promise<void> {\n await getRuntimeAsync();\n}\n\nasync function getRuntimeAsync(): Promise<Csg2Runtime> {\n if (csg2Runtime) {\n return csg2Runtime;\n }\n if (csg2RuntimePromise) {\n return csg2RuntimePromise;\n }\n\n csg2RuntimePromise = (async () => {\n const [module, wasm] = await Promise.all([import(\"manifold-3d\"), import(\"manifold-3d/manifold.wasm?url\")]);\n // Alias `import.meta.url` to a local before the `new URL(...)` below. Webpack's URL parser\n // only resolves `new URL(<literal>, import.meta.url)` to an emitted asset; with our runtime\n // first arg (`wasm.default`) it can't, so it emits a \"Critical dependency: the request of a\n // dependency is an expression\" warning (fatal for consumers that treat warnings as errors).\n // The alias hides that literal pattern from the heuristic. Nothing is lost: no bundler can\n // statically resolve the runtime arg, so none was emitting an asset here — the wasm URL comes\n // from the `?url` import above. `import.meta.url` is still substituted normally (it's a\n // meta-property rewrite, not gated on the `new URL` position), so runtime behavior and\n // relative-URL resolution are identical under webpack, Vite/Rollup, esbuild, and Parcel.\n const moduleUrl = import.meta.url;\n const manifoldModule: ManifoldToplevel = await module.default({\n locateFile: () => new URL(wasm.default, moduleUrl).href,\n });\n manifoldModule.setup();\n const runtime = {\n Manifold: manifoldModule.Manifold,\n Mesh: manifoldModule.Mesh,\n firstMaterialId: manifoldModule.Manifold.reserveIDs(MATERIAL_ID_RESERVE_COUNT),\n };\n csg2Runtime = runtime;\n return runtime;\n })();\n\n return csg2RuntimePromise;\n}\n\nfunction requireRuntime(): Csg2Runtime {\n if (!csg2Runtime) {\n throw new Error(\"CSG2 is not initialized. Call and await initializeCsg2Async() before using CSG2 operations.\");\n }\n return csg2Runtime;\n}\n\nfunction requireSolidManifold(solid: Csg2Solid, operation: string): Manifold {\n const manifold = solid._manifold;\n if (!manifold) {\n throw new Error(`${operation} cannot use a disposed CSG2 solid.`);\n }\n return manifold;\n}\n\nfunction solidFromManifold(manifold: Manifold, numProp: number): Csg2Solid {\n return { _manifold: manifold, _numProp: numProp } as unknown as Csg2Solid;\n}\n\nfunction transformPoint(m: Mat4, x: number, y: number, z: number): [number, number, number] {\n return [m[0]! * x + m[4]! * y + m[8]! * z + m[12]!, m[1]! * x + m[5]! * y + m[9]! * z + m[13]!, m[2]! * x + m[6]! * y + m[10]! * z + m[14]!];\n}\n\nfunction transformNormal(m: Mat4, inv: Mat4 | null, x: number, y: number, z: number): [number, number, number] {\n if (inv) {\n return normalizeVec3(inv[0]! * x + inv[1]! * y + inv[2]! * z, inv[4]! * x + inv[5]! * y + inv[6]! * z, inv[8]! * x + inv[9]! * y + inv[10]! * z, 1e-20);\n }\n return normalizeVec3(m[0]! * x + m[4]! * y + m[8]! * z, m[1]! * x + m[5]! * y + m[9]! * z, m[2]! * x + m[6]! * y + m[10]! * z, 1e-20);\n}\n\nfunction requireCpuGeometry(mesh: Mesh): GeometryBuffers {\n if (!mesh._cpuPositions) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU positions. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n if (!mesh._cpuIndices) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU indices. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n if (!mesh._cpuNormals) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") requires CPU normals. Use a Babylon Lite mesh factory or loader that retains CPU geometry.`);\n }\n return {\n positions: mesh._cpuPositions,\n normals: mesh._cpuNormals,\n indices: mesh._cpuIndices,\n uvs: mesh._cpuUvs,\n };\n}\n\n/**\n * Builds a {@link Csg2Solid} from a mesh's CPU geometry, baking its world transform.\n * @param mesh - Source mesh; must retain CPU positions, normals, and indices.\n * @param materialSlot - Material slot index (0 to 65535) tagged onto the solid's triangles.\n * @returns A CSG2 solid; call {@link disposeCsg2} when finished to free WASM memory.\n */\nexport function createCsg2FromMesh(mesh: Mesh, materialSlot = 0): Csg2Solid {\n const runtime = requireRuntime();\n if (materialSlot < 0 || materialSlot >= MATERIAL_ID_RESERVE_COUNT || !Number.isInteger(materialSlot)) {\n throw new Error(`createCsg2FromMesh(\"${mesh.name}\") materialSlot must be an integer from 0 to ${MATERIAL_ID_RESERVE_COUNT - 1}.`);\n }\n\n const geometry = requireCpuGeometry(mesh);\n const vertexCount = geometry.positions.length / 3;\n const numProp = 8;\n const vertProperties = new F32(vertexCount * numProp);\n const world = mesh.worldMatrix;\n const invWorld = mat4Invert(world);\n\n for (let i = 0; i < vertexCount; i++) {\n const p = i * 3;\n const uv = i * 2;\n const out = i * numProp;\n const [x, y, z] = transformPoint(world, geometry.positions[p]!, geometry.positions[p + 1]!, geometry.positions[p + 2]!);\n const [nx, ny, nz] = transformNormal(world, invWorld, geometry.normals[p]!, geometry.normals[p + 1]!, geometry.normals[p + 2]!);\n vertProperties[out] = x;\n vertProperties[out + 1] = y;\n vertProperties[out + 2] = z;\n vertProperties[out + 3] = nx;\n vertProperties[out + 4] = ny;\n vertProperties[out + 5] = nz;\n vertProperties[out + 6] = geometry.uvs?.[uv] ?? 0;\n vertProperties[out + 7] = geometry.uvs?.[uv + 1] ?? 0;\n }\n\n const triVerts = new U32(geometry.indices.length);\n for (let i = 0; i < geometry.indices.length; i += 3) {\n triVerts[i] = geometry.indices[i + 2]!;\n triVerts[i + 1] = geometry.indices[i + 1]!;\n triVerts[i + 2] = geometry.indices[i]!;\n }\n\n const manifoldMesh = new runtime.Mesh({\n numProp,\n vertProperties,\n triVerts,\n runIndex: new U32([0]),\n runOriginalID: new U32([runtime.firstMaterialId + materialSlot]),\n });\n manifoldMesh.merge();\n\n try {\n // manifold-3d's `setup()` replaces `Manifold` with a factory function,\n // `function (mesh) { const m = new ManifoldCtor(mesh); …; return m; }`, that has no\n // `this` reference. A downstream esbuild/terser minifier (the dist build, or any\n // consumer bundling `build/lib`) rewrites such a function expression into an arrow\n // function, which is NOT constructable — so `new runtime.Manifold(mesh)` throws\n // \"Manifold is not a constructor\". The wrapper returns the solid whether invoked with\n // or without `new`, so call it as a plain factory to stay robust under minification.\n const manifoldFactory = runtime.Manifold as unknown as (mesh: ManifoldMesh) => Manifold;\n return solidFromManifold(manifoldFactory(manifoldMesh), numProp);\n } catch (err) {\n throw new Error(`Error while creating CSG2 from mesh \"${mesh.name}\".`, { cause: err });\n }\n}\n\nfunction runBooleanOperation(operation: \"difference\" | \"intersection\" | \"union\", a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n const runtime = requireRuntime();\n if (a._numProp !== b._numProp) {\n throw new Error(\"CSG2 operations require solids with the same vertex property layout.\");\n }\n return solidFromManifold(runtime.Manifold[operation](requireSolidManifold(a, `csg2 ${operation}`), requireSolidManifold(b, `csg2 ${operation}`)), a._numProp);\n}\n\n/** Returns the boolean difference (`a` − `b`) of two solids as a new solid. */\nexport function csg2Subtract(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"difference\", a, b);\n}\n\n/** Returns the boolean intersection (`a` ∩ `b`) of two solids as a new solid. */\nexport function csg2Intersect(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"intersection\", a, b);\n}\n\n/** Returns the boolean union (`a` ∪ `b`) of two solids as a new solid. */\nexport function csg2Add(a: Csg2Solid, b: Csg2Solid): Csg2Solid {\n return runBooleanOperation(\"union\", a, b);\n}\n\n/** Frees the WASM memory backing a solid. The solid must not be used afterwards. */\nexport function disposeCsg2(solid: Csg2Solid): void {\n if (solid._manifold) {\n solid._manifold.delete();\n solid._manifold = null;\n }\n}\n\nfunction materialSlotFromOriginalId(runtime: Csg2Runtime, originalId: number, name: string): number {\n const materialSlot = originalId - runtime.firstMaterialId;\n if (materialSlot < 0 || materialSlot >= MATERIAL_ID_RESERVE_COUNT) {\n throw new Error(`createMeshesFromCsg2(\"${name}\") received an unknown Manifold material original ID ${originalId}.`);\n }\n return materialSlot;\n}\n\nfunction appendTriangle(\n output: { positions: number[]; normals: number[]; uvs: number[]; indices: number[] },\n mesh: ManifoldMesh,\n triVerts: Uint32Array,\n numProp: number,\n triIndex: number\n): void {\n const base = output.positions.length / 3;\n for (let corner = 2; corner >= 0; corner--) {\n const vertexIndex = triVerts[triIndex + corner]!;\n const prop = vertexIndex * numProp;\n output.positions.push(mesh.vertProperties[prop]!, mesh.vertProperties[prop + 1]!, mesh.vertProperties[prop + 2]!);\n output.normals.push(mesh.vertProperties[prop + 3]!, mesh.vertProperties[prop + 4]!, mesh.vertProperties[prop + 5]!);\n output.uvs.push(mesh.vertProperties[prop + 6]!, mesh.vertProperties[prop + 7]!);\n output.indices.push(base + (2 - corner));\n }\n}\n\nfunction createMeshFromOutput(engine: EngineContext, name: string, output: { positions: number[]; normals: number[]; uvs: number[]; indices: number[] }): Mesh {\n if (output.positions.length === 0) {\n throw new Error(`Unable to build CSG2 mesh \"${name}\". Manifold has 0 vertices for this output.`);\n }\n return createMeshFromData(engine, name, new F32(output.positions), new F32(output.normals), new U32(output.indices), new F32(output.uvs));\n}\n\n/**\n * Triangulates a {@link Csg2Solid} into a single renderable mesh.\n * @param name - Name for the created mesh.\n */\nexport function createMeshFromCsg2(engine: EngineContext, solid: Csg2Solid, name = \"csg2\"): Mesh {\n requireRuntime();\n const mesh = requireSolidManifold(solid, `createMeshFromCsg2(\"${name}\")`).getMesh();\n const output = { positions: [] as number[], normals: [] as number[], uvs: [] as number[], indices: [] as number[] };\n for (let i = 0; i < mesh.triVerts.length; i += 3) {\n appendTriangle(output, mesh, mesh.triVerts, solid._numProp, i);\n }\n return createMeshFromOutput(engine, name, output);\n}\n\n/**\n * Triangulates a {@link Csg2Solid} into one mesh per material slot.\n * @param materials - Materials indexed by the material slots assigned during construction.\n * @param name - Base name; each sub-mesh is suffixed with its slot index.\n * @returns One mesh per distinct material slot, each assigned its corresponding material.\n */\nexport function createMeshesFromCsg2(engine: EngineContext, solid: Csg2Solid, materials: readonly Material[], name = \"csg2\"): Mesh[] {\n const runtime = requireRuntime();\n const mesh = requireSolidManifold(solid, `createMeshesFromCsg2(\"${name}\")`).getMesh();\n const outputs: Array<{ materialSlot: number; positions: number[]; normals: number[]; uvs: number[]; indices: number[] }> = [];\n\n for (let run = 0; run < mesh.numRun; run++) {\n const originalId = mesh.runOriginalID[run]!;\n const materialSlot = materialSlotFromOriginalId(runtime, originalId, name);\n let output = outputs.find((entry) => entry.materialSlot === materialSlot);\n if (!output) {\n output = { materialSlot, positions: [], normals: [], uvs: [], indices: [] };\n outputs.push(output);\n }\n\n const start = mesh.runIndex[run] ?? 0;\n const end = mesh.runIndex[run + 1] ?? mesh.triVerts.length;\n for (let i = start; i < end; i += 3) {\n appendTriangle(output, mesh, mesh.triVerts, solid._numProp, i);\n }\n }\n\n outputs.sort((a, b) => a.materialSlot - b.materialSlot);\n return outputs.map((output) => {\n const material = materials[output.materialSlot];\n if (!material) {\n throw new Error(`createMeshesFromCsg2(\"${name}\") missing material for CSG2 material slot ${output.materialSlot}.`);\n }\n const result = createMeshFromOutput(engine, `${name}_sub${output.materialSlot}`, output);\n result.material = material;\n return result;\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uploadMeshToGPU, initMeshTransform } from './mesh.js';
|
|
2
|
-
import {
|
|
2
|
+
import { computeAabb } from '../math/compute-aabb.js';
|
|
3
3
|
import { createSphereData } from './create-sphere.js';
|
|
4
4
|
import { createBoxData } from './create-box.js';
|
|
5
5
|
import { createTorusData } from './create-torus.js';
|
|
@@ -8,11 +8,12 @@ const PARAM_BYTES = 192;
|
|
|
8
8
|
const COUNT_U32_OFFSET = 44;
|
|
9
9
|
const MESH_WORLD_FLOAT_OFFSET = 24;
|
|
10
10
|
const LOCAL_SPHERE_FLOAT_OFFSET = 40;
|
|
11
|
+
const BOUNDS_PAD_F32_OFFSET = 45;
|
|
11
12
|
const INDIRECT_ARGS_BYTES = 20;
|
|
12
13
|
const CULL_WGSL_NO_COLOR = (
|
|
13
14
|
/* wgsl */
|
|
14
15
|
`
|
|
15
|
-
struct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32};
|
|
16
|
+
struct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32,boundsPad:f32};
|
|
16
17
|
@group(0)@binding(0)var<storage,read> srcMatrices:array<mat4x4<f32>>;
|
|
17
18
|
@group(0)@binding(1)var<storage,read_write> dstMatrices:array<mat4x4<f32>>;
|
|
18
19
|
@group(0)@binding(2)var<storage,read_write> args:array<atomic<u32>>;
|
|
@@ -22,7 +23,7 @@ let center=(world*vec4<f32>(params.localSphere.xyz,1.0)).xyz;
|
|
|
22
23
|
let sx=length(world[0].xyz);
|
|
23
24
|
let sy=length(world[1].xyz);
|
|
24
25
|
let sz=length(world[2].xyz);
|
|
25
|
-
let radius=params.localSphere.w*max(max(sx,sy),sz)+0.0001;
|
|
26
|
+
let radius=params.localSphere.w*max(max(sx,sy),sz)+params.boundsPad+0.0001;
|
|
26
27
|
for(var i=0u;i<6u;i++){
|
|
27
28
|
let p=params.planes[i];
|
|
28
29
|
if(dot(p.xyz,center)+p.w < -radius){return false;}
|
|
@@ -206,6 +207,7 @@ function writeCullParams(engine, state, mesh, indexCount, instanceCount, camera,
|
|
|
206
207
|
params.set(mesh.worldMatrix, MESH_WORLD_FLOAT_OFFSET);
|
|
207
208
|
params.set(state._localSphere, LOCAL_SPHERE_FLOAT_OFFSET);
|
|
208
209
|
state._paramsU32[COUNT_U32_OFFSET] = instanceCount;
|
|
210
|
+
params[BOUNDS_PAD_F32_OFFSET] = mesh.thinInstances?._cullBoundsPad ?? 0;
|
|
209
211
|
const args = state._argsData;
|
|
210
212
|
args[0] = indexCount;
|
|
211
213
|
args[1] = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thin-instance-gpu-culling.js","sources":["../../../src/mesh/thin-instance-gpu-culling.ts"],"sourcesContent":["/** GPU frustum culling for opt-in thin instances.\n *\n * Dynamically imported only when a scene enables thin-instance GPU culling.\n * Each render binding owns its own state so render tasks with different cameras\n * never clobber one another's compacted instance buffers or indirect args.\n */\n\nimport { F32, U32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Camera } from \"../camera/camera.js\";\nimport { getViewProjectionMatrix } from \"../camera/camera.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { DrawUpdateContext } from \"../render/renderable.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh, MeshGPU } from \"./mesh.js\";\nimport type { ThinInstanceData } from \"./thin-instance.js\";\nimport { syncThinInstanceGpuData } from \"./thin-instance-gpu.js\";\nimport type { ThinInstanceDrawBuffers } from \"./thin-instance-gpu.js\";\n\nconst WORKGROUP_SIZE = 64;\nconst PARAM_BYTES = 192;\nconst COUNT_U32_OFFSET = 44;\nconst MESH_WORLD_FLOAT_OFFSET = 24;\nconst LOCAL_SPHERE_FLOAT_OFFSET = 40;\nconst INDIRECT_ARGS_BYTES = 20;\n\nconst CULL_WGSL_NO_COLOR = /* wgsl */ `\nstruct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32};\n@group(0)@binding(0)var<storage,read> srcMatrices:array<mat4x4<f32>>;\n@group(0)@binding(1)var<storage,read_write> dstMatrices:array<mat4x4<f32>>;\n@group(0)@binding(2)var<storage,read_write> args:array<atomic<u32>>;\n@group(0)@binding(3)var<uniform> params:CullParams;\nfn visible(world:mat4x4<f32>)->bool{\nlet center=(world*vec4<f32>(params.localSphere.xyz,1.0)).xyz;\nlet sx=length(world[0].xyz);\nlet sy=length(world[1].xyz);\nlet sz=length(world[2].xyz);\nlet radius=params.localSphere.w*max(max(sx,sy),sz)+0.0001;\nfor(var i=0u;i<6u;i++){\nlet p=params.planes[i];\nif(dot(p.xyz,center)+p.w < -radius){return false;}\n}\nreturn true;\n}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\n}`;\n\nconst CULL_WGSL_COLOR = `${CULL_WGSL_NO_COLOR}\n@group(0)@binding(4)var<storage,read> srcColors:array<vec4<f32>>;\n@group(0)@binding(5)var<storage,read_write> dstColors:array<vec4<f32>>;\n@compute @workgroup_size(64)\nfn mainColor(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\ndstColors[outIndex]=srcColors[i];\n}`;\n\n/** Per-render-binding GPU culling state. */\nexport interface ThinInstanceGpuCullState {\n /** @internal */\n _capacity: number;\n /** @internal */\n _visibleMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _visibleColorBuffer: GPUBuffer | null;\n /** @internal */\n _argsBuffer: GPUBuffer | null;\n /** @internal */\n _paramsBuffer: GPUBuffer | null;\n /** @internal */\n _bindGroup: GPUBindGroup | null;\n /** @internal */\n _srcMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _srcColorBuffer: GPUBuffer | null;\n /** @internal */\n _hasColor: boolean;\n /** @internal */\n _localSphereReady: boolean;\n /** @internal */\n _localSphere: Float32Array;\n /** @internal */\n _paramsBytes: ArrayBuffer;\n /** @internal */\n _paramsF32: Float32Array;\n /** @internal */\n _paramsU32: Uint32Array;\n /** @internal */\n _argsData: Uint32Array;\n /** @internal */\n _drawBuffers: ThinInstanceDrawBuffers | null;\n}\n\n/** Result consumed by a material draw closure after culling has run for the active pass. */\nexport interface ThinInstanceGpuCullResult {\n readonly drawBuffers: ThinInstanceDrawBuffers;\n readonly argsBuffer: GPUBuffer;\n}\n\nlet _cachedDevice: GPUDevice | null = null;\nlet _pipelineNoColor: GPUComputePipeline | null = null;\nlet _pipelineColor: GPUComputePipeline | null = null;\n\n/** Create per-binding culling state. */\nexport function createTiCullState(): ThinInstanceGpuCullState {\n const paramsBytes = new ArrayBuffer(PARAM_BYTES);\n return {\n _capacity: 0,\n _visibleMatrixBuffer: null,\n _visibleColorBuffer: null,\n _argsBuffer: null,\n _paramsBuffer: null,\n _bindGroup: null,\n _srcMatrixBuffer: null,\n _srcColorBuffer: null,\n _hasColor: false,\n _localSphereReady: false,\n _localSphere: new F32(4),\n _paramsBytes: paramsBytes,\n _paramsF32: new F32(paramsBytes),\n _paramsU32: new U32(paramsBytes),\n _argsData: new U32(5),\n _drawBuffers: null,\n };\n}\n\n/** Destroy GPU resources owned by a per-binding cull state. */\nexport function destroyTiCullState(state: ThinInstanceGpuCullState): void {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._argsBuffer?.destroy();\n state._paramsBuffer?.destroy();\n state._visibleMatrixBuffer = null;\n state._visibleColorBuffer = null;\n state._argsBuffer = null;\n state._paramsBuffer = null;\n state._bindGroup = null;\n state._drawBuffers = null;\n}\n\n/** Run culling for one render binding and return buffers for the subsequent indirect draw. */\nexport function prepareTiCull(\n engine: EngineContext,\n state: ThinInstanceGpuCullState,\n mesh: Mesh,\n gpu: MeshGPU,\n ti: ThinInstanceData,\n hasColor: boolean,\n context: DrawUpdateContext\n): ThinInstanceGpuCullResult | null {\n const camera = context._camera;\n if (!ti._gpuCullingEnabled || !camera || mesh.visible === false || ti.count === 0) {\n state._drawBuffers = null;\n return null;\n }\n if (hasColor && !ti.colors) {\n state._drawBuffers = null;\n return null;\n }\n if (!state._localSphereReady && !computeLocalSphere(mesh as Mesh, state._localSphere)) {\n state._drawBuffers = null;\n return null;\n }\n state._localSphereReady = true;\n\n syncThinInstanceGpuData(engine, ti, hasColor);\n const sourceMatrixBuffer = ti._gpuBuffer;\n const sourceColorBuffer = hasColor ? ti._colorGpuBuffer : null;\n if (!sourceMatrixBuffer || (hasColor && !sourceColorBuffer)) {\n state._drawBuffers = null;\n return null;\n }\n\n ensureCullBuffers(engine, state, ti._capacity, hasColor);\n const visibleMatrixBuffer = state._visibleMatrixBuffer!;\n const visibleColorBuffer = hasColor ? state._visibleColorBuffer! : null;\n const argsBuffer = state._argsBuffer!;\n const paramsBuffer = state._paramsBuffer!;\n const pipeline = getCullPipeline(engine, hasColor);\n\n if (state._bindGroup === null || state._srcMatrixBuffer !== sourceMatrixBuffer || state._srcColorBuffer !== sourceColorBuffer || state._hasColor !== hasColor) {\n const entries: GPUBindGroupEntry[] = [\n { binding: 0, resource: { buffer: sourceMatrixBuffer } },\n { binding: 1, resource: { buffer: visibleMatrixBuffer } },\n { binding: 2, resource: { buffer: argsBuffer } },\n { binding: 3, resource: { buffer: paramsBuffer } },\n ];\n if (hasColor) {\n entries.push({ binding: 4, resource: { buffer: sourceColorBuffer! } }, { binding: 5, resource: { buffer: visibleColorBuffer! } });\n }\n state._bindGroup = engine._device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries });\n state._srcMatrixBuffer = sourceMatrixBuffer;\n state._srcColorBuffer = sourceColorBuffer;\n state._hasColor = hasColor;\n }\n\n const v = camera.viewport;\n const aspect = (context.targetWidth / context.targetHeight) * (v ? v.width / v.height : 1);\n writeCullParams(engine, state, mesh, gpu.indexCount, ti.count, camera, aspect);\n\n const pass = engine._currentEncoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, state._bindGroup);\n pass.dispatchWorkgroups(Math.ceil(ti.count / WORKGROUP_SIZE));\n pass.end();\n\n state._drawBuffers = { matrixBuffer: visibleMatrixBuffer, colorBuffer: visibleColorBuffer };\n return { drawBuffers: state._drawBuffers, argsBuffer };\n}\n\nfunction ensureCullBuffers(engine: EngineContext, state: ThinInstanceGpuCullState, capacity: number, hasColor: boolean): void {\n const device = engine._device;\n if (state._capacity < capacity) {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._visibleMatrixBuffer = device.createBuffer({\n size: Math.max(capacity * 64, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._visibleColorBuffer = hasColor\n ? device.createBuffer({\n size: Math.max(capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n })\n : null;\n state._capacity = capacity;\n state._bindGroup = null;\n state._drawBuffers = null;\n } else if (hasColor && !state._visibleColorBuffer) {\n state._visibleColorBuffer = device.createBuffer({\n size: Math.max(state._capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._bindGroup = null;\n state._drawBuffers = null;\n }\n if (!state._argsBuffer) {\n state._argsBuffer = device.createBuffer({\n size: INDIRECT_ARGS_BYTES,\n usage: BU.INDIRECT | BU.STORAGE | BU.COPY_DST,\n });\n }\n if (!state._paramsBuffer) {\n state._paramsBuffer = device.createBuffer({\n size: PARAM_BYTES,\n usage: BU.UNIFORM | BU.COPY_DST,\n });\n }\n}\n\nfunction getCullPipeline(engine: EngineContext, hasColor: boolean): GPUComputePipeline {\n const device = engine._device;\n if (_cachedDevice !== device) {\n _cachedDevice = device;\n _pipelineNoColor = null;\n _pipelineColor = null;\n }\n if (hasColor) {\n _pipelineColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_COLOR }), entryPoint: \"mainColor\" },\n });\n return _pipelineColor;\n }\n _pipelineNoColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_NO_COLOR }), entryPoint: \"main\" },\n });\n return _pipelineNoColor;\n}\n\nfunction writeCullParams(engine: EngineContext, state: ThinInstanceGpuCullState, mesh: Mesh, indexCount: number, instanceCount: number, camera: Camera, aspect: number): void {\n const params = state._paramsF32;\n const viewProjection = getViewProjectionMatrix(camera, aspect);\n writeFrustumPlanes(params, viewProjection);\n params.set(mesh.worldMatrix, MESH_WORLD_FLOAT_OFFSET);\n params.set(state._localSphere, LOCAL_SPHERE_FLOAT_OFFSET);\n state._paramsU32[COUNT_U32_OFFSET] = instanceCount;\n\n const args = state._argsData;\n args[0] = indexCount;\n args[1] = 0;\n args[2] = 0;\n args[3] = 0;\n args[4] = 0;\n\n engine._device.queue.writeBuffer(state._argsBuffer!, 0, args.buffer, args.byteOffset, args.byteLength);\n engine._device.queue.writeBuffer(state._paramsBuffer!, 0, state._paramsBytes);\n}\n\nfunction writeFrustumPlanes(out: Float32Array, m: Mat4): void {\n writePlane(out, 0, m[3]! + m[0]!, m[7]! + m[4]!, m[11]! + m[8]!, m[15]! + m[12]!);\n writePlane(out, 4, m[3]! - m[0]!, m[7]! - m[4]!, m[11]! - m[8]!, m[15]! - m[12]!);\n writePlane(out, 8, m[3]! + m[1]!, m[7]! + m[5]!, m[11]! + m[9]!, m[15]! + m[13]!);\n writePlane(out, 12, m[3]! - m[1]!, m[7]! - m[5]!, m[11]! - m[9]!, m[15]! - m[13]!);\n writePlane(out, 16, m[2]!, m[6]!, m[10]!, m[14]!);\n writePlane(out, 20, m[3]! - m[2]!, m[7]! - m[6]!, m[11]! - m[10]!, m[15]! - m[14]!);\n}\n\nfunction writePlane(out: Float32Array, offset: number, x: number, y: number, z: number, w: number): void {\n const invLen = 1 / Math.hypot(x, y, z);\n out[offset] = x * invLen;\n out[offset + 1] = y * invLen;\n out[offset + 2] = z * invLen;\n out[offset + 3] = w * invLen;\n}\n\nfunction computeLocalSphere(mesh: Mesh, out: Float32Array): boolean {\n const positions = mesh._cpuPositions;\n if (!positions || positions.length < 3) {\n return false;\n }\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i]!;\n const y = positions[i + 1]!;\n const z = positions[i + 2]!;\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n if (!isFinite(minX)) {\n return false;\n }\n const cx = (minX + maxX) * 0.5;\n const cy = (minY + maxY) * 0.5;\n const cz = (minZ + maxZ) * 0.5;\n const dx = maxX - cx;\n const dy = maxY - cy;\n const dz = maxZ - cz;\n out[0] = cx;\n out[1] = cy;\n out[2] = cz;\n out[3] = Math.hypot(dx, dy, dz);\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"thin-instance-gpu-culling.js","sources":["../../../src/mesh/thin-instance-gpu-culling.ts"],"sourcesContent":["/** GPU frustum culling for opt-in thin instances.\n *\n * Dynamically imported only when a scene enables thin-instance GPU culling.\n * Each render binding owns its own state so render tasks with different cameras\n * never clobber one another's compacted instance buffers or indirect args.\n */\n\nimport { F32, U32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Camera } from \"../camera/camera.js\";\nimport { getViewProjectionMatrix } from \"../camera/camera.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { DrawUpdateContext } from \"../render/renderable.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh, MeshGPU } from \"./mesh.js\";\nimport type { ThinInstanceData } from \"./thin-instance.js\";\nimport { syncThinInstanceGpuData } from \"./thin-instance-gpu.js\";\nimport type { ThinInstanceDrawBuffers } from \"./thin-instance-gpu.js\";\n\nconst WORKGROUP_SIZE = 64;\nconst PARAM_BYTES = 192;\nconst COUNT_U32_OFFSET = 44;\nconst MESH_WORLD_FLOAT_OFFSET = 24;\nconst LOCAL_SPHERE_FLOAT_OFFSET = 40;\nconst BOUNDS_PAD_F32_OFFSET = 45;\nconst INDIRECT_ARGS_BYTES = 20;\n\nconst CULL_WGSL_NO_COLOR = /* wgsl */ `\nstruct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32,boundsPad:f32};\n@group(0)@binding(0)var<storage,read> srcMatrices:array<mat4x4<f32>>;\n@group(0)@binding(1)var<storage,read_write> dstMatrices:array<mat4x4<f32>>;\n@group(0)@binding(2)var<storage,read_write> args:array<atomic<u32>>;\n@group(0)@binding(3)var<uniform> params:CullParams;\nfn visible(world:mat4x4<f32>)->bool{\nlet center=(world*vec4<f32>(params.localSphere.xyz,1.0)).xyz;\nlet sx=length(world[0].xyz);\nlet sy=length(world[1].xyz);\nlet sz=length(world[2].xyz);\nlet radius=params.localSphere.w*max(max(sx,sy),sz)+params.boundsPad+0.0001;\nfor(var i=0u;i<6u;i++){\nlet p=params.planes[i];\nif(dot(p.xyz,center)+p.w < -radius){return false;}\n}\nreturn true;\n}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\n}`;\n\nconst CULL_WGSL_COLOR = `${CULL_WGSL_NO_COLOR}\n@group(0)@binding(4)var<storage,read> srcColors:array<vec4<f32>>;\n@group(0)@binding(5)var<storage,read_write> dstColors:array<vec4<f32>>;\n@compute @workgroup_size(64)\nfn mainColor(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\ndstColors[outIndex]=srcColors[i];\n}`;\n\n/** Per-render-binding GPU culling state. */\nexport interface ThinInstanceGpuCullState {\n /** @internal */\n _capacity: number;\n /** @internal */\n _visibleMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _visibleColorBuffer: GPUBuffer | null;\n /** @internal */\n _argsBuffer: GPUBuffer | null;\n /** @internal */\n _paramsBuffer: GPUBuffer | null;\n /** @internal */\n _bindGroup: GPUBindGroup | null;\n /** @internal */\n _srcMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _srcColorBuffer: GPUBuffer | null;\n /** @internal */\n _hasColor: boolean;\n /** @internal */\n _localSphereReady: boolean;\n /** @internal */\n _localSphere: Float32Array;\n /** @internal */\n _paramsBytes: ArrayBuffer;\n /** @internal */\n _paramsF32: Float32Array;\n /** @internal */\n _paramsU32: Uint32Array;\n /** @internal */\n _argsData: Uint32Array;\n /** @internal */\n _drawBuffers: ThinInstanceDrawBuffers | null;\n}\n\n/** Result consumed by a material draw closure after culling has run for the active pass. */\nexport interface ThinInstanceGpuCullResult {\n readonly drawBuffers: ThinInstanceDrawBuffers;\n readonly argsBuffer: GPUBuffer;\n}\n\nlet _cachedDevice: GPUDevice | null = null;\nlet _pipelineNoColor: GPUComputePipeline | null = null;\nlet _pipelineColor: GPUComputePipeline | null = null;\n\n/** Create per-binding culling state. */\nexport function createTiCullState(): ThinInstanceGpuCullState {\n const paramsBytes = new ArrayBuffer(PARAM_BYTES);\n return {\n _capacity: 0,\n _visibleMatrixBuffer: null,\n _visibleColorBuffer: null,\n _argsBuffer: null,\n _paramsBuffer: null,\n _bindGroup: null,\n _srcMatrixBuffer: null,\n _srcColorBuffer: null,\n _hasColor: false,\n _localSphereReady: false,\n _localSphere: new F32(4),\n _paramsBytes: paramsBytes,\n _paramsF32: new F32(paramsBytes),\n _paramsU32: new U32(paramsBytes),\n _argsData: new U32(5),\n _drawBuffers: null,\n };\n}\n\n/** Destroy GPU resources owned by a per-binding cull state. */\nexport function destroyTiCullState(state: ThinInstanceGpuCullState): void {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._argsBuffer?.destroy();\n state._paramsBuffer?.destroy();\n state._visibleMatrixBuffer = null;\n state._visibleColorBuffer = null;\n state._argsBuffer = null;\n state._paramsBuffer = null;\n state._bindGroup = null;\n state._drawBuffers = null;\n}\n\n/** Run culling for one render binding and return buffers for the subsequent indirect draw. */\nexport function prepareTiCull(\n engine: EngineContext,\n state: ThinInstanceGpuCullState,\n mesh: Mesh,\n gpu: MeshGPU,\n ti: ThinInstanceData,\n hasColor: boolean,\n context: DrawUpdateContext\n): ThinInstanceGpuCullResult | null {\n const camera = context._camera;\n if (!ti._gpuCullingEnabled || !camera || mesh.visible === false || ti.count === 0) {\n state._drawBuffers = null;\n return null;\n }\n if (hasColor && !ti.colors) {\n state._drawBuffers = null;\n return null;\n }\n if (!state._localSphereReady && !computeLocalSphere(mesh as Mesh, state._localSphere)) {\n state._drawBuffers = null;\n return null;\n }\n state._localSphereReady = true;\n\n syncThinInstanceGpuData(engine, ti, hasColor);\n const sourceMatrixBuffer = ti._gpuBuffer;\n const sourceColorBuffer = hasColor ? ti._colorGpuBuffer : null;\n if (!sourceMatrixBuffer || (hasColor && !sourceColorBuffer)) {\n state._drawBuffers = null;\n return null;\n }\n\n ensureCullBuffers(engine, state, ti._capacity, hasColor);\n const visibleMatrixBuffer = state._visibleMatrixBuffer!;\n const visibleColorBuffer = hasColor ? state._visibleColorBuffer! : null;\n const argsBuffer = state._argsBuffer!;\n const paramsBuffer = state._paramsBuffer!;\n const pipeline = getCullPipeline(engine, hasColor);\n\n if (state._bindGroup === null || state._srcMatrixBuffer !== sourceMatrixBuffer || state._srcColorBuffer !== sourceColorBuffer || state._hasColor !== hasColor) {\n const entries: GPUBindGroupEntry[] = [\n { binding: 0, resource: { buffer: sourceMatrixBuffer } },\n { binding: 1, resource: { buffer: visibleMatrixBuffer } },\n { binding: 2, resource: { buffer: argsBuffer } },\n { binding: 3, resource: { buffer: paramsBuffer } },\n ];\n if (hasColor) {\n entries.push({ binding: 4, resource: { buffer: sourceColorBuffer! } }, { binding: 5, resource: { buffer: visibleColorBuffer! } });\n }\n state._bindGroup = engine._device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries });\n state._srcMatrixBuffer = sourceMatrixBuffer;\n state._srcColorBuffer = sourceColorBuffer;\n state._hasColor = hasColor;\n }\n\n const v = camera.viewport;\n const aspect = (context.targetWidth / context.targetHeight) * (v ? v.width / v.height : 1);\n writeCullParams(engine, state, mesh, gpu.indexCount, ti.count, camera, aspect);\n\n const pass = engine._currentEncoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, state._bindGroup);\n pass.dispatchWorkgroups(Math.ceil(ti.count / WORKGROUP_SIZE));\n pass.end();\n\n state._drawBuffers = { matrixBuffer: visibleMatrixBuffer, colorBuffer: visibleColorBuffer };\n return { drawBuffers: state._drawBuffers, argsBuffer };\n}\n\nfunction ensureCullBuffers(engine: EngineContext, state: ThinInstanceGpuCullState, capacity: number, hasColor: boolean): void {\n const device = engine._device;\n if (state._capacity < capacity) {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._visibleMatrixBuffer = device.createBuffer({\n size: Math.max(capacity * 64, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._visibleColorBuffer = hasColor\n ? device.createBuffer({\n size: Math.max(capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n })\n : null;\n state._capacity = capacity;\n state._bindGroup = null;\n state._drawBuffers = null;\n } else if (hasColor && !state._visibleColorBuffer) {\n state._visibleColorBuffer = device.createBuffer({\n size: Math.max(state._capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._bindGroup = null;\n state._drawBuffers = null;\n }\n if (!state._argsBuffer) {\n state._argsBuffer = device.createBuffer({\n size: INDIRECT_ARGS_BYTES,\n usage: BU.INDIRECT | BU.STORAGE | BU.COPY_DST,\n });\n }\n if (!state._paramsBuffer) {\n state._paramsBuffer = device.createBuffer({\n size: PARAM_BYTES,\n usage: BU.UNIFORM | BU.COPY_DST,\n });\n }\n}\n\nfunction getCullPipeline(engine: EngineContext, hasColor: boolean): GPUComputePipeline {\n const device = engine._device;\n if (_cachedDevice !== device) {\n _cachedDevice = device;\n _pipelineNoColor = null;\n _pipelineColor = null;\n }\n if (hasColor) {\n _pipelineColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_COLOR }), entryPoint: \"mainColor\" },\n });\n return _pipelineColor;\n }\n _pipelineNoColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_NO_COLOR }), entryPoint: \"main\" },\n });\n return _pipelineNoColor;\n}\n\nfunction writeCullParams(engine: EngineContext, state: ThinInstanceGpuCullState, mesh: Mesh, indexCount: number, instanceCount: number, camera: Camera, aspect: number): void {\n const params = state._paramsF32;\n const viewProjection = getViewProjectionMatrix(camera, aspect);\n writeFrustumPlanes(params, viewProjection);\n params.set(mesh.worldMatrix, MESH_WORLD_FLOAT_OFFSET);\n params.set(state._localSphere, LOCAL_SPHERE_FLOAT_OFFSET);\n state._paramsU32[COUNT_U32_OFFSET] = instanceCount;\n params[BOUNDS_PAD_F32_OFFSET] = mesh.thinInstances?._cullBoundsPad ?? 0;\n\n const args = state._argsData;\n args[0] = indexCount;\n args[1] = 0;\n args[2] = 0;\n args[3] = 0;\n args[4] = 0;\n\n engine._device.queue.writeBuffer(state._argsBuffer!, 0, args.buffer, args.byteOffset, args.byteLength);\n engine._device.queue.writeBuffer(state._paramsBuffer!, 0, state._paramsBytes);\n}\n\nfunction writeFrustumPlanes(out: Float32Array, m: Mat4): void {\n writePlane(out, 0, m[3]! + m[0]!, m[7]! + m[4]!, m[11]! + m[8]!, m[15]! + m[12]!);\n writePlane(out, 4, m[3]! - m[0]!, m[7]! - m[4]!, m[11]! - m[8]!, m[15]! - m[12]!);\n writePlane(out, 8, m[3]! + m[1]!, m[7]! + m[5]!, m[11]! + m[9]!, m[15]! + m[13]!);\n writePlane(out, 12, m[3]! - m[1]!, m[7]! - m[5]!, m[11]! - m[9]!, m[15]! - m[13]!);\n writePlane(out, 16, m[2]!, m[6]!, m[10]!, m[14]!);\n writePlane(out, 20, m[3]! - m[2]!, m[7]! - m[6]!, m[11]! - m[10]!, m[15]! - m[14]!);\n}\n\nfunction writePlane(out: Float32Array, offset: number, x: number, y: number, z: number, w: number): void {\n const invLen = 1 / Math.hypot(x, y, z);\n out[offset] = x * invLen;\n out[offset + 1] = y * invLen;\n out[offset + 2] = z * invLen;\n out[offset + 3] = w * invLen;\n}\n\nfunction computeLocalSphere(mesh: Mesh, out: Float32Array): boolean {\n const positions = mesh._cpuPositions;\n if (!positions || positions.length < 3) {\n return false;\n }\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i]!;\n const y = positions[i + 1]!;\n const z = positions[i + 2]!;\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n if (!isFinite(minX)) {\n return false;\n }\n const cx = (minX + maxX) * 0.5;\n const cy = (minY + maxY) * 0.5;\n const cz = (minZ + maxZ) * 0.5;\n const dx = maxX - cx;\n const dy = maxY - cy;\n const dz = maxZ - cz;\n out[0] = cx;\n out[1] = cy;\n out[2] = cz;\n out[3] = Math.hypot(dx, dy, dz);\n return true;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -135,6 +135,13 @@ function enableThinInstanceGpuCulling(mesh, enabled = true) {
|
|
|
135
135
|
ti._gpuVersion = -1;
|
|
136
136
|
ti._colorGpuVersion = -1;
|
|
137
137
|
}
|
|
138
|
+
function setThinInstanceCullBoundsPad(mesh, pad) {
|
|
139
|
+
const ti = mesh.thinInstances;
|
|
140
|
+
if (!ti) {
|
|
141
|
+
throw new Error("setThinInstanceCullBoundsPad requires mesh.thinInstances");
|
|
142
|
+
}
|
|
143
|
+
ti._cullBoundsPad = pad;
|
|
144
|
+
}
|
|
138
145
|
|
|
139
|
-
export { addThinInstance, enableThinInstanceGpuCulling, flushThinInstances, removeThinInstance, setThinInstanceColor, setThinInstanceColors, setThinInstanceCount, setThinInstanceMatrix, setThinInstances };
|
|
146
|
+
export { addThinInstance, enableThinInstanceGpuCulling, flushThinInstances, removeThinInstance, setThinInstanceColor, setThinInstanceColors, setThinInstanceCount, setThinInstanceCullBoundsPad, setThinInstanceMatrix, setThinInstances };
|
|
140
147
|
//# sourceMappingURL=thin-instance.js.map
|