@babylonjs/lite 1.14.0 → 1.15.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 +18 -0
- package/dist/index.js +326 -326
- package/dist/index.js.map +1 -1
- package/index.d.ts +72 -6
- package/lib/camera/arc-rotate.js +2 -20
- package/lib/camera/arc-rotate.js.map +1 -1
- package/lib/camera/camera.js +21 -4
- package/lib/camera/camera.js.map +1 -1
- package/lib/camera/free-camera.js +2 -19
- package/lib/camera/free-camera.js.map +1 -1
- package/lib/camera/geospatial-camera.js +2 -19
- package/lib/camera/geospatial-camera.js.map +1 -1
- package/lib/camera/orthographic.js +70 -0
- package/lib/camera/orthographic.js.map +1 -0
- package/lib/engine/engine.js +1 -1
- package/lib/frame-graph/render-task.js +2 -2
- package/lib/frame-graph/render-task.js.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/light/clustered.js +19 -6
- package/lib/light/clustered.js.map +1 -1
- package/lib/material/shader/shader-renderable.js +2 -2
- package/lib/material/shader/shader-renderable.js.map +1 -1
- package/lib/material/standard/enable-standard-mesh-features.js.map +1 -1
- package/lib/math/index.js +1 -0
- package/lib/math/index.js.map +1 -1
- package/lib/math/mat4-look-at-world-lh.js +55 -0
- package/lib/math/mat4-look-at-world-lh.js.map +1 -0
- package/lib/math/mat4-ortho-lh-to-ref.js +22 -0
- package/lib/math/mat4-ortho-lh-to-ref.js.map +1 -0
- package/lib/math/mat4.js +1 -0
- package/lib/math/mat4.js.map +1 -1
- package/lib/navigation/index.js +1 -1
- package/lib/navigation/navigation.js +12 -1
- package/lib/navigation/navigation.js.map +1 -1
- package/lib/post-process/taa.js +2 -1
- package/lib/post-process/taa.js.map +1 -1
- package/lib/shadow/csm-shadow-task-hooks.js +13 -6
- package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
- package/lib/shadow/shadow-base.js +3 -2
- package/lib/shadow/shadow-base.js.map +1 -1
- package/lib/text/text-renderable.js +2 -2
- package/lib/text/text-renderable.js.map +1 -1
- package/package.json +3 -11
- package/material/standard/enable-standard-mesh-features.d.ts +0 -4
- package/material/standard/enable-standard-vertex-colors.d.ts +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clustered.js","sources":["../../../src/light/clustered.ts"],"sourcesContent":["import { F32, U32 } from \"../engine/typed-arrays.js\";\nimport { TU, SS } from \"../engine/gpu-flags.js\";\nimport { getProjectionMatrix, getViewMatrix, type Camera } from \"../camera/camera.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { SceneContext } from \"../scene/scene.js\";\nimport { createUniformBuffer } from \"../resource/gpu-buffers.js\";\nimport type { PbrExt } from \"../material/pbr/pbr-flags.js\";\nimport { _registerPbrExt } from \"../material/pbr/pbr-flags.js\";\nimport { CLUSTERED_LIGHT_BLOCK, CLUSTERED_LIGHT_STRUCTS } from \"../material/pbr/fragments/clustered-light-wgsl.js\";\n\nconst PBR2_HAS_CLUSTERED_LIGHTS = 1 << 17;\nconst MAX_DATA_TEXTURE_WIDTH = 8192;\nconst CLUSTER_BATCH_SIZE = 32;\nconst EMPTY_SLICE_FIRST = 0xffffffff;\n\n/**\n * A single point light stored inside a {@link ClusteredLightContainer}. Plain\n * data — created via {@link createClusteredPointLight} and mutated in place.\n */\nexport interface ClusteredPointLight {\n /** World-space position `[x, y, z]`. */\n position: [number, number, number];\n /** Diffuse colour `[r, g, b]` in linear space. */\n diffuse: [number, number, number];\n /** Falloff range in world units. */\n range: number;\n /** Light intensity multiplier. */\n intensity: number;\n}\n\n/**\n * Holds a large set of point lights that are binned into screen-space clusters\n * on the GPU, so PBR materials can shade hundreds of lights efficiently. Add it\n * to a scene with {@link addClusteredLightContainer}.\n */\nexport interface ClusteredLightContainer {\n /** Discriminant tag identifying this object as a clustered light container. */\n readonly kind: \"clusteredLightContainer\";\n /** The point lights managed by this container. */\n pointLights: ClusteredPointLight[];\n /** Number of cluster tiles across the screen horizontally. */\n horizontalTiles: number;\n /** Number of cluster tiles across the screen vertically. */\n verticalTiles: number;\n /** Number of depth slices used to bin lights along view-space Z. */\n zSlices: number;\n /** @internal */\n _version: number;\n}\n\n/** Options for {@link createClusteredPointLight}. */\nexport interface ClusteredPointLightOptions {\n /** World-space position `[x, y, z]`. */\n position: [number, number, number];\n /** Diffuse colour `[r, g, b]` in linear space. */\n diffuse: [number, number, number];\n /** Falloff range in world units. Default `1`. */\n range?: number;\n /** Light intensity multiplier. Default `1`. */\n intensity?: number;\n}\n\n/** Options for {@link createClusteredLightContainer}. */\nexport interface ClusteredLightContainerOptions {\n /** Number of cluster tiles across the screen horizontally. Default `64`. */\n horizontalTiles?: number;\n /** Number of cluster tiles across the screen vertically. Default `64`. */\n verticalTiles?: number;\n /** Number of depth slices used to bin lights along view-space Z. Default `16`. */\n zSlices?: number;\n}\n\nexport interface ClusteredLightGpuState {\n paramsBuffer: GPUBuffer;\n lightsView: GPUTextureView;\n cellsView: GPUTextureView;\n indicesView: GPUTextureView;\n refresh(camera: Camera | null | undefined, targetWidth: number, targetHeight: number): void;\n dispose(): void;\n}\n\n/**\n * Create an empty {@link ClusteredLightContainer}. Add point lights with\n * {@link createClusteredPointLight}, then register it on a scene via\n * {@link addClusteredLightContainer}.\n *\n * @param options - Optional cluster tiling overrides.\n * @returns A new, empty clustered light container.\n */\nexport function createClusteredLightContainer(options?: ClusteredLightContainerOptions): ClusteredLightContainer {\n return {\n kind: \"clusteredLightContainer\",\n pointLights: [],\n horizontalTiles: options?.horizontalTiles ?? 64,\n verticalTiles: options?.verticalTiles ?? 64,\n zSlices: options?.zSlices ?? 16,\n _version: 0,\n };\n}\n\n/**\n * Add a point light to a clustered light container.\n *\n * @param container - The container to add the light to.\n * @param options - The light's position, colour and (optional) range/intensity.\n * @returns The created light (also pushed onto `container.pointLights`); mutate\n * it in place and call {@link markClusteredLightContainerDirty} to animate it.\n */\nexport function createClusteredPointLight(container: ClusteredLightContainer, options: ClusteredPointLightOptions): ClusteredPointLight {\n const light: ClusteredPointLight = {\n position: options.position,\n diffuse: options.diffuse,\n range: options.range ?? 1,\n intensity: options.intensity ?? 1,\n };\n container.pointLights.push(light);\n container._version++;\n return light;\n}\n\n/** Force the container's GPU light state to re-upload next frame. Call after mutating a light's\n * position / range / intensity / diffuse in place (e.g. animated lights such as drifting fireflies),\n * since those edits don't bump the container version on their own. */\nexport function markClusteredLightContainerDirty(container: ClusteredLightContainer): void {\n container._version++;\n}\n\n/**\n * Register a clustered light container on a scene, building its GPU state and\n * wiring it into the PBR materials already present in the scene.\n *\n * @param scene - The scene to attach the container to.\n * @param container - The clustered light container to register.\n */\nexport function addClusteredLightContainer(scene: SceneContext, container: ClusteredLightContainer): void {\n const ctx = scene as SceneContext;\n ctx._clusteredLightContainer = container;\n _registerPbrExt(clusteredPbrExt);\n const state = buildClusteredLightGpuState(ctx.surface.engine, ctx, container);\n ctx._clusteredLightUpdater = (camera, targetWidth, targetHeight) => state.refresh(camera, targetWidth, targetHeight);\n ctx._disposables.push(() => state.dispose());\n for (const mesh of ctx.meshes) {\n if (mesh.material) {\n const mat = mesh.material as { _clusteredLightState?: ClusteredLightGpuState; _renderFeatures?: unknown };\n mat._clusteredLightState = state;\n mat._renderFeatures = undefined;\n }\n }\n}\n\nconst clusteredPbrExt: PbrExt = {\n id: \"clustered-lights\",\n phase: \"fragment\",\n detect(mat: unknown) {\n return (mat as { _clusteredLightState?: ClusteredLightGpuState })._clusteredLightState ? { f: 0, f2: PBR2_HAS_CLUSTERED_LIGHTS } : { f: 0, f2: 0 };\n },\n frag(ctx) {\n if ((ctx._features2 & PBR2_HAS_CLUSTERED_LIGHTS) === 0) {\n return null;\n }\n return {\n _id: \"clustered-lights\",\n _bindings: [\n { _name: \"clusteredLightParams\", _type: { _kind: \"uniform-buffer\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredLights\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\", _sampleType: \"unfilterable-float\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredCells\", _type: { _kind: \"texture\", _textureType: \"texture_2d<u32>\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredIndices\", _type: { _kind: \"texture\", _textureType: \"texture_2d<u32>\" }, _visibility: SS.FRAGMENT },\n ],\n _helperFunctions: CLUSTERED_LIGHT_STRUCTS,\n _fragmentSlots: { AD: CLUSTERED_LIGHT_BLOCK, BL: CLUSTERED_LIGHT_BLOCK },\n };\n },\n bind(ctx, entries, b) {\n const state = (ctx._material as { _clusteredLightState?: ClusteredLightGpuState })._clusteredLightState;\n if (!state) {\n return b;\n }\n entries.push({ binding: b++, resource: { buffer: state.paramsBuffer } });\n entries.push({ binding: b++, resource: state.lightsView });\n entries.push({ binding: b++, resource: state.cellsView });\n entries.push({ binding: b++, resource: state.indicesView });\n return b;\n },\n};\n\nexport function buildClusteredLightGpuState(engine: EngineContext, scene: SceneContext, container: ClusteredLightContainer): ClusteredLightGpuState {\n const camera = scene.camera;\n if (!camera) {\n throw new Error(\"buildClusteredLightGpuState: scene.camera is required\");\n }\n const width = Math.max(1, engine.canvas.width);\n const height = Math.max(1, engine.canvas.height);\n const tileCountX = Math.max(1, container.horizontalTiles | 0);\n const tileCountY = Math.max(1, container.verticalTiles | 0);\n const zSlices = Math.max(1, container.zSlices | 0);\n const maxDataTextureWidth = Math.max(1, Math.min(MAX_DATA_TEXTURE_WIDTH, engine._device.limits.maxTextureDimension2D));\n const batchCount = Math.max(1, Math.ceil(container.pointLights.length / CLUSTER_BATCH_SIZE));\n const lightTexels = Math.max(1, container.pointLights.length * 2);\n const maskTexels = Math.max(1, tileCountX * tileCountY * batchCount);\n const dataTextureWidth = Math.min(maxDataTextureWidth, Math.max(lightTexels, zSlices, maskTexels));\n const lightData = new F32(textureElementCount(lightTexels, 4, dataTextureWidth));\n const sliceData = new U32(textureElementCount(zSlices, 4, dataTextureWidth));\n const maskData = new U32(textureElementCount(maskTexels, 1, dataTextureWidth));\n const lightSnapshot = new F32(container.pointLights.length * 8);\n lightSnapshot.fill(Number.NaN);\n const activeLights: { light: ClusteredPointLight; depth: number }[] = [];\n const params = new ArrayBuffer(32);\n const paramsU = new U32(params);\n const paramsF = new F32(params);\n paramsU[0] = tileCountX;\n paramsU[1] = tileCountY;\n paramsU[2] = zSlices;\n paramsU[3] = container.pointLights.length;\n paramsF[4] = camera.nearPlane;\n paramsF[5] = camera.farPlane;\n paramsU[6] = dataTextureWidth;\n paramsU[7] = batchCount;\n\n const paramsBuffer = createUniformBuffer(engine, paramsF, \"clustered-light-params\");\n const lightsTexture = createDataTexture(engine, \"rgba32float\", lightTexels, \"clustered-light-data\", dataTextureWidth);\n const cellsTexture = createDataTexture(engine, \"rgba32uint\", zSlices, \"clustered-slice-data\", dataTextureWidth);\n const indicesTexture = createDataTexture(engine, \"r32uint\", maskTexels, \"clustered-tile-mask-data\", dataTextureWidth);\n let lastCamera: Camera | null | undefined;\n let lastCameraVersion = -1;\n let lastTargetWidth = 0;\n let lastTargetHeight = 0;\n let lastContainerVersion = -1;\n let lastLightCount = -1;\n const state: ClusteredLightGpuState = {\n paramsBuffer,\n lightsView: lightsTexture.createView(),\n cellsView: cellsTexture.createView(),\n indicesView: indicesTexture.createView(),\n refresh(activeCamera, targetWidth, targetHeight) {\n if (!activeCamera) {\n return;\n }\n const safeWidth = Math.max(1, targetWidth);\n const safeHeight = Math.max(1, targetHeight);\n if (\n activeCamera === lastCamera &&\n activeCamera.worldMatrixVersion === lastCameraVersion &&\n safeWidth === lastTargetWidth &&\n safeHeight === lastTargetHeight &&\n container._version === lastContainerVersion &&\n container.pointLights.length === lastLightCount\n ) {\n return;\n }\n if (container.pointLights.length * 2 > lightTexels || Math.ceil(container.pointLights.length / CLUSTER_BATCH_SIZE) > batchCount) {\n throw new Error(\"ClusteredLightContainer: light count cannot grow after GPU state creation.\");\n }\n let topologyDirty =\n activeCamera !== lastCamera ||\n activeCamera.worldMatrixVersion !== lastCameraVersion ||\n safeWidth !== lastTargetWidth ||\n safeHeight !== lastTargetHeight ||\n container.pointLights.length !== lastLightCount;\n let lightDataDirty = topologyDirty;\n if (container._version !== lastContainerVersion || container.pointLights.length !== lastLightCount) {\n for (let i = 0; i < container.pointLights.length; i++) {\n const light = container.pointLights[i]!;\n const off = i * 8;\n const wasActive = lightSnapshot[off + 3]! > 0 && lightSnapshot[off + 7]! > 0;\n const isActive = light.range > 0 && light.intensity > 0;\n if (\n lightSnapshot[off] !== light.position[0] ||\n lightSnapshot[off + 1] !== light.position[1] ||\n lightSnapshot[off + 2] !== light.position[2] ||\n lightSnapshot[off + 3] !== light.range ||\n wasActive !== isActive\n ) {\n topologyDirty = true;\n }\n if (\n lightSnapshot[off + 4] !== light.diffuse[0] ||\n lightSnapshot[off + 5] !== light.diffuse[1] ||\n lightSnapshot[off + 6] !== light.diffuse[2] ||\n lightSnapshot[off + 7] !== light.intensity\n ) {\n lightDataDirty = true;\n }\n lightSnapshot[off] = light.position[0];\n lightSnapshot[off + 1] = light.position[1];\n lightSnapshot[off + 2] = light.position[2];\n lightSnapshot[off + 3] = light.range;\n lightSnapshot[off + 4] = light.diffuse[0];\n lightSnapshot[off + 5] = light.diffuse[1];\n lightSnapshot[off + 6] = light.diffuse[2];\n lightSnapshot[off + 7] = light.intensity;\n }\n }\n if (!topologyDirty && !lightDataDirty) {\n lastContainerVersion = container._version;\n return;\n }\n\n if (topologyDirty) {\n lightDataDirty = true;\n sliceData.fill(0);\n activeLights.length = 0;\n const aspect = safeWidth / safeHeight;\n const view = getViewMatrix(activeCamera);\n const proj = getProjectionMatrix(activeCamera, aspect);\n const nearZ = activeCamera.nearPlane;\n const farZ = activeCamera.farPlane;\n const logFarNear = Math.log(farZ / nearZ);\n const sliceScale = zSlices / logFarNear;\n const sliceBias = -(zSlices * Math.log(nearZ)) / logFarNear;\n for (const light of container.pointLights) {\n if (light.range > 0 && light.intensity > 0) {\n activeLights.push({ light, depth: viewZ(light.position, view) });\n }\n }\n activeLights.sort((a, b) => a.depth - b.depth);\n const activeBatchCount = Math.max(1, Math.ceil(activeLights.length / CLUSTER_BATCH_SIZE));\n const activeMaskTexels = tileCountX * tileCountY * activeBatchCount;\n maskData.fill(0, 0, activeMaskTexels);\n for (let i = 0; i < zSlices; i++) {\n const off = i * 4;\n sliceData[off] = EMPTY_SLICE_FIRST;\n sliceData[off + 1] = 0;\n }\n for (let i = 0; i < activeLights.length; i++) {\n const { light, depth } = activeLights[i]!;\n addLightToClusters(sliceData, maskData, light, depth, i, view, proj, tileCountX, tileCountY, zSlices, sliceScale, sliceBias, activeBatchCount);\n }\n paramsU[0] = tileCountX;\n paramsU[1] = tileCountY;\n paramsU[2] = zSlices;\n paramsU[3] = activeLights.length;\n paramsF[4] = sliceScale;\n paramsF[5] = sliceBias;\n paramsU[7] = activeBatchCount;\n engine._device.queue.writeBuffer(paramsBuffer, 0, paramsF as Float32Array<ArrayBuffer>);\n writeDataTexture(engine, cellsTexture, sliceData, 4, zSlices, dataTextureWidth);\n if (activeLights.length > 0) {\n writeDataTexture(engine, indicesTexture, maskData, 1, activeMaskTexels, dataTextureWidth);\n }\n }\n if (lightDataDirty) {\n for (let i = 0; i < activeLights.length; i++) {\n const light = activeLights[i]!.light;\n const off = i * 8;\n lightData[off] = light.position[0];\n lightData[off + 1] = light.position[1];\n lightData[off + 2] = light.position[2];\n lightData[off + 3] = light.range;\n lightData[off + 4] = light.diffuse[0];\n lightData[off + 5] = light.diffuse[1];\n lightData[off + 6] = light.diffuse[2];\n lightData[off + 7] = light.intensity;\n }\n if (activeLights.length > 0) {\n writeDataTexture(engine, lightsTexture, lightData, 4, activeLights.length * 2, dataTextureWidth);\n }\n }\n lastCamera = activeCamera;\n lastCameraVersion = activeCamera.worldMatrixVersion;\n lastTargetWidth = safeWidth;\n lastTargetHeight = safeHeight;\n lastContainerVersion = container._version;\n lastLightCount = container.pointLights.length;\n },\n dispose() {\n paramsBuffer.destroy();\n lightsTexture.destroy();\n cellsTexture.destroy();\n indicesTexture.destroy();\n },\n };\n state.refresh(camera, width, height);\n return state;\n}\n\nfunction textureElementCount(texels: number, components: number, dataTextureWidth: number): number {\n return dataTextureWidth * Math.max(1, Math.ceil(texels / dataTextureWidth)) * components;\n}\n\nfunction createDataTexture(engine: EngineContext, format: GPUTextureFormat, texels: number, label: string, dataTextureWidth: number): GPUTexture {\n const height = Math.max(1, Math.ceil(texels / dataTextureWidth));\n const texture = engine._device.createTexture({\n label,\n size: { width: dataTextureWidth, height },\n format,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n return texture;\n}\n\nfunction writeDataTexture(engine: EngineContext, texture: GPUTexture, data: Float32Array | Uint32Array, components: number, texels: number, dataTextureWidth: number): void {\n const height = Math.max(1, Math.ceil(texels / dataTextureWidth));\n const width = height > 1 ? dataTextureWidth : Math.max(1, Math.min(texels, dataTextureWidth));\n engine._device.queue.writeTexture({ texture }, data.buffer, { bytesPerRow: width * components * 4, rowsPerImage: height }, { width, height });\n}\n\nfunction addLightToClusters(\n sliceData: Uint32Array,\n maskData: Uint32Array,\n light: ClusteredPointLight,\n viewDepth: number,\n lightIndex: number,\n view: ArrayLike<number>,\n proj: ArrayLike<number>,\n tileCountX: number,\n tileCountY: number,\n zSlices: number,\n sliceScale: number,\n sliceBias: number,\n batchCount: number\n): void {\n const vx = view[0]! * light.position[0] + view[4]! * light.position[1] + view[8]! * light.position[2] + view[12]!;\n const vy = view[1]! * light.position[0] + view[5]! * light.position[1] + view[9]! * light.position[2] + view[13]!;\n const vz = viewDepth;\n const range = Math.max(0, light.range);\n const firstSlice = getSliceIndex(vz - range, sliceScale, sliceBias);\n const lastSlice = getSliceIndex(vz + range, sliceScale, sliceBias);\n if (lastSlice < 0 || firstSlice >= zSlices) {\n return;\n }\n\n const bounds = projectedSphereBounds(vx, vy, vz, range, proj, tileCountX, tileCountY);\n const minX = bounds[0];\n const maxX = bounds[1];\n const minY = bounds[2];\n const maxY = bounds[3];\n const z0 = clampInt(firstSlice, 0, zSlices - 1);\n const z1 = clampInt(lastSlice, 0, zSlices - 1);\n for (let z = z0; z <= z1; z++) {\n const off = z * 4;\n sliceData[off] = Math.min(sliceData[off]!, lightIndex);\n sliceData[off + 1] = Math.max(sliceData[off + 1]!, lightIndex);\n }\n const batch = Math.floor(lightIndex / CLUSTER_BATCH_SIZE);\n const bit = 1 << (lightIndex % CLUSTER_BATCH_SIZE);\n for (let y = minY; y <= maxY; y++) {\n for (let x = minX; x <= maxX; x++) {\n const maskIndex = (x * tileCountY + y) * batchCount + batch;\n maskData[maskIndex] = maskData[maskIndex]! | bit;\n }\n }\n}\n\nfunction viewZ(position: readonly [number, number, number], view: ArrayLike<number>): number {\n return view[2]! * position[0] + view[6]! * position[1] + view[10]! * position[2] + view[14]!;\n}\n\nfunction getSliceIndex(depth: number, sliceScale: number, sliceBias: number): number {\n return depth > 0 ? Math.floor(Math.log(depth) * sliceScale + sliceBias) : -1;\n}\n\nfunction clampInt(v: number, min: number, max: number): number {\n return v < min ? min : v > max ? max : v;\n}\n\nfunction projectedSphereBounds(\n vx: number,\n vy: number,\n vz: number,\n range: number,\n proj: ArrayLike<number>,\n tileCountX: number,\n tileCountY: number\n): [number, number, number, number] {\n const rangeSq = range * range;\n let minNdcX = -1;\n let maxNdcX = 1;\n let minNdcY = -1;\n let maxNdcY = 1;\n if (vz > range) {\n const x0 = projectedSphereEdge(vx, vz, rangeSq, proj[0]!, -1);\n const x1 = projectedSphereEdge(vx, vz, rangeSq, proj[0]!, 1);\n minNdcX = Math.min(x0, x1);\n maxNdcX = Math.max(x0, x1);\n const y0 = projectedSphereEdge(vy, vz, rangeSq, proj[5]!, -1);\n const y1 = projectedSphereEdge(vy, vz, rangeSq, proj[5]!, 1);\n minNdcY = Math.min(y0, y1);\n maxNdcY = Math.max(y0, y1);\n }\n return [\n clampInt(Math.floor((minNdcX * 0.5 + 0.5) * tileCountX) - 1, 0, tileCountX - 1),\n clampInt(Math.floor((maxNdcX * 0.5 + 0.5) * tileCountX) + 1, 0, tileCountX - 1),\n clampInt(Math.floor((0.5 - maxNdcY * 0.5) * tileCountY) - 1, 0, tileCountY - 1),\n clampInt(Math.floor((0.5 - minNdcY * 0.5) * tileCountY) + 1, 0, tileCountY - 1),\n ];\n}\n\nfunction projectedSphereEdge(axis: number, depth: number, rangeSq: number, projectionScale: number, side: -1 | 1): number {\n const distSq = axis * axis + depth * depth;\n if (distSq <= rangeSq) {\n return side;\n }\n const sinSq = rangeSq / distSq;\n const cosSq = Math.max(1 - sinSq, 0.01);\n const sinCos = side * Math.sqrt(sinSq * cosSq);\n const rotatedAxis = cosSq * axis + sinCos * depth;\n const rotatedDepth = -sinCos * axis + cosSq * depth;\n return (projectionScale * rotatedAxis) / Math.max(rotatedDepth, 0.01);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clustered.js","sources":["../../../src/light/clustered.ts"],"sourcesContent":["import { F32, U32 } from \"../engine/typed-arrays.js\";\nimport { TU, SS } from \"../engine/gpu-flags.js\";\nimport { getProjectionMatrix, getViewMatrix, getEffectiveAspectRatio, _cameraChangeKey, type Camera } from \"../camera/camera.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { SceneContext } from \"../scene/scene.js\";\nimport { createUniformBuffer } from \"../resource/gpu-buffers.js\";\nimport type { PbrExt } from \"../material/pbr/pbr-flags.js\";\nimport { _registerPbrExt } from \"../material/pbr/pbr-flags.js\";\nimport { CLUSTERED_LIGHT_BLOCK, CLUSTERED_LIGHT_STRUCTS } from \"../material/pbr/fragments/clustered-light-wgsl.js\";\n\nconst PBR2_HAS_CLUSTERED_LIGHTS = 1 << 17;\nconst MAX_DATA_TEXTURE_WIDTH = 8192;\nconst CLUSTER_BATCH_SIZE = 32;\nconst EMPTY_SLICE_FIRST = 0xffffffff;\n\n/**\n * A single point light stored inside a {@link ClusteredLightContainer}. Plain\n * data — created via {@link createClusteredPointLight} and mutated in place.\n */\nexport interface ClusteredPointLight {\n /** World-space position `[x, y, z]`. */\n position: [number, number, number];\n /** Diffuse colour `[r, g, b]` in linear space. */\n diffuse: [number, number, number];\n /** Falloff range in world units. */\n range: number;\n /** Light intensity multiplier. */\n intensity: number;\n}\n\n/**\n * Holds a large set of point lights that are binned into screen-space clusters\n * on the GPU, so PBR materials can shade hundreds of lights efficiently. Add it\n * to a scene with {@link addClusteredLightContainer}.\n */\nexport interface ClusteredLightContainer {\n /** Discriminant tag identifying this object as a clustered light container. */\n readonly kind: \"clusteredLightContainer\";\n /** The point lights managed by this container. */\n pointLights: ClusteredPointLight[];\n /** Number of cluster tiles across the screen horizontally. */\n horizontalTiles: number;\n /** Number of cluster tiles across the screen vertically. */\n verticalTiles: number;\n /** Number of depth slices used to bin lights along view-space Z. */\n zSlices: number;\n /** @internal */\n _version: number;\n}\n\n/** Options for {@link createClusteredPointLight}. */\nexport interface ClusteredPointLightOptions {\n /** World-space position `[x, y, z]`. */\n position: [number, number, number];\n /** Diffuse colour `[r, g, b]` in linear space. */\n diffuse: [number, number, number];\n /** Falloff range in world units. Default `1`. */\n range?: number;\n /** Light intensity multiplier. Default `1`. */\n intensity?: number;\n}\n\n/** Options for {@link createClusteredLightContainer}. */\nexport interface ClusteredLightContainerOptions {\n /** Number of cluster tiles across the screen horizontally. Default `64`. */\n horizontalTiles?: number;\n /** Number of cluster tiles across the screen vertically. Default `64`. */\n verticalTiles?: number;\n /** Number of depth slices used to bin lights along view-space Z. Default `16`. */\n zSlices?: number;\n}\n\nexport interface ClusteredLightGpuState {\n paramsBuffer: GPUBuffer;\n lightsView: GPUTextureView;\n cellsView: GPUTextureView;\n indicesView: GPUTextureView;\n refresh(camera: Camera | null | undefined, targetWidth: number, targetHeight: number): void;\n dispose(): void;\n}\n\n/**\n * Create an empty {@link ClusteredLightContainer}. Add point lights with\n * {@link createClusteredPointLight}, then register it on a scene via\n * {@link addClusteredLightContainer}.\n *\n * @param options - Optional cluster tiling overrides.\n * @returns A new, empty clustered light container.\n */\nexport function createClusteredLightContainer(options?: ClusteredLightContainerOptions): ClusteredLightContainer {\n return {\n kind: \"clusteredLightContainer\",\n pointLights: [],\n horizontalTiles: options?.horizontalTiles ?? 64,\n verticalTiles: options?.verticalTiles ?? 64,\n zSlices: options?.zSlices ?? 16,\n _version: 0,\n };\n}\n\n/**\n * Add a point light to a clustered light container.\n *\n * @param container - The container to add the light to.\n * @param options - The light's position, colour and (optional) range/intensity.\n * @returns The created light (also pushed onto `container.pointLights`); mutate\n * it in place and call {@link markClusteredLightContainerDirty} to animate it.\n */\nexport function createClusteredPointLight(container: ClusteredLightContainer, options: ClusteredPointLightOptions): ClusteredPointLight {\n const light: ClusteredPointLight = {\n position: options.position,\n diffuse: options.diffuse,\n range: options.range ?? 1,\n intensity: options.intensity ?? 1,\n };\n container.pointLights.push(light);\n container._version++;\n return light;\n}\n\n/** Force the container's GPU light state to re-upload next frame. Call after mutating a light's\n * position / range / intensity / diffuse in place (e.g. animated lights such as drifting fireflies),\n * since those edits don't bump the container version on their own. */\nexport function markClusteredLightContainerDirty(container: ClusteredLightContainer): void {\n container._version++;\n}\n\n/**\n * Register a clustered light container on a scene, building its GPU state and\n * wiring it into the PBR materials already present in the scene.\n *\n * @param scene - The scene to attach the container to.\n * @param container - The clustered light container to register.\n */\nexport function addClusteredLightContainer(scene: SceneContext, container: ClusteredLightContainer): void {\n const ctx = scene as SceneContext;\n ctx._clusteredLightContainer = container;\n _registerPbrExt(clusteredPbrExt);\n const state = buildClusteredLightGpuState(ctx.surface.engine, ctx, container);\n ctx._clusteredLightUpdater = (camera, targetWidth, targetHeight) => state.refresh(camera, targetWidth, targetHeight);\n ctx._disposables.push(() => state.dispose());\n for (const mesh of ctx.meshes) {\n if (mesh.material) {\n const mat = mesh.material as { _clusteredLightState?: ClusteredLightGpuState; _renderFeatures?: unknown };\n mat._clusteredLightState = state;\n mat._renderFeatures = undefined;\n }\n }\n}\n\nconst clusteredPbrExt: PbrExt = {\n id: \"clustered-lights\",\n phase: \"fragment\",\n detect(mat: unknown) {\n return (mat as { _clusteredLightState?: ClusteredLightGpuState })._clusteredLightState ? { f: 0, f2: PBR2_HAS_CLUSTERED_LIGHTS } : { f: 0, f2: 0 };\n },\n frag(ctx) {\n if ((ctx._features2 & PBR2_HAS_CLUSTERED_LIGHTS) === 0) {\n return null;\n }\n return {\n _id: \"clustered-lights\",\n _bindings: [\n { _name: \"clusteredLightParams\", _type: { _kind: \"uniform-buffer\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredLights\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\", _sampleType: \"unfilterable-float\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredCells\", _type: { _kind: \"texture\", _textureType: \"texture_2d<u32>\" }, _visibility: SS.FRAGMENT },\n { _name: \"clusteredIndices\", _type: { _kind: \"texture\", _textureType: \"texture_2d<u32>\" }, _visibility: SS.FRAGMENT },\n ],\n _helperFunctions: CLUSTERED_LIGHT_STRUCTS,\n _fragmentSlots: { AD: CLUSTERED_LIGHT_BLOCK, BL: CLUSTERED_LIGHT_BLOCK },\n };\n },\n bind(ctx, entries, b) {\n const state = (ctx._material as { _clusteredLightState?: ClusteredLightGpuState })._clusteredLightState;\n if (!state) {\n return b;\n }\n entries.push({ binding: b++, resource: { buffer: state.paramsBuffer } });\n entries.push({ binding: b++, resource: state.lightsView });\n entries.push({ binding: b++, resource: state.cellsView });\n entries.push({ binding: b++, resource: state.indicesView });\n return b;\n },\n};\n\nexport function buildClusteredLightGpuState(engine: EngineContext, scene: SceneContext, container: ClusteredLightContainer): ClusteredLightGpuState {\n const camera = scene.camera;\n if (!camera) {\n throw new Error(\"buildClusteredLightGpuState: scene.camera is required\");\n }\n const width = Math.max(1, engine.canvas.width);\n const height = Math.max(1, engine.canvas.height);\n const tileCountX = Math.max(1, container.horizontalTiles | 0);\n const tileCountY = Math.max(1, container.verticalTiles | 0);\n const zSlices = Math.max(1, container.zSlices | 0);\n const maxDataTextureWidth = Math.max(1, Math.min(MAX_DATA_TEXTURE_WIDTH, engine._device.limits.maxTextureDimension2D));\n const batchCount = Math.max(1, Math.ceil(container.pointLights.length / CLUSTER_BATCH_SIZE));\n const lightTexels = Math.max(1, container.pointLights.length * 2);\n const maskTexels = Math.max(1, tileCountX * tileCountY * batchCount);\n const dataTextureWidth = Math.min(maxDataTextureWidth, Math.max(lightTexels, zSlices, maskTexels));\n const lightData = new F32(textureElementCount(lightTexels, 4, dataTextureWidth));\n const sliceData = new U32(textureElementCount(zSlices, 4, dataTextureWidth));\n const maskData = new U32(textureElementCount(maskTexels, 1, dataTextureWidth));\n const lightSnapshot = new F32(container.pointLights.length * 8);\n lightSnapshot.fill(Number.NaN);\n const activeLights: { light: ClusteredPointLight; depth: number }[] = [];\n const params = new ArrayBuffer(32);\n const paramsU = new U32(params);\n const paramsF = new F32(params);\n paramsU[0] = tileCountX;\n paramsU[1] = tileCountY;\n paramsU[2] = zSlices;\n paramsU[3] = container.pointLights.length;\n paramsF[4] = camera.nearPlane;\n paramsF[5] = camera.farPlane;\n paramsU[6] = dataTextureWidth;\n paramsU[7] = batchCount;\n\n const paramsBuffer = createUniformBuffer(engine, paramsF, \"clustered-light-params\");\n const lightsTexture = createDataTexture(engine, \"rgba32float\", lightTexels, \"clustered-light-data\", dataTextureWidth);\n const cellsTexture = createDataTexture(engine, \"rgba32uint\", zSlices, \"clustered-slice-data\", dataTextureWidth);\n const indicesTexture = createDataTexture(engine, \"r32uint\", maskTexels, \"clustered-tile-mask-data\", dataTextureWidth);\n let lastCamera: Camera | null | undefined;\n let lastCameraVersion = -1;\n let lastTargetWidth = 0;\n let lastTargetHeight = 0;\n let lastAspect = -1;\n let lastContainerVersion = -1;\n let lastLightCount = -1;\n const state: ClusteredLightGpuState = {\n paramsBuffer,\n lightsView: lightsTexture.createView(),\n cellsView: cellsTexture.createView(),\n indicesView: indicesTexture.createView(),\n refresh(activeCamera, targetWidth, targetHeight) {\n if (!activeCamera) {\n return;\n }\n const safeWidth = Math.max(1, targetWidth);\n const safeHeight = Math.max(1, targetHeight);\n // Effective aspect, not the raw target ratio: a camera with a normalized viewport\n // renders through a different projection than width/height implies, and the forward\n // pass already folds the viewport in (`_writePassSceneUBO`). Binning lights from a\n // projection the frame never uses puts them in the wrong tiles. It is also part of\n // the dirty key below, since a viewport change moves it with everything else equal.\n const aspect = getEffectiveAspectRatio(activeCamera, safeWidth, safeHeight);\n if (\n activeCamera === lastCamera &&\n _cameraChangeKey(activeCamera) === lastCameraVersion &&\n safeWidth === lastTargetWidth &&\n safeHeight === lastTargetHeight &&\n aspect === lastAspect &&\n container._version === lastContainerVersion &&\n container.pointLights.length === lastLightCount\n ) {\n return;\n }\n if (container.pointLights.length * 2 > lightTexels || Math.ceil(container.pointLights.length / CLUSTER_BATCH_SIZE) > batchCount) {\n throw new Error(\"ClusteredLightContainer: light count cannot grow after GPU state creation.\");\n }\n let topologyDirty =\n activeCamera !== lastCamera ||\n _cameraChangeKey(activeCamera) !== lastCameraVersion ||\n safeWidth !== lastTargetWidth ||\n safeHeight !== lastTargetHeight ||\n aspect !== lastAspect ||\n container.pointLights.length !== lastLightCount;\n let lightDataDirty = topologyDirty;\n if (container._version !== lastContainerVersion || container.pointLights.length !== lastLightCount) {\n for (let i = 0; i < container.pointLights.length; i++) {\n const light = container.pointLights[i]!;\n const off = i * 8;\n const wasActive = lightSnapshot[off + 3]! > 0 && lightSnapshot[off + 7]! > 0;\n const isActive = light.range > 0 && light.intensity > 0;\n if (\n lightSnapshot[off] !== light.position[0] ||\n lightSnapshot[off + 1] !== light.position[1] ||\n lightSnapshot[off + 2] !== light.position[2] ||\n lightSnapshot[off + 3] !== light.range ||\n wasActive !== isActive\n ) {\n topologyDirty = true;\n }\n if (\n lightSnapshot[off + 4] !== light.diffuse[0] ||\n lightSnapshot[off + 5] !== light.diffuse[1] ||\n lightSnapshot[off + 6] !== light.diffuse[2] ||\n lightSnapshot[off + 7] !== light.intensity\n ) {\n lightDataDirty = true;\n }\n lightSnapshot[off] = light.position[0];\n lightSnapshot[off + 1] = light.position[1];\n lightSnapshot[off + 2] = light.position[2];\n lightSnapshot[off + 3] = light.range;\n lightSnapshot[off + 4] = light.diffuse[0];\n lightSnapshot[off + 5] = light.diffuse[1];\n lightSnapshot[off + 6] = light.diffuse[2];\n lightSnapshot[off + 7] = light.intensity;\n }\n }\n if (!topologyDirty && !lightDataDirty) {\n lastContainerVersion = container._version;\n return;\n }\n\n if (topologyDirty) {\n lightDataDirty = true;\n sliceData.fill(0);\n activeLights.length = 0;\n const view = getViewMatrix(activeCamera);\n const proj = getProjectionMatrix(activeCamera, aspect);\n const nearZ = activeCamera.nearPlane;\n const farZ = activeCamera.farPlane;\n const logFarNear = Math.log(farZ / nearZ);\n const sliceScale = zSlices / logFarNear;\n const sliceBias = -(zSlices * Math.log(nearZ)) / logFarNear;\n for (const light of container.pointLights) {\n if (light.range > 0 && light.intensity > 0) {\n activeLights.push({ light, depth: viewZ(light.position, view) });\n }\n }\n activeLights.sort((a, b) => a.depth - b.depth);\n const activeBatchCount = Math.max(1, Math.ceil(activeLights.length / CLUSTER_BATCH_SIZE));\n const activeMaskTexels = tileCountX * tileCountY * activeBatchCount;\n maskData.fill(0, 0, activeMaskTexels);\n for (let i = 0; i < zSlices; i++) {\n const off = i * 4;\n sliceData[off] = EMPTY_SLICE_FIRST;\n sliceData[off + 1] = 0;\n }\n for (let i = 0; i < activeLights.length; i++) {\n const { light, depth } = activeLights[i]!;\n addLightToClusters(sliceData, maskData, light, depth, i, view, proj, tileCountX, tileCountY, zSlices, sliceScale, sliceBias, activeBatchCount);\n }\n paramsU[0] = tileCountX;\n paramsU[1] = tileCountY;\n paramsU[2] = zSlices;\n paramsU[3] = activeLights.length;\n paramsF[4] = sliceScale;\n paramsF[5] = sliceBias;\n paramsU[7] = activeBatchCount;\n engine._device.queue.writeBuffer(paramsBuffer, 0, paramsF as Float32Array<ArrayBuffer>);\n writeDataTexture(engine, cellsTexture, sliceData, 4, zSlices, dataTextureWidth);\n if (activeLights.length > 0) {\n writeDataTexture(engine, indicesTexture, maskData, 1, activeMaskTexels, dataTextureWidth);\n }\n }\n if (lightDataDirty) {\n for (let i = 0; i < activeLights.length; i++) {\n const light = activeLights[i]!.light;\n const off = i * 8;\n lightData[off] = light.position[0];\n lightData[off + 1] = light.position[1];\n lightData[off + 2] = light.position[2];\n lightData[off + 3] = light.range;\n lightData[off + 4] = light.diffuse[0];\n lightData[off + 5] = light.diffuse[1];\n lightData[off + 6] = light.diffuse[2];\n lightData[off + 7] = light.intensity;\n }\n if (activeLights.length > 0) {\n writeDataTexture(engine, lightsTexture, lightData, 4, activeLights.length * 2, dataTextureWidth);\n }\n }\n lastCamera = activeCamera;\n lastCameraVersion = _cameraChangeKey(activeCamera);\n lastTargetWidth = safeWidth;\n lastTargetHeight = safeHeight;\n lastAspect = aspect;\n lastContainerVersion = container._version;\n lastLightCount = container.pointLights.length;\n },\n dispose() {\n paramsBuffer.destroy();\n lightsTexture.destroy();\n cellsTexture.destroy();\n indicesTexture.destroy();\n },\n };\n state.refresh(camera, width, height);\n return state;\n}\n\nfunction textureElementCount(texels: number, components: number, dataTextureWidth: number): number {\n return dataTextureWidth * Math.max(1, Math.ceil(texels / dataTextureWidth)) * components;\n}\n\nfunction createDataTexture(engine: EngineContext, format: GPUTextureFormat, texels: number, label: string, dataTextureWidth: number): GPUTexture {\n const height = Math.max(1, Math.ceil(texels / dataTextureWidth));\n const texture = engine._device.createTexture({\n label,\n size: { width: dataTextureWidth, height },\n format,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n return texture;\n}\n\nfunction writeDataTexture(engine: EngineContext, texture: GPUTexture, data: Float32Array | Uint32Array, components: number, texels: number, dataTextureWidth: number): void {\n const height = Math.max(1, Math.ceil(texels / dataTextureWidth));\n const width = height > 1 ? dataTextureWidth : Math.max(1, Math.min(texels, dataTextureWidth));\n engine._device.queue.writeTexture({ texture }, data.buffer, { bytesPerRow: width * components * 4, rowsPerImage: height }, { width, height });\n}\n\nfunction addLightToClusters(\n sliceData: Uint32Array,\n maskData: Uint32Array,\n light: ClusteredPointLight,\n viewDepth: number,\n lightIndex: number,\n view: ArrayLike<number>,\n proj: ArrayLike<number>,\n tileCountX: number,\n tileCountY: number,\n zSlices: number,\n sliceScale: number,\n sliceBias: number,\n batchCount: number\n): void {\n const vx = view[0]! * light.position[0] + view[4]! * light.position[1] + view[8]! * light.position[2] + view[12]!;\n const vy = view[1]! * light.position[0] + view[5]! * light.position[1] + view[9]! * light.position[2] + view[13]!;\n const vz = viewDepth;\n const range = Math.max(0, light.range);\n const firstSlice = getSliceIndex(vz - range, sliceScale, sliceBias);\n const lastSlice = getSliceIndex(vz + range, sliceScale, sliceBias);\n if (lastSlice < 0 || firstSlice >= zSlices) {\n return;\n }\n\n const bounds = projectedSphereBounds(vx, vy, vz, range, proj, tileCountX, tileCountY);\n const minX = bounds[0];\n const maxX = bounds[1];\n const minY = bounds[2];\n const maxY = bounds[3];\n const z0 = clampInt(firstSlice, 0, zSlices - 1);\n const z1 = clampInt(lastSlice, 0, zSlices - 1);\n for (let z = z0; z <= z1; z++) {\n const off = z * 4;\n sliceData[off] = Math.min(sliceData[off]!, lightIndex);\n sliceData[off + 1] = Math.max(sliceData[off + 1]!, lightIndex);\n }\n const batch = Math.floor(lightIndex / CLUSTER_BATCH_SIZE);\n const bit = 1 << (lightIndex % CLUSTER_BATCH_SIZE);\n for (let y = minY; y <= maxY; y++) {\n for (let x = minX; x <= maxX; x++) {\n const maskIndex = (x * tileCountY + y) * batchCount + batch;\n maskData[maskIndex] = maskData[maskIndex]! | bit;\n }\n }\n}\n\nfunction viewZ(position: readonly [number, number, number], view: ArrayLike<number>): number {\n return view[2]! * position[0] + view[6]! * position[1] + view[10]! * position[2] + view[14]!;\n}\n\nfunction getSliceIndex(depth: number, sliceScale: number, sliceBias: number): number {\n return depth > 0 ? Math.floor(Math.log(depth) * sliceScale + sliceBias) : -1;\n}\n\nfunction clampInt(v: number, min: number, max: number): number {\n return v < min ? min : v > max ? max : v;\n}\n\nfunction projectedSphereBounds(\n vx: number,\n vy: number,\n vz: number,\n range: number,\n proj: ArrayLike<number>,\n tileCountX: number,\n tileCountY: number\n): [number, number, number, number] {\n const rangeSq = range * range;\n let minNdcX = -1;\n let maxNdcX = 1;\n let minNdcY = -1;\n let maxNdcY = 1;\n // proj[11] is 1 for a perspective projection and 0 for an orthographic one — a\n // projection-agnostic discriminator that needs no coupling to the camera module.\n // Under orthographic projection the silhouette is depth-independent: the sphere maps\n // to an axis-aligned box of exactly its own radius, offset by the (possibly\n // off-center) projection translation in proj[12]/proj[13], which the perspective\n // path below ignores entirely.\n if (proj[11] === 0) {\n const sx = proj[0]!;\n const sy = proj[5]!;\n const cx = sx * vx + proj[12]!;\n const cy = sy * vy + proj[13]!;\n const rx = Math.abs(sx * range);\n const ry = Math.abs(sy * range);\n minNdcX = Math.max(cx - rx, -1);\n maxNdcX = Math.min(cx + rx, 1);\n minNdcY = Math.max(cy - ry, -1);\n maxNdcY = Math.min(cy + ry, 1);\n } else if (vz > range) {\n const x0 = projectedSphereEdge(vx, vz, rangeSq, proj[0]!, -1);\n const x1 = projectedSphereEdge(vx, vz, rangeSq, proj[0]!, 1);\n minNdcX = Math.min(x0, x1);\n maxNdcX = Math.max(x0, x1);\n const y0 = projectedSphereEdge(vy, vz, rangeSq, proj[5]!, -1);\n const y1 = projectedSphereEdge(vy, vz, rangeSq, proj[5]!, 1);\n minNdcY = Math.min(y0, y1);\n maxNdcY = Math.max(y0, y1);\n }\n return [\n clampInt(Math.floor((minNdcX * 0.5 + 0.5) * tileCountX) - 1, 0, tileCountX - 1),\n clampInt(Math.floor((maxNdcX * 0.5 + 0.5) * tileCountX) + 1, 0, tileCountX - 1),\n clampInt(Math.floor((0.5 - maxNdcY * 0.5) * tileCountY) - 1, 0, tileCountY - 1),\n clampInt(Math.floor((0.5 - minNdcY * 0.5) * tileCountY) + 1, 0, tileCountY - 1),\n ];\n}\n\nfunction projectedSphereEdge(axis: number, depth: number, rangeSq: number, projectionScale: number, side: -1 | 1): number {\n const distSq = axis * axis + depth * depth;\n if (distSq <= rangeSq) {\n return side;\n }\n const sinSq = rangeSq / distSq;\n const cosSq = Math.max(1 - sinSq, 0.01);\n const sinCos = side * Math.sqrt(sinSq * cosSq);\n const rotatedAxis = cosSq * axis + sinCos * depth;\n const rotatedDepth = -sinCos * axis + cosSq * depth;\n return (projectionScale * rotatedAxis) / Math.max(rotatedDepth, 0.01);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { F32, U8, U32, I32 } from '../../engine/typed-arrays.js';
|
|
|
3
3
|
import { BU } from '../../engine/gpu-flags.js';
|
|
4
4
|
import { createEmptyUniformBuffer } from '../../resource/gpu-buffers.js';
|
|
5
5
|
import { acquireTexture, releaseTexture } from '../../resource/gpu-pool.js';
|
|
6
|
-
import { getEffectiveAspectRatio, getViewMatrix, getProjectionMatrix, getViewProjectionMatrix } from '../../camera/camera.js';
|
|
6
|
+
import { _cameraChangeKey, getEffectiveAspectRatio, getViewMatrix, getProjectionMatrix, getViewProjectionMatrix } from '../../camera/camera.js';
|
|
7
7
|
import { mat4MultiplyInto } from '../../math/mat4-multiply-into.js';
|
|
8
8
|
import { _isShaderSystemUniform } from './shader-material.js';
|
|
9
9
|
import { getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings } from './shader-pipeline.js';
|
|
@@ -194,7 +194,7 @@ function updatePacket(scene, material, packet, context, uniformBatch) {
|
|
|
194
194
|
const engine = scene.surface.engine;
|
|
195
195
|
const state = material;
|
|
196
196
|
const camera = context._camera ?? scene.camera;
|
|
197
|
-
const cameraVersion = camera ? camera
|
|
197
|
+
const cameraVersion = camera ? _cameraChangeKey(camera) : -1;
|
|
198
198
|
const meshWmVersion = packet.mesh.worldMatrixVersion;
|
|
199
199
|
const alphaCutoff = material._uniformValues.get("alphaCutoff")?.value[0] ?? 0.4;
|
|
200
200
|
const aspect = camera ? getEffectiveAspectRatio(camera, context.targetWidth, context.targetHeight) : 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\";\nimport type { UniformCopyBatch } from \"../../render/uniform-copy-batch.js\";\n\ntype UniformBatchFactory = (signature: import(\"../../engine/render-target.js\").RenderTargetSignature) => UniformCopyBatch;\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 _shaderCustomBytes?: Uint8Array<ArrayBuffer> | null;\n _shaderCustomVersion?: number;\n}\n\n/** @internal */\nexport type ShaderRenderPass = GPURenderPassEncoder | GPURenderBundleEncoder;\n\nexport function buildShaderMaterialRenderables(scene: SceneContext, meshes: Mesh[], getUniformBatch?: UniformBatchFactory): 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, getUniformBatch);\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, false, getUniformBatch);\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 let getUniformBatch: UniformBatchFactory | undefined;\n if (meshes.length > 1) {\n const { getUniformCopyBatch } = await import(\"../../render/uniform-copy-batch.js\");\n getUniformBatch = getUniformCopyBatch;\n }\n const firstMaterial = meshes[0]?.material;\n if (firstMaterial && meshes.some((mesh) => mesh.material !== firstMaterial)) {\n const { enableShaderPipelineCache } = await import(\"./shader-pipeline-cache.js\");\n enableShaderPipelineCache(scene.surface.engine, meshes);\n }\n const buildPlain = (s: SceneContext, plainMeshes: Mesh[]): MeshGroupBuildResult => buildShaderMaterialRenderables(s, plainMeshes, getUniformBatch);\n if (!meshes.some((m) => !!m.thinInstances)) {\n return buildPlain(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 buildPlain,\n createPacket,\n updatePacket,\n updateCustomUbo,\n getAttrBuffer,\n getOrCreateShaderPipeline,\n getOrCreateShaderPipelineBindings,\n getUniformBatch,\n cull\n );\n}\n\nfunction buildSingleShaderRenderable(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean, getUniformBatch?: UniformBatchFactory): Renderable {\n return buildMaterialRenderables(scene, material, [mesh], isOverride, getUniformBatch)[0]!;\n}\n\nfunction buildMaterialRenderables(scene: SceneContext, material: ShaderMaterial, meshes: readonly Mesh[], isOverride = false, getUniformBatch?: UniformBatchFactory): 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, getUniformBatch));\n }\n return [createOpaqueRenderable(scene, material, packets, isOverride, getUniformBatch)];\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(\n scene: SceneContext,\n material: ShaderMaterial,\n packets: readonly ShaderPacket[],\n isOverride: boolean,\n getUniformBatch?: UniformBatchFactory\n): 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, uniformBatch?: UniformCopyBatch): void => {\n updateCustomUbo(scene.surface.engine, material, uniformBatch);\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, uniformBatch);\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 const uniformBatch = getUniformBatch?.(sig);\n return {\n renderable: r,\n pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings),\n _updateBatches: uniformBatch ? [uniformBatch] : undefined,\n update: (context) => update(context, uniformBatch),\n draw: (pass) => draw(pass, eng),\n };\n },\n };\n return r;\n}\n\nfunction createTransparentRenderable(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, isOverride: boolean, getUniformBatch?: UniformBatchFactory): 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, uniformBatch?: UniformCopyBatch): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return;\n }\n updateCustomUbo(scene.surface.engine, material, uniformBatch);\n updatePacket(scene, material, packet, context, uniformBatch);\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 const uniformBatch = getUniformBatch?.(sig);\n return {\n renderable: r,\n pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings),\n _updateBatches: uniformBatch ? [uniformBatch] : undefined,\n update: (context) => update(context, uniformBatch),\n draw: (pass) => draw(pass, eng),\n };\n },\n };\n return r;\n}\n\nfunction updatePacket(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext, uniformBatch?: UniformCopyBatch): 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 if (uniformBatch) {\n uniformBatch.queue(packet.systemUBO, packet.systemData);\n } else {\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n }\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._shaderCustomBytes = 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._shaderCustomBytes = new U8(state._shaderCustomData);\n state._shaderCustomVersion = -1;\n updateCustomUbo(engine, material);\n}\n\nfunction updateCustomUbo(engine: EngineContext, material: ShaderMaterial, uniformBatch?: UniformCopyBatch): 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 = state._shaderCustomBytes ?? (state._shaderCustomBytes = 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 if (uniformBatch) {\n uniformBatch.queue(customUbo, bytes);\n } else {\n engine._device.queue.writeBuffer(customUbo, 0, bytes);\n }\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 storageBuffer = slot?.current;\n const buffer = storageBuffer?._buffer;\n if (!buffer || !engine._storageBuffers?.has(storageBuffer)) {\n throw new Error(`ShaderMaterial storage \"${storage.name}\" is invalid.`);\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 const buffer = slot.current._buffer;\n if (buffer) {\n buffers.push(buffer);\n }\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 Object.assign(\n () => {\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 { p: packet }\n )\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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"}
|
|
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, _cameraChangeKey } 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\";\nimport type { UniformCopyBatch } from \"../../render/uniform-copy-batch.js\";\n\ntype UniformBatchFactory = (signature: import(\"../../engine/render-target.js\").RenderTargetSignature) => UniformCopyBatch;\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 _shaderCustomBytes?: Uint8Array<ArrayBuffer> | null;\n _shaderCustomVersion?: number;\n}\n\n/** @internal */\nexport type ShaderRenderPass = GPURenderPassEncoder | GPURenderBundleEncoder;\n\nexport function buildShaderMaterialRenderables(scene: SceneContext, meshes: Mesh[], getUniformBatch?: UniformBatchFactory): 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, getUniformBatch);\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, false, getUniformBatch);\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 let getUniformBatch: UniformBatchFactory | undefined;\n if (meshes.length > 1) {\n const { getUniformCopyBatch } = await import(\"../../render/uniform-copy-batch.js\");\n getUniformBatch = getUniformCopyBatch;\n }\n const firstMaterial = meshes[0]?.material;\n if (firstMaterial && meshes.some((mesh) => mesh.material !== firstMaterial)) {\n const { enableShaderPipelineCache } = await import(\"./shader-pipeline-cache.js\");\n enableShaderPipelineCache(scene.surface.engine, meshes);\n }\n const buildPlain = (s: SceneContext, plainMeshes: Mesh[]): MeshGroupBuildResult => buildShaderMaterialRenderables(s, plainMeshes, getUniformBatch);\n if (!meshes.some((m) => !!m.thinInstances)) {\n return buildPlain(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 buildPlain,\n createPacket,\n updatePacket,\n updateCustomUbo,\n getAttrBuffer,\n getOrCreateShaderPipeline,\n getOrCreateShaderPipelineBindings,\n getUniformBatch,\n cull\n );\n}\n\nfunction buildSingleShaderRenderable(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean, getUniformBatch?: UniformBatchFactory): Renderable {\n return buildMaterialRenderables(scene, material, [mesh], isOverride, getUniformBatch)[0]!;\n}\n\nfunction buildMaterialRenderables(scene: SceneContext, material: ShaderMaterial, meshes: readonly Mesh[], isOverride = false, getUniformBatch?: UniformBatchFactory): 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, getUniformBatch));\n }\n return [createOpaqueRenderable(scene, material, packets, isOverride, getUniformBatch)];\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(\n scene: SceneContext,\n material: ShaderMaterial,\n packets: readonly ShaderPacket[],\n isOverride: boolean,\n getUniformBatch?: UniformBatchFactory\n): 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, uniformBatch?: UniformCopyBatch): void => {\n updateCustomUbo(scene.surface.engine, material, uniformBatch);\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, uniformBatch);\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 const uniformBatch = getUniformBatch?.(sig);\n return {\n renderable: r,\n pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings),\n _updateBatches: uniformBatch ? [uniformBatch] : undefined,\n update: (context) => update(context, uniformBatch),\n draw: (pass) => draw(pass, eng),\n };\n },\n };\n return r;\n}\n\nfunction createTransparentRenderable(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, isOverride: boolean, getUniformBatch?: UniformBatchFactory): 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, uniformBatch?: UniformCopyBatch): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return;\n }\n updateCustomUbo(scene.surface.engine, material, uniformBatch);\n updatePacket(scene, material, packet, context, uniformBatch);\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 const uniformBatch = getUniformBatch?.(sig);\n return {\n renderable: r,\n pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings),\n _updateBatches: uniformBatch ? [uniformBatch] : undefined,\n update: (context) => update(context, uniformBatch),\n draw: (pass) => draw(pass, eng),\n };\n },\n };\n return r;\n}\n\nfunction updatePacket(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext, uniformBatch?: UniformCopyBatch): 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 ? _cameraChangeKey(camera) : -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 if (uniformBatch) {\n uniformBatch.queue(packet.systemUBO, packet.systemData);\n } else {\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n }\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._shaderCustomBytes = 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._shaderCustomBytes = new U8(state._shaderCustomData);\n state._shaderCustomVersion = -1;\n updateCustomUbo(engine, material);\n}\n\nfunction updateCustomUbo(engine: EngineContext, material: ShaderMaterial, uniformBatch?: UniformCopyBatch): 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 = state._shaderCustomBytes ?? (state._shaderCustomBytes = 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 if (uniformBatch) {\n uniformBatch.queue(customUbo, bytes);\n } else {\n engine._device.queue.writeBuffer(customUbo, 0, bytes);\n }\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 storageBuffer = slot?.current;\n const buffer = storageBuffer?._buffer;\n if (!buffer || !engine._storageBuffers?.has(storageBuffer)) {\n throw new Error(`ShaderMaterial storage \"${storage.name}\" is invalid.`);\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 const buffer = slot.current._buffer;\n if (buffer) {\n buffers.push(buffer);\n }\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 Object.assign(\n () => {\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 { p: packet }\n )\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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enable-standard-mesh-features.js","sources":["../../../../src/material/standard/enable-standard-mesh-features.ts"],"sourcesContent":["/**\n * Published opt-ins for Standard skeletal skinning and UV translation. Import\n * from `@babylonjs/lite
|
|
1
|
+
{"version":3,"file":"enable-standard-mesh-features.js","sources":["../../../../src/material/standard/enable-standard-mesh-features.ts"],"sourcesContent":["/**\n * Published opt-ins for Standard skeletal skinning and UV translation. Import\n * from the `@babylonjs/lite` root entry.\n *\n * RGBA vertex colours are enabled separately through the canonical\n * `enableStandardVertexColors()` from\n * the `@babylonjs/lite` root entry.\n */\n\nimport { _preloadStdMeshExt } from \"./standard-group-builder.js\";\nimport { _enableStandardGeometrySkeletonVelocity } from \"./standard-geometry-feature-hooks.js\";\nimport { _installStandardUvOffsetResolver } from \"./standard-pipeline.js\";\n\nlet _skeletonEnabled = false;\n/** Enable four/eight-influence skeletal skinning for Standard meshes. */\nexport function enableStandardSkeleton(): void {\n if (_skeletonEnabled) {\n return;\n }\n _skeletonEnabled = true;\n _enableStandardGeometrySkeletonVelocity(() => import(\"./standard-geometry-skeleton-velocity.js\"));\n // Eagerly preload + register the skinning ext so a skeletal mesh added AFTER the\n // initial group build (synchronous `_rebuildSingle`, which cannot import) is still\n // deformed. Registration is global + durable; the group builder awaits it as a\n // backstop before the first frame. See `_preloadStdMeshExt`.\n _preloadStdMeshExt(() => import(\"./fragments/std-skeleton-fragment.js\"), \"stdSkeletonExt\");\n}\n\nlet _uvOffsetEnabled = false;\n/** Enable `StandardMaterialProps.uvOffset` reads. Missing offsets remain [0, 0]. */\nexport function enableStandardUvOffset(): void {\n if (_uvOffsetEnabled) {\n return;\n }\n _uvOffsetEnabled = true;\n _installStandardUvOffsetResolver((material) => material.uvOffset ?? null);\n}\n"],"names":[],"mappings":";;;;AAaA,IAAI,gBAAA,GAAmB,KAAA;AAEhB,SAAS,sBAAA,GAA+B;AAC3C,EAAA,IAAI,gBAAA,EAAkB;AAClB,IAAA;AAAA,EACJ;AACA,EAAA,gBAAA,GAAmB,IAAA;AACnB,EAAA,uCAAA,CAAwC,MAAM,OAAO,0CAA0C,CAAC,CAAA;AAKhG,EAAA,kBAAA,CAAmB,MAAM,OAAO,sCAAsC,CAAA,EAAG,gBAAgB,CAAA;AAC7F;AAEA,IAAI,gBAAA,GAAmB,KAAA;AAEhB,SAAS,sBAAA,GAA+B;AAC3C,EAAA,IAAI,gBAAA,EAAkB;AAClB,IAAA;AAAA,EACJ;AACA,EAAA,gBAAA,GAAmB,IAAA;AACnB,EAAA,gCAAA,CAAiC,CAAC,QAAA,KAAa,QAAA,CAAS,QAAA,IAAY,IAAI,CAAA;AAC5E;;;;"}
|
package/lib/math/index.js
CHANGED
|
@@ -21,6 +21,7 @@ export { mat4Multiply } from './mat4-multiply.js';
|
|
|
21
21
|
export { mat4LookAtLH } from './mat4-look-at-lh.js';
|
|
22
22
|
export { mat4PerspectiveLH } from './mat4-perspective-lh.js';
|
|
23
23
|
export { mat4PerspectiveLHToRef } from './mat4-perspective-lh-to-ref.js';
|
|
24
|
+
export { mat4OrthoOffCenterLHToRef } from './mat4-ortho-lh-to-ref.js';
|
|
24
25
|
export { mat4Invert } from './mat4-invert.js';
|
|
25
26
|
export { mat4Scale } from './mat4-scale.js';
|
|
26
27
|
export { mat4Translation } from './mat4-translation.js';
|
package/lib/math/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function mat4LookAtWorldLHToRef(out, eye, target, up) {
|
|
2
|
+
out[3] = 0;
|
|
3
|
+
out[7] = 0;
|
|
4
|
+
out[11] = 0;
|
|
5
|
+
out[12] = eye.x;
|
|
6
|
+
out[13] = eye.y;
|
|
7
|
+
out[14] = eye.z;
|
|
8
|
+
out[15] = 1;
|
|
9
|
+
let zx = target.x - eye.x;
|
|
10
|
+
let zy = target.y - eye.y;
|
|
11
|
+
let zz = target.z - eye.z;
|
|
12
|
+
const zLen = Math.sqrt(zx * zx + zy * zy + zz * zz);
|
|
13
|
+
let xx = 0;
|
|
14
|
+
let xy = 0;
|
|
15
|
+
let xz = 0;
|
|
16
|
+
let xLen = 0;
|
|
17
|
+
if (zLen >= 1e-10) {
|
|
18
|
+
const invZ = 1 / zLen;
|
|
19
|
+
zx *= invZ;
|
|
20
|
+
zy *= invZ;
|
|
21
|
+
zz *= invZ;
|
|
22
|
+
xx = up.y * zz - up.z * zy;
|
|
23
|
+
xy = up.z * zx - up.x * zz;
|
|
24
|
+
xz = up.x * zy - up.y * zx;
|
|
25
|
+
xLen = Math.sqrt(xx * xx + xy * xy + xz * xz);
|
|
26
|
+
}
|
|
27
|
+
if (xLen < 1e-10) {
|
|
28
|
+
out[0] = 1;
|
|
29
|
+
out[1] = 0;
|
|
30
|
+
out[2] = 0;
|
|
31
|
+
out[4] = 0;
|
|
32
|
+
out[5] = 1;
|
|
33
|
+
out[6] = 0;
|
|
34
|
+
out[8] = 0;
|
|
35
|
+
out[9] = 0;
|
|
36
|
+
out[10] = 1;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const invX = 1 / xLen;
|
|
40
|
+
xx *= invX;
|
|
41
|
+
xy *= invX;
|
|
42
|
+
xz *= invX;
|
|
43
|
+
out[0] = xx;
|
|
44
|
+
out[1] = xy;
|
|
45
|
+
out[2] = xz;
|
|
46
|
+
out[4] = zy * xz - zz * xy;
|
|
47
|
+
out[5] = zz * xx - zx * xz;
|
|
48
|
+
out[6] = zx * xy - zy * xx;
|
|
49
|
+
out[8] = zx;
|
|
50
|
+
out[9] = zy;
|
|
51
|
+
out[10] = zz;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { mat4LookAtWorldLHToRef };
|
|
55
|
+
//# sourceMappingURL=mat4-look-at-world-lh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mat4-look-at-world-lh.js","sources":["../../../src/math/mat4-look-at-world-lh.ts"],"sourcesContent":["import type { Mat4Storage, Vec3 } from \"./types.js\";\n\n/** Write the camera-to-world matrix for an eye looking at `target` — the inverse of the\n * `mat4LookAtLH` view matrix, built directly instead of by inverting one.\n *\n * Every camera factory needs this, not a view matrix: the engine stores a camera's *world*\n * matrix (so cameras parent like any other node) and derives the view matrix from it in\n * `getViewMatrix`. Routing through `mat4LookAtLH` meant, on every camera move, allocating a\n * view matrix, computing a translation column that was immediately discarded, and then\n * transposing the rotation back out of it. The basis is the same three vectors either way,\n * so this writes them straight into the caller's storage: columns `[xAxis, yAxis, zAxis, eye]`.\n *\n * Degenerate input — eye on target, or the view direction parallel to `up` — leaves an\n * identity rotation with the eye translation, matching `mat4LookAtLH`'s identity fallback. */\nexport function mat4LookAtWorldLHToRef(out: Mat4Storage, eye: Vec3, target: Vec3, up: Vec3): void {\n out[3] = 0;\n out[7] = 0;\n out[11] = 0;\n out[12] = eye.x;\n out[13] = eye.y;\n out[14] = eye.z;\n out[15] = 1;\n\n // Left-handed: +Z points from the eye towards the target.\n let zx = target.x - eye.x;\n let zy = target.y - eye.y;\n let zz = target.z - eye.z;\n const zLen = Math.sqrt(zx * zx + zy * zy + zz * zz);\n let xx = 0;\n let xy = 0;\n let xz = 0;\n let xLen = 0;\n if (zLen >= 1e-10) {\n const invZ = 1 / zLen;\n zx *= invZ;\n zy *= invZ;\n zz *= invZ;\n // xAxis = cross(up, zAxis)\n xx = up.y * zz - up.z * zy;\n xy = up.z * zx - up.x * zz;\n xz = up.x * zy - up.y * zx;\n xLen = Math.sqrt(xx * xx + xy * xy + xz * xz);\n }\n if (xLen < 1e-10) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n return;\n }\n const invX = 1 / xLen;\n xx *= invX;\n xy *= invX;\n xz *= invX;\n\n out[0] = xx;\n out[1] = xy;\n out[2] = xz;\n // yAxis = cross(zAxis, xAxis) — already unit, both operands are.\n out[4] = zy * xz - zz * xy;\n out[5] = zz * xx - zx * xz;\n out[6] = zx * xy - zy * xx;\n out[8] = zx;\n out[9] = zy;\n out[10] = zz;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function mat4OrthoOffCenterLHToRef(out, left, right, bottom, top, near, far) {
|
|
2
|
+
const range = far - near;
|
|
3
|
+
out[0] = 2 / (right - left);
|
|
4
|
+
out[1] = 0;
|
|
5
|
+
out[2] = 0;
|
|
6
|
+
out[3] = 0;
|
|
7
|
+
out[4] = 0;
|
|
8
|
+
out[5] = 2 / (top - bottom);
|
|
9
|
+
out[6] = 0;
|
|
10
|
+
out[7] = 0;
|
|
11
|
+
out[8] = 0;
|
|
12
|
+
out[9] = 0;
|
|
13
|
+
out[10] = -1 / range;
|
|
14
|
+
out[11] = 0;
|
|
15
|
+
out[12] = (left + right) / (left - right);
|
|
16
|
+
out[13] = (top + bottom) / (bottom - top);
|
|
17
|
+
out[14] = far / range;
|
|
18
|
+
out[15] = 1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { mat4OrthoOffCenterLHToRef };
|
|
22
|
+
//# sourceMappingURL=mat4-ortho-lh-to-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mat4-ortho-lh-to-ref.js","sources":["../../../src/math/mat4-ortho-lh-to-ref.ts"],"sourcesContent":["import type { Mat4Storage } from \"./types.js\";\n\n/** Write a reverse-Z off-center orthographic projection into `out` without allocating.\n * WebGPU clip-space depth is [0, 1]; like `mat4PerspectiveLHToRef` this maps\n * `near -> 1` and `far -> 0`, so orthographic cameras share the engine's\n * reverse-Z depth state (clear 0, compare `greater`).\n *\n * This writer overwrites all 16 elements. `mat4PerspectiveLHToRef` writes only the five\n * a perspective matrix needs (0, 5, 10, 11, 14) and assumes the rest of its target is\n * already zero, so the two are not symmetric: switching perspective to orthographic is\n * safe on a shared cache, while the reverse relies on `disableOrthographicCamera`\n * clearing out[12], out[13] and out[15] before handing the cache back. Optional\n * projectors fully overwrite their output so a future third projection type cannot be\n * contaminated by whichever one ran before it.\n * Storage may be F32- or F64-backed. */\nexport function mat4OrthoOffCenterLHToRef(out: Mat4Storage, left: number, right: number, bottom: number, top: number, near: number, far: number): void {\n const range = far - near;\n out[0] = 2 / (right - left);\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = 2 / (top - bottom);\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = -1 / range;\n out[11] = 0;\n out[12] = (left + right) / (left - right);\n out[13] = (top + bottom) / (bottom - top);\n out[14] = far / range;\n out[15] = 1;\n}\n"],"names":[],"mappings":"AAeO,SAAS,0BAA0B,GAAA,EAAkB,IAAA,EAAc,OAAe,MAAA,EAAgB,GAAA,EAAa,MAAc,GAAA,EAAmB;AACnJ,EAAA,MAAM,QAAQ,GAAA,GAAM,IAAA;AACpB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA,IAAK,KAAA,GAAQ,IAAA,CAAA;AACtB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA,IAAK,GAAA,GAAM,MAAA,CAAA;AACpB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACT,EAAA,GAAA,CAAI,EAAE,IAAI,EAAA,GAAK,KAAA;AACf,EAAA,GAAA,CAAI,EAAE,CAAA,GAAI,CAAA;AACV,EAAA,GAAA,CAAI,EAAE,CAAA,GAAA,CAAK,IAAA,GAAO,KAAA,KAAU,IAAA,GAAO,KAAA,CAAA;AACnC,EAAA,GAAA,CAAI,EAAE,CAAA,GAAA,CAAK,GAAA,GAAM,MAAA,KAAW,MAAA,GAAS,GAAA,CAAA;AACrC,EAAA,GAAA,CAAI,EAAE,IAAI,GAAA,GAAM,KAAA;AAChB,EAAA,GAAA,CAAI,EAAE,CAAA,GAAI,CAAA;AACd;;;;"}
|
package/lib/math/mat4.js
CHANGED
|
@@ -3,6 +3,7 @@ export { mat4Multiply } from './mat4-multiply.js';
|
|
|
3
3
|
export { mat4LookAtLH } from './mat4-look-at-lh.js';
|
|
4
4
|
export { mat4PerspectiveLH } from './mat4-perspective-lh.js';
|
|
5
5
|
export { mat4PerspectiveLHToRef } from './mat4-perspective-lh-to-ref.js';
|
|
6
|
+
export { mat4OrthoOffCenterLHToRef } from './mat4-ortho-lh-to-ref.js';
|
|
6
7
|
export { mat4Invert } from './mat4-invert.js';
|
|
7
8
|
export { mat4Scale } from './mat4-scale.js';
|
|
8
9
|
export { mat4Translation } from './mat4-translation.js';
|
package/lib/math/mat4.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mat4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mat4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
|
package/lib/navigation/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { addAgent, addBoxObstacle, addCylinderObstacle, agentGoto, computePath, createDebugNavMeshGeometry, createNavCrowd, createNavMesh, createNavMeshFromSources, createNavigationPluginAsync, disposeNavigationPlugin, findClosestPointWithin, findRandomPoint, findRandomPointAroundCircle, getAgentPosition, getAgentVelocity, getClosestPoint, getNavigationRandomSeed, raycast, removeObstacle, setNavigationRandomSeed, updateNavCrowd, updateNavMeshObstacles } from './navigation.js';
|
|
1
|
+
export { addAgent, addBoxObstacle, addCylinderObstacle, agentGoto, computePath, createDebugNavMeshGeometry, createNavCrowd, createNavMesh, createNavMeshFromSources, createNavigationPluginAsync, disposeNavigationPlugin, findClosestPointWithin, findRandomPoint, findRandomPointAroundCircle, getAgentPosition, getAgentVelocity, getClosestPoint, getNavigationRandomSeed, navRayBlocked, raycast, removeObstacle, setNavigationRandomSeed, updateNavCrowd, updateNavMeshObstacles } from './navigation.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|