bplinejs 0.0.101-beta.10

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.
Files changed (129) hide show
  1. package/README.md +215 -0
  2. package/docs/API.md +471 -0
  3. package/lib/Camera/index.d.ts +88 -0
  4. package/lib/Camera/index.js +178 -0
  5. package/lib/Camera/index.js.map +1 -0
  6. package/lib/Color/index.d.ts +99 -0
  7. package/lib/Color/index.js +178 -0
  8. package/lib/Color/index.js.map +1 -0
  9. package/lib/Geometry/Geo.d.ts +131 -0
  10. package/lib/Geometry/Geo.js +180 -0
  11. package/lib/Geometry/Geo.js.map +1 -0
  12. package/lib/Geometry/Poly2D.d.ts +53 -0
  13. package/lib/Geometry/Poly2D.js +133 -0
  14. package/lib/Geometry/Poly2D.js.map +1 -0
  15. package/lib/Geometry/Rect2d.d.ts +89 -0
  16. package/lib/Geometry/Rect2d.js +128 -0
  17. package/lib/Geometry/Rect2d.js.map +1 -0
  18. package/lib/Geometry/index.d.ts +6 -0
  19. package/lib/Geometry/index.js +4 -0
  20. package/lib/Group/index.d.ts +70 -0
  21. package/lib/Group/index.js +110 -0
  22. package/lib/Group/index.js.map +1 -0
  23. package/lib/ID.d.ts +6 -0
  24. package/lib/ID.js +15 -0
  25. package/lib/ID.js.map +1 -0
  26. package/lib/IMesh/index.d.ts +104 -0
  27. package/lib/IMesh/index.js +333 -0
  28. package/lib/IMesh/index.js.map +1 -0
  29. package/lib/Material/Material.d.ts +158 -0
  30. package/lib/Material/Material.js +229 -0
  31. package/lib/Material/Material.js.map +1 -0
  32. package/lib/Material/baseMaterial.d.ts +15 -0
  33. package/lib/Material/baseMaterial.js +24 -0
  34. package/lib/Material/baseMaterial.js.map +1 -0
  35. package/lib/Material/index.d.ts +4 -0
  36. package/lib/Material/index.js +3 -0
  37. package/lib/Material/shaders/base/poly/fragment.js +6 -0
  38. package/lib/Material/shaders/base/poly/fragment.js.map +1 -0
  39. package/lib/Material/shaders/base/poly/vertex.js +6 -0
  40. package/lib/Material/shaders/base/poly/vertex.js.map +1 -0
  41. package/lib/Material/shaders/base/rect/fragment.js +6 -0
  42. package/lib/Material/shaders/base/rect/fragment.js.map +1 -0
  43. package/lib/Material/shaders/base/rect/vertex.js +6 -0
  44. package/lib/Material/shaders/base/rect/vertex.js.map +1 -0
  45. package/lib/Material/shaders/line/fragment.js +6 -0
  46. package/lib/Material/shaders/line/fragment.js.map +1 -0
  47. package/lib/Material/shaders/line/vertex.js +6 -0
  48. package/lib/Material/shaders/line/vertex.js.map +1 -0
  49. package/lib/Mesh/index.d.ts +154 -0
  50. package/lib/Mesh/index.js +254 -0
  51. package/lib/Mesh/index.js.map +1 -0
  52. package/lib/Object/index.d.ts +95 -0
  53. package/lib/Object/index.js +212 -0
  54. package/lib/Object/index.js.map +1 -0
  55. package/lib/Raws/index.d.ts +87 -0
  56. package/lib/Raws/index.js +164 -0
  57. package/lib/Raws/index.js.map +1 -0
  58. package/lib/Render/BufferManager.d.ts +93 -0
  59. package/lib/Render/BufferManager.js +281 -0
  60. package/lib/Render/BufferManager.js.map +1 -0
  61. package/lib/Render/DepthManager.d.ts +22 -0
  62. package/lib/Render/DepthManager.js +95 -0
  63. package/lib/Render/DepthManager.js.map +1 -0
  64. package/lib/Render/DestroyManager.d.ts +74 -0
  65. package/lib/Render/DestroyManager.js +221 -0
  66. package/lib/Render/DestroyManager.js.map +1 -0
  67. package/lib/Render/DevelopmentValidator.d.ts +73 -0
  68. package/lib/Render/DevelopmentValidator.js +188 -0
  69. package/lib/Render/DevelopmentValidator.js.map +1 -0
  70. package/lib/Render/DrawCallManager.d.ts +58 -0
  71. package/lib/Render/DrawCallManager.js +267 -0
  72. package/lib/Render/DrawCallManager.js.map +1 -0
  73. package/lib/Render/PipelineManager.d.ts +46 -0
  74. package/lib/Render/PipelineManager.js +254 -0
  75. package/lib/Render/PipelineManager.js.map +1 -0
  76. package/lib/Render/SamplerManager.d.ts +26 -0
  77. package/lib/Render/SamplerManager.js +42 -0
  78. package/lib/Render/SamplerManager.js.map +1 -0
  79. package/lib/Render/SceneUpdate.d.ts +9 -0
  80. package/lib/Render/SceneUpdate.js +18 -0
  81. package/lib/Render/SceneUpdate.js.map +1 -0
  82. package/lib/Render/TextureManager.d.ts +33 -0
  83. package/lib/Render/TextureManager.js +152 -0
  84. package/lib/Render/TextureManager.js.map +1 -0
  85. package/lib/Render/index.d.ts +212 -0
  86. package/lib/Render/index.js +347 -0
  87. package/lib/Render/index.js.map +1 -0
  88. package/lib/Render/types.d.ts +191 -0
  89. package/lib/Scene/index.d.ts +124 -0
  90. package/lib/Scene/index.js +225 -0
  91. package/lib/Scene/index.js.map +1 -0
  92. package/lib/Style/EdgeStyle.d.ts +28 -0
  93. package/lib/Style/EdgeStyle.js +67 -0
  94. package/lib/Style/EdgeStyle.js.map +1 -0
  95. package/lib/Style/JoinStyle.d.ts +27 -0
  96. package/lib/Style/JoinStyle.js +53 -0
  97. package/lib/Style/JoinStyle.js.map +1 -0
  98. package/lib/Style/PartStyle.d.ts +50 -0
  99. package/lib/Style/PartStyle.js +92 -0
  100. package/lib/Style/PartStyle.js.map +1 -0
  101. package/lib/Style/PointsStyle.d.ts +43 -0
  102. package/lib/Style/PointsStyle.js +98 -0
  103. package/lib/Style/PointsStyle.js.map +1 -0
  104. package/lib/Style/SolidStyle.d.ts +37 -0
  105. package/lib/Style/SolidStyle.js +83 -0
  106. package/lib/Style/SolidStyle.js.map +1 -0
  107. package/lib/Style/TexturedStyle.d.ts +29 -0
  108. package/lib/Style/TexturedStyle.js +66 -0
  109. package/lib/Style/TexturedStyle.js.map +1 -0
  110. package/lib/Style/WireframeStyle.d.ts +7 -0
  111. package/lib/Style/WireframeStyle.js +13 -0
  112. package/lib/Style/WireframeStyle.js.map +1 -0
  113. package/lib/Style/WriteStyleData.d.ts +10 -0
  114. package/lib/Style/WriteStyleData.js +59 -0
  115. package/lib/Style/WriteStyleData.js.map +1 -0
  116. package/lib/Style/index.d.ts +50 -0
  117. package/lib/Style/index.js +92 -0
  118. package/lib/Style/index.js.map +1 -0
  119. package/lib/Style/types.d.ts +21 -0
  120. package/lib/Texture/Layers.d.ts +26 -0
  121. package/lib/Texture/Layers.js +42 -0
  122. package/lib/Texture/Layers.js.map +1 -0
  123. package/lib/Texture/index.d.ts +116 -0
  124. package/lib/Texture/index.js +198 -0
  125. package/lib/Texture/index.js.map +1 -0
  126. package/lib/global-types.d.ts +8 -0
  127. package/lib/index.d.ts +43 -0
  128. package/lib/index.js +34 -0
  129. package/package.json +130 -0
@@ -0,0 +1,281 @@
1
+ import "../Style/WriteStyleData.js";
2
+ import DepthManager from "./DepthManager.js";
3
+ import DevelopmentValidator from "./DevelopmentValidator.js";
4
+ //#region src/scripts/Render/BufferManager.ts
5
+ /**
6
+ * 管理当前 Render 对应的 Camera、Material、Mesh 和 Geometry GPUBuffer。
7
+ * @class
8
+ */
9
+ var BufferManager = class {
10
+ pipeline;
11
+ depthManager;
12
+ developmentValidator;
13
+ _cameraSnapshot;
14
+ _validatedMaterials = /* @__PURE__ */ new WeakMap();
15
+ /**
16
+ * 创建缓冲管理器。
17
+ * @param pipeline 当前 Render 的共享管线资源
18
+ */
19
+ constructor(pipeline) {
20
+ this.pipeline = pipeline;
21
+ this.depthManager = new DepthManager(pipeline);
22
+ this.developmentValidator = new DevelopmentValidator();
23
+ }
24
+ /**
25
+ * 创建或更新当前场景需要的 GPUBuffer。
26
+ * @param scene 场景对象
27
+ * @param camera 相机对象
28
+ * @param dpr 当前设备像素比
29
+ * @param renderMode 当前 Render 运行模式
30
+ * @returns 无返回值
31
+ */
32
+ draw(scene, camera, dpr, renderMode) {
33
+ const device = this.pipeline.device;
34
+ if (device === void 0) return;
35
+ if (renderMode === "development") this.developmentValidator.validateCamera(camera);
36
+ this.drawCameraBuffers(device, camera, dpr);
37
+ this.drawGeometryBuffers(device, scene, renderMode);
38
+ this.prepareMaterials(scene, renderMode);
39
+ this.drawMeshBuffers(device, scene, renderMode);
40
+ this.depthManager.prepare(scene);
41
+ }
42
+ /**
43
+ * 按 materialList 检查材质,共享材质每个版本只检查一次。
44
+ * 材质显示数值的 GPU 存储属于 Mesh 实例数组,不在这里重复创建一份缓冲。
45
+ * @param scene 场景对象
46
+ * @param renderMode production 跳过开发检查
47
+ */
48
+ prepareMaterials(scene, renderMode) {
49
+ if (renderMode !== "development") return;
50
+ for (const material of scene.materialList) {
51
+ if (this._validatedMaterials.get(material) === material.version) continue;
52
+ this.developmentValidator.validateMaterial(material);
53
+ this._validatedMaterials.set(material, material.version);
54
+ }
55
+ }
56
+ /**
57
+ * 创建并写入基础 GPUBuffer。
58
+ * @param device 当前 Render 对应的 WebGPU 设备
59
+ * @param label GPU 调试标签
60
+ * @param data 首次写入的缓冲数据
61
+ * @param usage 缓冲用途标记
62
+ * @returns 已写入数据的 GPUBuffer
63
+ */
64
+ createBuffer(device, label, data, usage) {
65
+ const buffer = device.createBuffer({
66
+ label,
67
+ size: data.byteLength,
68
+ usage
69
+ });
70
+ device.queue.writeBuffer(buffer, 0, data);
71
+ return buffer;
72
+ }
73
+ /**
74
+ * 按当前 Render 自己的矩阵身份和版本快照上传相机数据。
75
+ * @param device WebGPU 设备
76
+ * @param camera 相机对象
77
+ * @param dpr 设备像素比
78
+ */
79
+ drawCameraBuffers(device, camera, dpr) {
80
+ camera.ensureCameraMatrix();
81
+ const buffers = this.pipeline.buffers.cameraUniform;
82
+ const previous = this._cameraSnapshot;
83
+ const cameraChanged = previous?.camera !== camera;
84
+ const viewChanged = cameraChanged || previous?.view !== camera.viewMatrix || previous.viewVersion !== camera.viewMatrix.version;
85
+ const projectionChanged = cameraChanged || previous?.projection !== camera.orthogonalMatrix || previous.projectionVersion !== camera.orthogonalMatrix.version;
86
+ const parametersChanged = cameraChanged || previous?.zoom !== camera.zoom || previous.dpr !== dpr;
87
+ const created = buffers.length === 0;
88
+ if (created) buffers.push(this.createBuffer(device, "Camera View Matrix Buffer", camera.viewMatrix.GPUData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), this.createBuffer(device, "Camera Orthogonal Matrix Buffer", camera.orthogonalMatrix.GPUData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), this.createBuffer(device, "Render Camera Parameters Buffer", new Float32Array([
89
+ camera.zoom,
90
+ dpr,
91
+ 0,
92
+ 0
93
+ ]), GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST));
94
+ else {
95
+ if (viewChanged) device.queue.writeBuffer(buffers[0], 0, camera.viewMatrix.GPUData);
96
+ if (projectionChanged) device.queue.writeBuffer(buffers[1], 0, camera.orthogonalMatrix.GPUData);
97
+ if (parametersChanged) device.queue.writeBuffer(buffers[2], 0, new Float32Array([
98
+ camera.zoom,
99
+ dpr,
100
+ 0,
101
+ 0
102
+ ]));
103
+ }
104
+ if (created || viewChanged || projectionChanged || parametersChanged) this._cameraSnapshot = {
105
+ camera,
106
+ view: camera.viewMatrix,
107
+ viewVersion: camera.viewMatrix.version,
108
+ projection: camera.orthogonalMatrix,
109
+ projectionVersion: camera.orthogonalMatrix.version,
110
+ zoom: camera.zoom,
111
+ dpr
112
+ };
113
+ }
114
+ /**
115
+ * 创建或更新每个 Mesh 的连续矩阵与样式 Storage 数组,分别对比版本。
116
+ * @param device 当前 WebGPU 设备
117
+ * @param scene 场景对象
118
+ * @param renderMode 当前 Render 运行模式
119
+ * @returns 无返回值
120
+ */
121
+ drawMeshBuffers(device, scene, renderMode) {
122
+ for (const mesh of scene.drawList) {
123
+ if (renderMode === "development" && (mesh.geometryPending || mesh.materialPending || !this.pipeline.buffers.meshStyle.has(mesh.id))) this.developmentValidator.validateMesh(mesh);
124
+ const material = mesh.material;
125
+ if (material === void 0) continue;
126
+ mesh.updateInstanceData();
127
+ if (mesh.count === 0) continue;
128
+ const limit = Math.min(device.limits.maxBufferSize, device.limits.maxStorageBufferBindingSize);
129
+ if (mesh.matrixData.byteLength > limit || mesh.styleData.byteLength > limit) throw new RangeError("Mesh " + String(mesh.id) + " capacity exceeds this GPUDevice storage buffer limit: " + String(limit) + " bytes.");
130
+ const matrixBuffers = this.pipeline.buffers.meshMatrix;
131
+ let matrixBuffer = matrixBuffers.get(mesh.id);
132
+ if (matrixBuffer !== void 0 && matrixBuffer.capacity !== mesh.capacity) {
133
+ matrixBuffer.buffer.destroy();
134
+ matrixBuffers.delete(mesh.id);
135
+ matrixBuffer = void 0;
136
+ }
137
+ if (matrixBuffer === void 0) {
138
+ matrixBuffer = {
139
+ meshId: mesh.id,
140
+ capacity: mesh.capacity,
141
+ version: mesh.matrixVersion,
142
+ buffer: this.createBuffer(device, "Mesh " + String(mesh.id) + " Instance Matrices", mesh.matrixData, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST)
143
+ };
144
+ matrixBuffers.set(mesh.id, matrixBuffer);
145
+ } else if (matrixBuffer.version !== mesh.matrixVersion) {
146
+ device.queue.writeBuffer(matrixBuffer.buffer, 0, mesh.matrixData, 0, mesh.count * 12);
147
+ matrixBuffer.version = mesh.matrixVersion;
148
+ }
149
+ let styleBuffer = this.pipeline.buffers.meshStyle.get(mesh.id);
150
+ if (styleBuffer !== void 0 && styleBuffer.capacity !== mesh.capacity) {
151
+ styleBuffer.buffer.destroy();
152
+ this.pipeline.buffers.meshStyle.delete(mesh.id);
153
+ styleBuffer = void 0;
154
+ }
155
+ if (styleBuffer === void 0) this.pipeline.buffers.meshStyle.set(mesh.id, {
156
+ meshId: mesh.id,
157
+ materialId: material.id,
158
+ capacity: mesh.capacity,
159
+ version: mesh.styleVersion,
160
+ buffer: this.createBuffer(device, "Mesh " + String(mesh.id) + " Instance Styles", mesh.styleData, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST)
161
+ });
162
+ else {
163
+ styleBuffer.materialId = material.id;
164
+ if (styleBuffer.version !== mesh.styleVersion) {
165
+ device.queue.writeBuffer(styleBuffer.buffer, 0, mesh.styleData, 0, mesh.count * 44);
166
+ styleBuffer.version = mesh.styleVersion;
167
+ }
168
+ }
169
+ }
170
+ }
171
+ /**
172
+ * 为去重后的 Geometry 创建顶点、二维轮廓法线、UV、索引和参数缓冲。
173
+ * @param device 当前 WebGPU 设备
174
+ * @param scene 场景对象
175
+ * @param renderMode 当前 Render 运行模式
176
+ * @returns 无返回值
177
+ */
178
+ drawGeometryBuffers(device, scene, renderMode) {
179
+ for (const geometry of scene.geometryList) {
180
+ geometry.ensureGeometry();
181
+ const cachedGeometry = this.pipeline.buffers.geometry.get(geometry.id);
182
+ if (cachedGeometry?.version === geometry.version) continue;
183
+ if (renderMode === "development") this.developmentValidator.validateGeometry(geometry);
184
+ if (cachedGeometry !== void 0) {
185
+ this.destroyGeometryBuffer(cachedGeometry);
186
+ this.pipeline.buffers.geometry.delete(geometry.id);
187
+ }
188
+ const geometryData = geometry.geometry;
189
+ const normalData = geometry.normal;
190
+ const uvData = geometry.uv;
191
+ const indexData = geometry.index;
192
+ const vertexType = geometry.vertexType;
193
+ const position = geometry.position;
194
+ const miterScale = geometry.miterScale;
195
+ const triangleBuffer = geometryData !== void 0 && normalData !== void 0 && uvData !== void 0 && indexData !== void 0 && vertexType !== void 0 && position !== void 0 && miterScale !== void 0 && indexData.length > 0 ? this.createGeometryBufferPart(device, "Geometry " + String(geometry.id) + " Merged", {
196
+ geometry: geometryData,
197
+ normal: normalData,
198
+ uv: uvData,
199
+ index: indexData,
200
+ vertexType,
201
+ position,
202
+ miterScale
203
+ }) : void 0;
204
+ const linePointsBuffer = geometry.linePoints !== void 0 && geometry.linePoints.index.length > 0 ? this.createGeometryBufferPart(device, "Geometry " + String(geometry.id) + " Line Points", geometry.linePoints) : void 0;
205
+ if (triangleBuffer === void 0 && linePointsBuffer === void 0) continue;
206
+ const uniformBuffer = this.createBuffer(device, "Geometry " + String(geometry.id) + " Parameters Buffer", geometry.uniformData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
207
+ this.pipeline.buffers.geometry.set(geometry.id, {
208
+ geometryId: geometry.id,
209
+ version: geometry.version,
210
+ uniform: uniformBuffer,
211
+ geometry: triangleBuffer,
212
+ linePoints: linePointsBuffer
213
+ });
214
+ }
215
+ }
216
+ /**
217
+ * 创建单种几何绘制模式的顶点、二维轮廓法线、UV 和索引缓冲。
218
+ * @param device 当前 WebGPU 设备
219
+ * @param label GPU 调试标签前缀
220
+ * @param data CPU 几何数据
221
+ * @returns 已创建的几何缓冲分区
222
+ */
223
+ createGeometryBufferPart(device, label, data) {
224
+ const vertexData = new Float32Array(data.geometry);
225
+ const normalData = new Float32Array(data.normal);
226
+ const textureCoordinateData = new Float32Array(data.uv);
227
+ const elementData = data.index instanceof Uint32Array ? new Uint32Array(data.index) : new Uint16Array(data.index);
228
+ const positionData = data.position === void 0 ? void 0 : new Float32Array(data.position);
229
+ const miterScaleData = data.miterScale === void 0 ? void 0 : new Float32Array(data.miterScale);
230
+ const alignedIndexByteLength = Math.ceil(elementData.byteLength / 4) * 4;
231
+ const alignedIndexData = new Uint8Array(alignedIndexByteLength);
232
+ alignedIndexData.set(new Uint8Array(elementData.buffer));
233
+ return {
234
+ vertex: this.createBuffer(device, label + " Vertex Buffer", vertexData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
235
+ normal: this.createBuffer(device, label + " Normal Buffer", normalData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
236
+ uv: this.createBuffer(device, label + " UV Buffer", textureCoordinateData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
237
+ index: this.createBuffer(device, label + " Index Buffer", alignedIndexData, GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST),
238
+ vertexType: data.vertexType === void 0 ? void 0 : this.createBuffer(device, label + " Vertex Type Buffer", new Float32Array(data.vertexType), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
239
+ pointsFirstIndex: this.getPointsFirstIndex(data),
240
+ indexFormat: data.index instanceof Uint32Array ? "uint32" : "uint16",
241
+ position: positionData === void 0 ? void 0 : this.createBuffer(device, label + " Point Centers Buffer", positionData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),
242
+ miterScale: miterScaleData === void 0 ? void 0 : this.createBuffer(device, label + " Miter Scale Buffer", miterScaleData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST)
243
+ };
244
+ }
245
+ /**
246
+ * 获取关键点索引段起点,缓存后绘制时无需重复遍历。
247
+ * 原生 line-list 需要插在实体面与关键点之间时,复用同一个合并缓冲分段绘制。
248
+ * @param data 已按面、边框、关键点顺序合并的数据
249
+ * @returns 关键点索引段起点;没有关键点时等于总索引数
250
+ */
251
+ getPointsFirstIndex(data) {
252
+ if (data.vertexType !== void 0) {
253
+ for (let index = 0; index < data.index.length; index += 1) if (data.vertexType[data.index[index]] === 1) return index;
254
+ }
255
+ return data.index.length;
256
+ }
257
+ /**
258
+ * 销毁一个 Geometry 缓存集合中的全部已创建缓冲。
259
+ * @param geometryBuffer Geometry GPU 缓存集合
260
+ * @returns 无返回值
261
+ */
262
+ destroyGeometryBuffer(geometryBuffer) {
263
+ for (const entry of this.pipeline.buffers.meshMatrix.values()) if (entry.bindGroup?.geometry === geometryBuffer.uniform) entry.bindGroup = void 0;
264
+ const DestroyPart = (part) => {
265
+ part?.vertex.destroy();
266
+ part?.normal.destroy();
267
+ part?.uv.destroy();
268
+ part?.index.destroy();
269
+ part?.miterScale?.destroy();
270
+ part?.position?.destroy();
271
+ part?.vertexType?.destroy();
272
+ };
273
+ DestroyPart(geometryBuffer.geometry);
274
+ DestroyPart(geometryBuffer.linePoints);
275
+ geometryBuffer.uniform.destroy();
276
+ }
277
+ };
278
+ //#endregion
279
+ export { BufferManager as default };
280
+
281
+ //# sourceMappingURL=BufferManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BufferManager.js","names":[],"sources":["../../src/scripts/Render/BufferManager.ts"],"sourcesContent":["import { STYLE_STRIDE } from \"../Style\";\nimport type Camera from \"../Camera\";\nimport type { Mat3 } from \"bpmatrixjs/Math\";\nimport type { GeoPartDataLike } from \"../Geometry/Geo\";\nimport type Scene from \"../Scene\";\nimport type { Material2d } from \"../global-types\";\nimport DepthManager from \"./DepthManager\";\nimport DevelopmentValidator from \"./DevelopmentValidator\";\nimport type { GeometryBufferLike, GeometryBufferPartLike, PipelineLike, RenderMode } from \"./types\";\n\ninterface BufferManagerLike {\n draw(scene: Scene, camera: Camera, dpr: number, renderMode: RenderMode): void;\n}\n\n/**\n * 管理当前 Render 对应的 Camera、Material、Mesh 和 Geometry GPUBuffer。\n * @class\n */\nclass BufferManager implements BufferManagerLike {\n private readonly pipeline: PipelineLike;\n private readonly depthManager: DepthManager;\n private readonly developmentValidator: DevelopmentValidator;\n private _cameraSnapshot: {\n camera: Camera;\n view: Mat3;\n viewVersion: number;\n projection: Mat3;\n projectionVersion: number;\n zoom: number;\n dpr: number;\n } | undefined;\n private readonly _validatedMaterials = new WeakMap<Material2d, number>();\n\n /**\n * 创建缓冲管理器。\n * @param pipeline 当前 Render 的共享管线资源\n */\n public constructor(pipeline: PipelineLike) {\n this.pipeline = pipeline;\n this.depthManager = new DepthManager(pipeline);\n this.developmentValidator = new DevelopmentValidator();\n }\n\n /**\n * 创建或更新当前场景需要的 GPUBuffer。\n * @param scene 场景对象\n * @param camera 相机对象\n * @param dpr 当前设备像素比\n * @param renderMode 当前 Render 运行模式\n * @returns 无返回值\n */\n public draw(\n scene: Scene,\n camera: Camera,\n dpr: number,\n renderMode: RenderMode,\n ): void {\n const device: GPUDevice | undefined = this.pipeline.device;\n\n if (device === undefined) {\n return;\n }\n\n if (renderMode === \"development\") {\n this.developmentValidator.validateCamera(camera);\n }\n\n this.drawCameraBuffers(device, camera, dpr);\n this.drawGeometryBuffers(device, scene, renderMode);\n this.prepareMaterials(scene, renderMode);\n this.drawMeshBuffers(device, scene, renderMode);\n this.depthManager.prepare(scene);\n }\n\n /**\n * 按 materialList 检查材质,共享材质每个版本只检查一次。\n * 材质显示数值的 GPU 存储属于 Mesh 实例数组,不在这里重复创建一份缓冲。\n * @param scene 场景对象\n * @param renderMode production 跳过开发检查\n */\n private prepareMaterials(scene: Scene, renderMode: RenderMode): void {\n if (renderMode !== \"development\") return;\n for (const material of scene.materialList) {\n if (this._validatedMaterials.get(material) === material.version) continue;\n this.developmentValidator.validateMaterial(material);\n this._validatedMaterials.set(material, material.version);\n }\n }\n\n /**\n * 创建并写入基础 GPUBuffer。\n * @param device 当前 Render 对应的 WebGPU 设备\n * @param label GPU 调试标签\n * @param data 首次写入的缓冲数据\n * @param usage 缓冲用途标记\n * @returns 已写入数据的 GPUBuffer\n */\n private createBuffer(device: GPUDevice, label: string, data: GPUAllowSharedBufferSource, usage: GPUBufferUsageFlags): GPUBuffer {\n const buffer: GPUBuffer = device.createBuffer({\n label,\n size: data.byteLength,\n usage,\n });\n\n device.queue.writeBuffer(buffer, 0, data);\n return buffer;\n }\n\n /**\n * 按当前 Render 自己的矩阵身份和版本快照上传相机数据。\n * @param device WebGPU 设备\n * @param camera 相机对象\n * @param dpr 设备像素比\n */\n private drawCameraBuffers(device: GPUDevice, camera: Camera, dpr: number): void {\n camera.ensureCameraMatrix();\n const buffers: GPUBuffer[] = this.pipeline.buffers.cameraUniform;\n const previous = this._cameraSnapshot;\n const cameraChanged: boolean = previous?.camera !== camera;\n const viewChanged: boolean = cameraChanged || previous?.view !== camera.viewMatrix\n || previous.viewVersion !== camera.viewMatrix.version;\n const projectionChanged: boolean = cameraChanged || previous?.projection !== camera.orthogonalMatrix\n || previous.projectionVersion !== camera.orthogonalMatrix.version;\n const parametersChanged: boolean = cameraChanged || previous?.zoom !== camera.zoom || previous.dpr !== dpr;\n const created: boolean = buffers.length === 0;\n if (created) {\n buffers.push(\n this.createBuffer(device, \"Camera View Matrix Buffer\", camera.viewMatrix.GPUData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),\n this.createBuffer(device, \"Camera Orthogonal Matrix Buffer\", camera.orthogonalMatrix.GPUData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),\n this.createBuffer(device, \"Render Camera Parameters Buffer\", new Float32Array([camera.zoom, dpr, 0, 0]), GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),\n );\n } else {\n if (viewChanged) device.queue.writeBuffer(buffers[0], 0, camera.viewMatrix.GPUData);\n if (projectionChanged) device.queue.writeBuffer(buffers[1], 0, camera.orthogonalMatrix.GPUData);\n if (parametersChanged) device.queue.writeBuffer(buffers[2], 0, new Float32Array([camera.zoom, dpr, 0, 0]));\n }\n if (created || viewChanged || projectionChanged || parametersChanged) {\n this._cameraSnapshot = {\n camera, view: camera.viewMatrix, viewVersion: camera.viewMatrix.version,\n projection: camera.orthogonalMatrix, projectionVersion: camera.orthogonalMatrix.version,\n zoom: camera.zoom, dpr,\n };\n }\n }\n\n /**\n * 创建或更新每个 Mesh 的连续矩阵与样式 Storage 数组,分别对比版本。\n * @param device 当前 WebGPU 设备\n * @param scene 场景对象\n * @param renderMode 当前 Render 运行模式\n * @returns 无返回值\n */\n private drawMeshBuffers(device: GPUDevice, scene: Scene, renderMode: RenderMode): void {\n for (const mesh of scene.drawList) {\n if (renderMode === \"development\" && (mesh.geometryPending || mesh.materialPending\n || !this.pipeline.buffers.meshStyle.has(mesh.id))) {\n this.developmentValidator.validateMesh(mesh);\n }\n\n const material = mesh.material;\n if (material === undefined) continue;\n mesh.updateInstanceData();\n if (mesh.count === 0) continue;\n const limit: number = Math.min(device.limits.maxBufferSize, device.limits.maxStorageBufferBindingSize);\n if (mesh.matrixData.byteLength > limit || mesh.styleData.byteLength > limit) {\n throw new RangeError(\"Mesh \" + String(mesh.id) + \" capacity exceeds this GPUDevice storage buffer limit: \" + String(limit) + \" bytes.\");\n }\n const matrixBuffers = this.pipeline.buffers.meshMatrix;\n let matrixBuffer = matrixBuffers.get(mesh.id);\n if (matrixBuffer !== undefined && matrixBuffer.capacity !== mesh.capacity) {\n matrixBuffer.buffer.destroy();\n matrixBuffers.delete(mesh.id);\n matrixBuffer = undefined;\n }\n if (matrixBuffer === undefined) {\n matrixBuffer = {\n meshId: mesh.id, capacity: mesh.capacity, version: mesh.matrixVersion,\n buffer: this.createBuffer(device, \"Mesh \" + String(mesh.id) + \" Instance Matrices\",\n mesh.matrixData, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST),\n };\n matrixBuffers.set(mesh.id, matrixBuffer);\n } else if (matrixBuffer.version !== mesh.matrixVersion) {\n device.queue.writeBuffer(matrixBuffer.buffer, 0, mesh.matrixData, 0, mesh.count * 12);\n matrixBuffer.version = mesh.matrixVersion;\n }\n\n let styleBuffer = this.pipeline.buffers.meshStyle.get(mesh.id);\n if (styleBuffer !== undefined && styleBuffer.capacity !== mesh.capacity) {\n styleBuffer.buffer.destroy();\n this.pipeline.buffers.meshStyle.delete(mesh.id);\n styleBuffer = undefined;\n }\n if (styleBuffer === undefined) {\n this.pipeline.buffers.meshStyle.set(mesh.id, {\n meshId: mesh.id, materialId: material.id,\n capacity: mesh.capacity, version: mesh.styleVersion,\n buffer: this.createBuffer(device, \"Mesh \" + String(mesh.id) + \" Instance Styles\",\n mesh.styleData, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST),\n });\n } else {\n // 即使样式内容相同,更换材质后也要维护销毁时使用的关联 ID。\n styleBuffer.materialId = material.id;\n if (styleBuffer.version !== mesh.styleVersion) {\n device.queue.writeBuffer(styleBuffer.buffer, 0, mesh.styleData, 0, mesh.count * STYLE_STRIDE);\n styleBuffer.version = mesh.styleVersion;\n }\n }\n }\n }\n\n /**\n * 为去重后的 Geometry 创建顶点、二维轮廓法线、UV、索引和参数缓冲。\n * @param device 当前 WebGPU 设备\n * @param scene 场景对象\n * @param renderMode 当前 Render 运行模式\n * @returns 无返回值\n */\n private drawGeometryBuffers(device: GPUDevice, scene: Scene, renderMode: RenderMode): void {\n for (const geometry of scene.geometryList) {\n geometry.ensureGeometry();\n\n const cachedGeometry: GeometryBufferLike | undefined = this.pipeline.buffers.geometry.get(geometry.id);\n\n if (cachedGeometry?.version === geometry.version) {\n continue;\n }\n\n if (renderMode === \"development\") {\n this.developmentValidator.validateGeometry(geometry);\n }\n\n if (cachedGeometry !== undefined) {\n this.destroyGeometryBuffer(cachedGeometry);\n this.pipeline.buffers.geometry.delete(geometry.id);\n }\n\n const geometryData = geometry.geometry;\n const normalData = geometry.normal;\n const uvData = geometry.uv;\n const indexData = geometry.index;\n const vertexType = geometry.vertexType;\n const position = geometry.position;\n const miterScale = geometry.miterScale;\n const triangleBuffer = geometryData !== undefined\n && normalData !== undefined && uvData !== undefined && indexData !== undefined\n && vertexType !== undefined && position !== undefined && miterScale !== undefined\n && indexData.length > 0\n ? this.createGeometryBufferPart(\n device, \"Geometry \" + String(geometry.id) + \" Merged\",\n { geometry: geometryData, normal: normalData, uv: uvData, index: indexData, vertexType, position, miterScale },\n )\n : undefined;\n const linePointsBuffer = geometry.linePoints !== undefined && geometry.linePoints.index.length > 0\n ? this.createGeometryBufferPart(device, \"Geometry \" + String(geometry.id) + \" Line Points\", geometry.linePoints)\n : undefined;\n if (triangleBuffer === undefined && linePointsBuffer === undefined) {\n continue;\n }\n const uniformBuffer: GPUBuffer = this.createBuffer(device, \"Geometry \" + String(geometry.id) + \" Parameters Buffer\", geometry.uniformData, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);\n\n this.pipeline.buffers.geometry.set(geometry.id, {\n geometryId: geometry.id,\n version: geometry.version,\n uniform: uniformBuffer,\n geometry: triangleBuffer,\n linePoints: linePointsBuffer,\n });\n }\n }\n\n /**\n * 创建单种几何绘制模式的顶点、二维轮廓法线、UV 和索引缓冲。\n * @param device 当前 WebGPU 设备\n * @param label GPU 调试标签前缀\n * @param data CPU 几何数据\n * @returns 已创建的几何缓冲分区\n */\n private createGeometryBufferPart(device: GPUDevice, label: string, data: GeoPartDataLike): GeometryBufferPartLike {\n const vertexData: Float32Array<ArrayBuffer> = new Float32Array(data.geometry);\n const normalData: Float32Array<ArrayBuffer> = new Float32Array(data.normal);\n const textureCoordinateData: Float32Array<ArrayBuffer> = new Float32Array(data.uv);\n const elementData: Uint16Array<ArrayBuffer> | Uint32Array<ArrayBuffer> = data.index instanceof Uint32Array\n ? new Uint32Array(data.index)\n : new Uint16Array(data.index);\n const positionData: Float32Array<ArrayBuffer> | undefined = data.position === undefined\n ? undefined\n : new Float32Array(data.position);\n const miterScaleData: Float32Array<ArrayBuffer> | undefined = data.miterScale === undefined\n ? undefined\n : new Float32Array(data.miterScale);\n const alignedIndexByteLength: number = Math.ceil(elementData.byteLength / 4) * 4;\n const alignedIndexData: Uint8Array<ArrayBuffer> = new Uint8Array(alignedIndexByteLength);\n\n // WebGPU 写入长度必须是 4 的倍数,末尾补位不参与 drawIndexed。\n alignedIndexData.set(new Uint8Array(elementData.buffer));\n\n return {\n vertex: this.createBuffer(device, label + \" Vertex Buffer\", vertexData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n normal: this.createBuffer(device, label + \" Normal Buffer\", normalData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n uv: this.createBuffer(device, label + \" UV Buffer\", textureCoordinateData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n index: this.createBuffer(device, label + \" Index Buffer\", alignedIndexData, GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST),\n vertexType: data.vertexType === undefined\n ? undefined\n : this.createBuffer(device, label + \" Vertex Type Buffer\", new Float32Array(data.vertexType), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n pointsFirstIndex: this.getPointsFirstIndex(data),\n indexFormat: data.index instanceof Uint32Array ? \"uint32\" : \"uint16\",\n position: positionData === undefined\n ? undefined\n : this.createBuffer(device, label + \" Point Centers Buffer\", positionData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n miterScale: miterScaleData === undefined\n ? undefined\n : this.createBuffer(device, label + \" Miter Scale Buffer\", miterScaleData, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST),\n };\n }\n\n /**\n * 获取关键点索引段起点,缓存后绘制时无需重复遍历。\n * 原生 line-list 需要插在实体面与关键点之间时,复用同一个合并缓冲分段绘制。\n * @param data 已按面、边框、关键点顺序合并的数据\n * @returns 关键点索引段起点;没有关键点时等于总索引数\n */\n private getPointsFirstIndex(data: GeoPartDataLike): number {\n if (data.vertexType !== undefined) {\n for (let index: number = 0; index < data.index.length; index += 1) {\n if (data.vertexType[data.index[index]] === 1) {\n return index;\n }\n }\n }\n return data.index.length;\n }\n\n /**\n * 销毁一个 Geometry 缓存集合中的全部已创建缓冲。\n * @param geometryBuffer Geometry GPU 缓存集合\n * @returns 无返回值\n */\n private destroyGeometryBuffer(geometryBuffer: GeometryBufferLike): void {\n for (const entry of this.pipeline.buffers.meshMatrix.values()) {\n if (entry.bindGroup?.geometry === geometryBuffer.uniform) entry.bindGroup = undefined;\n }\n const DestroyPart = (part: GeometryBufferPartLike | undefined): void => {\n part?.vertex.destroy();\n part?.normal.destroy();\n part?.uv.destroy();\n part?.index.destroy();\n part?.miterScale?.destroy();\n part?.position?.destroy();\n part?.vertexType?.destroy();\n };\n\n DestroyPart(geometryBuffer.geometry);\n DestroyPart(geometryBuffer.linePoints);\n geometryBuffer.uniform.destroy();\n }\n}\n\nexport default BufferManager;\nexport type { BufferManagerLike };\n"],"mappings":";;;;;;;;AAkBA,IAAM,gBAAN,MAAiD;CAC7C;CACA;CACA;CACA;CASA,sCAAuC,IAAI,QAA4B;;;;;CAMvE,YAAmB,UAAwB;EACvC,KAAK,WAAW;EAChB,KAAK,eAAe,IAAI,aAAa,QAAQ;EAC7C,KAAK,uBAAuB,IAAI,qBAAqB;CACzD;;;;;;;;;CAUA,KACI,OACA,QACA,KACA,YACI;EACJ,MAAM,SAAgC,KAAK,SAAS;EAEpD,IAAI,WAAW,KAAA,GACX;EAGJ,IAAI,eAAe,eACf,KAAK,qBAAqB,eAAe,MAAM;EAGnD,KAAK,kBAAkB,QAAQ,QAAQ,GAAG;EAC1C,KAAK,oBAAoB,QAAQ,OAAO,UAAU;EAClD,KAAK,iBAAiB,OAAO,UAAU;EACvC,KAAK,gBAAgB,QAAQ,OAAO,UAAU;EAC9C,KAAK,aAAa,QAAQ,KAAK;CACnC;;;;;;;CAQA,iBAAyB,OAAc,YAA8B;EACjE,IAAI,eAAe,eAAe;EAClC,KAAK,MAAM,YAAY,MAAM,cAAc;GACvC,IAAI,KAAK,oBAAoB,IAAI,QAAQ,MAAM,SAAS,SAAS;GACjE,KAAK,qBAAqB,iBAAiB,QAAQ;GACnD,KAAK,oBAAoB,IAAI,UAAU,SAAS,OAAO;EAC3D;CACJ;;;;;;;;;CAUA,aAAqB,QAAmB,OAAe,MAAkC,OAAuC;EAC5H,MAAM,SAAoB,OAAO,aAAa;GAC1C;GACA,MAAM,KAAK;GACX;EACJ,CAAC;EAED,OAAO,MAAM,YAAY,QAAQ,GAAG,IAAI;EACxC,OAAO;CACX;;;;;;;CAQA,kBAA0B,QAAmB,QAAgB,KAAmB;EAC5E,OAAO,mBAAmB;EAC1B,MAAM,UAAuB,KAAK,SAAS,QAAQ;EACnD,MAAM,WAAW,KAAK;EACtB,MAAM,gBAAyB,UAAU,WAAW;EACpD,MAAM,cAAuB,iBAAiB,UAAU,SAAS,OAAO,cACjE,SAAS,gBAAgB,OAAO,WAAW;EAClD,MAAM,oBAA6B,iBAAiB,UAAU,eAAe,OAAO,oBAC7E,SAAS,sBAAsB,OAAO,iBAAiB;EAC9D,MAAM,oBAA6B,iBAAiB,UAAU,SAAS,OAAO,QAAQ,SAAS,QAAQ;EACvG,MAAM,UAAmB,QAAQ,WAAW;EAC5C,IAAI,SACA,QAAQ,KACJ,KAAK,aAAa,QAAQ,6BAA6B,OAAO,WAAW,SAAS,eAAe,UAAU,eAAe,QAAQ,GAClI,KAAK,aAAa,QAAQ,mCAAmC,OAAO,iBAAiB,SAAS,eAAe,UAAU,eAAe,QAAQ,GAC9I,KAAK,aAAa,QAAQ,mCAAmC,IAAI,aAAa;GAAC,OAAO;GAAM;GAAK;GAAG;EAAC,CAAC,GAAG,eAAe,UAAU,eAAe,QAAQ,CAC7J;OACG;GACH,IAAI,aAAa,OAAO,MAAM,YAAY,QAAQ,IAAI,GAAG,OAAO,WAAW,OAAO;GAClF,IAAI,mBAAmB,OAAO,MAAM,YAAY,QAAQ,IAAI,GAAG,OAAO,iBAAiB,OAAO;GAC9F,IAAI,mBAAmB,OAAO,MAAM,YAAY,QAAQ,IAAI,GAAG,IAAI,aAAa;IAAC,OAAO;IAAM;IAAK;IAAG;GAAC,CAAC,CAAC;EAC7G;EACA,IAAI,WAAW,eAAe,qBAAqB,mBAC/C,KAAK,kBAAkB;GACnB;GAAQ,MAAM,OAAO;GAAY,aAAa,OAAO,WAAW;GAChE,YAAY,OAAO;GAAkB,mBAAmB,OAAO,iBAAiB;GAChF,MAAM,OAAO;GAAM;EACvB;CAER;;;;;;;;CASA,gBAAwB,QAAmB,OAAc,YAA8B;EACnF,KAAK,MAAM,QAAQ,MAAM,UAAU;GAC/B,IAAI,eAAe,kBAAkB,KAAK,mBAAmB,KAAK,mBAC3D,CAAC,KAAK,SAAS,QAAQ,UAAU,IAAI,KAAK,EAAE,IAC/C,KAAK,qBAAqB,aAAa,IAAI;GAG/C,MAAM,WAAW,KAAK;GACtB,IAAI,aAAa,KAAA,GAAW;GAC5B,KAAK,mBAAmB;GACxB,IAAI,KAAK,UAAU,GAAG;GACtB,MAAM,QAAgB,KAAK,IAAI,OAAO,OAAO,eAAe,OAAO,OAAO,2BAA2B;GACrG,IAAI,KAAK,WAAW,aAAa,SAAS,KAAK,UAAU,aAAa,OAClE,MAAM,IAAI,WAAW,UAAU,OAAO,KAAK,EAAE,IAAI,4DAA4D,OAAO,KAAK,IAAI,SAAS;GAE1I,MAAM,gBAAgB,KAAK,SAAS,QAAQ;GAC5C,IAAI,eAAe,cAAc,IAAI,KAAK,EAAE;GAC5C,IAAI,iBAAiB,KAAA,KAAa,aAAa,aAAa,KAAK,UAAU;IACvE,aAAa,OAAO,QAAQ;IAC5B,cAAc,OAAO,KAAK,EAAE;IAC5B,eAAe,KAAA;GACnB;GACA,IAAI,iBAAiB,KAAA,GAAW;IAC5B,eAAe;KACX,QAAQ,KAAK;KAAI,UAAU,KAAK;KAAU,SAAS,KAAK;KACxD,QAAQ,KAAK,aAAa,QAAQ,UAAU,OAAO,KAAK,EAAE,IAAI,sBAC1D,KAAK,YAAY,eAAe,UAAU,eAAe,QAAQ;IACzE;IACA,cAAc,IAAI,KAAK,IAAI,YAAY;GAC3C,OAAO,IAAI,aAAa,YAAY,KAAK,eAAe;IACpD,OAAO,MAAM,YAAY,aAAa,QAAQ,GAAG,KAAK,YAAY,GAAG,KAAK,QAAQ,EAAE;IACpF,aAAa,UAAU,KAAK;GAChC;GAEA,IAAI,cAAc,KAAK,SAAS,QAAQ,UAAU,IAAI,KAAK,EAAE;GAC7D,IAAI,gBAAgB,KAAA,KAAa,YAAY,aAAa,KAAK,UAAU;IACrE,YAAY,OAAO,QAAQ;IAC3B,KAAK,SAAS,QAAQ,UAAU,OAAO,KAAK,EAAE;IAC9C,cAAc,KAAA;GAClB;GACA,IAAI,gBAAgB,KAAA,GAChB,KAAK,SAAS,QAAQ,UAAU,IAAI,KAAK,IAAI;IACzC,QAAQ,KAAK;IAAI,YAAY,SAAS;IACtC,UAAU,KAAK;IAAU,SAAS,KAAK;IACvC,QAAQ,KAAK,aAAa,QAAQ,UAAU,OAAO,KAAK,EAAE,IAAI,oBAC1D,KAAK,WAAW,eAAe,UAAU,eAAe,QAAQ;GACxE,CAAC;QACE;IAEH,YAAY,aAAa,SAAS;IAClC,IAAI,YAAY,YAAY,KAAK,cAAc;KAC3C,OAAO,MAAM,YAAY,YAAY,QAAQ,GAAG,KAAK,WAAW,GAAG,KAAK,QAAA,EAAoB;KAC5F,YAAY,UAAU,KAAK;IAC/B;GACJ;EACJ;CACJ;;;;;;;;CASA,oBAA4B,QAAmB,OAAc,YAA8B;EACvF,KAAK,MAAM,YAAY,MAAM,cAAc;GACvC,SAAS,eAAe;GAExB,MAAM,iBAAiD,KAAK,SAAS,QAAQ,SAAS,IAAI,SAAS,EAAE;GAErG,IAAI,gBAAgB,YAAY,SAAS,SACrC;GAGJ,IAAI,eAAe,eACf,KAAK,qBAAqB,iBAAiB,QAAQ;GAGvD,IAAI,mBAAmB,KAAA,GAAW;IAC9B,KAAK,sBAAsB,cAAc;IACzC,KAAK,SAAS,QAAQ,SAAS,OAAO,SAAS,EAAE;GACrD;GAEA,MAAM,eAAe,SAAS;GAC9B,MAAM,aAAa,SAAS;GAC5B,MAAM,SAAS,SAAS;GACxB,MAAM,YAAY,SAAS;GAC3B,MAAM,aAAa,SAAS;GAC5B,MAAM,WAAW,SAAS;GAC1B,MAAM,aAAa,SAAS;GAC5B,MAAM,iBAAiB,iBAAiB,KAAA,KACjC,eAAe,KAAA,KAAa,WAAW,KAAA,KAAa,cAAc,KAAA,KAClE,eAAe,KAAA,KAAa,aAAa,KAAA,KAAa,eAAe,KAAA,KACrE,UAAU,SAAS,IACpB,KAAK,yBACH,QAAQ,cAAc,OAAO,SAAS,EAAE,IAAI,WAC5C;IAAE,UAAU;IAAc,QAAQ;IAAY,IAAI;IAAQ,OAAO;IAAW;IAAY;IAAU;GAAW,CACjH,IACE,KAAA;GACN,MAAM,mBAAmB,SAAS,eAAe,KAAA,KAAa,SAAS,WAAW,MAAM,SAAS,IAC3F,KAAK,yBAAyB,QAAQ,cAAc,OAAO,SAAS,EAAE,IAAI,gBAAgB,SAAS,UAAU,IAC7G,KAAA;GACN,IAAI,mBAAmB,KAAA,KAAa,qBAAqB,KAAA,GACrD;GAEJ,MAAM,gBAA2B,KAAK,aAAa,QAAQ,cAAc,OAAO,SAAS,EAAE,IAAI,sBAAsB,SAAS,aAAa,eAAe,UAAU,eAAe,QAAQ;GAE3L,KAAK,SAAS,QAAQ,SAAS,IAAI,SAAS,IAAI;IAC5C,YAAY,SAAS;IACrB,SAAS,SAAS;IAClB,SAAS;IACT,UAAU;IACV,YAAY;GAChB,CAAC;EACL;CACJ;;;;;;;;CASA,yBAAiC,QAAmB,OAAe,MAA+C;EAC9G,MAAM,aAAwC,IAAI,aAAa,KAAK,QAAQ;EAC5E,MAAM,aAAwC,IAAI,aAAa,KAAK,MAAM;EAC1E,MAAM,wBAAmD,IAAI,aAAa,KAAK,EAAE;EACjF,MAAM,cAAmE,KAAK,iBAAiB,cACzF,IAAI,YAAY,KAAK,KAAK,IAC1B,IAAI,YAAY,KAAK,KAAK;EAChC,MAAM,eAAsD,KAAK,aAAa,KAAA,IACxE,KAAA,IACA,IAAI,aAAa,KAAK,QAAQ;EACpC,MAAM,iBAAwD,KAAK,eAAe,KAAA,IAC5E,KAAA,IACA,IAAI,aAAa,KAAK,UAAU;EACtC,MAAM,yBAAiC,KAAK,KAAK,YAAY,aAAa,CAAC,IAAI;EAC/E,MAAM,mBAA4C,IAAI,WAAW,sBAAsB;EAGvF,iBAAiB,IAAI,IAAI,WAAW,YAAY,MAAM,CAAC;EAEvD,OAAO;GACH,QAAQ,KAAK,aAAa,QAAQ,QAAQ,kBAAkB,YAAY,eAAe,SAAS,eAAe,QAAQ;GACvH,QAAQ,KAAK,aAAa,QAAQ,QAAQ,kBAAkB,YAAY,eAAe,SAAS,eAAe,QAAQ;GACvH,IAAI,KAAK,aAAa,QAAQ,QAAQ,cAAc,uBAAuB,eAAe,SAAS,eAAe,QAAQ;GAC1H,OAAO,KAAK,aAAa,QAAQ,QAAQ,iBAAiB,kBAAkB,eAAe,QAAQ,eAAe,QAAQ;GAC1H,YAAY,KAAK,eAAe,KAAA,IAC1B,KAAA,IACA,KAAK,aAAa,QAAQ,QAAQ,uBAAuB,IAAI,aAAa,KAAK,UAAU,GAAG,eAAe,SAAS,eAAe,QAAQ;GACjJ,kBAAkB,KAAK,oBAAoB,IAAI;GAC/C,aAAa,KAAK,iBAAiB,cAAc,WAAW;GAC5D,UAAU,iBAAiB,KAAA,IACrB,KAAA,IACA,KAAK,aAAa,QAAQ,QAAQ,yBAAyB,cAAc,eAAe,SAAS,eAAe,QAAQ;GAC9H,YAAY,mBAAmB,KAAA,IACzB,KAAA,IACA,KAAK,aAAa,QAAQ,QAAQ,uBAAuB,gBAAgB,eAAe,SAAS,eAAe,QAAQ;EAClI;CACJ;;;;;;;CAQA,oBAA4B,MAA+B;EACvD,IAAI,KAAK,eAAe,KAAA,GACf;QAAA,IAAI,QAAgB,GAAG,QAAQ,KAAK,MAAM,QAAQ,SAAS,GAC5D,IAAI,KAAK,WAAW,KAAK,MAAM,YAAY,GACvC,OAAO;EAAA;EAInB,OAAO,KAAK,MAAM;CACtB;;;;;;CAOA,sBAA8B,gBAA0C;EACpE,KAAK,MAAM,SAAS,KAAK,SAAS,QAAQ,WAAW,OAAO,GACxD,IAAI,MAAM,WAAW,aAAa,eAAe,SAAS,MAAM,YAAY,KAAA;EAEhF,MAAM,eAAe,SAAmD;GACpE,MAAM,OAAO,QAAQ;GACrB,MAAM,OAAO,QAAQ;GACrB,MAAM,GAAG,QAAQ;GACjB,MAAM,MAAM,QAAQ;GACpB,MAAM,YAAY,QAAQ;GAC1B,MAAM,UAAU,QAAQ;GACxB,MAAM,YAAY,QAAQ;EAC9B;EAEA,YAAY,eAAe,QAAQ;EACnC,YAAY,eAAe,UAAU;EACrC,eAAe,QAAQ,QAAQ;CACnC;AACJ"}
@@ -0,0 +1,22 @@
1
+ import type Scene from "../Scene";
2
+ import type { DepthTextureLike, PipelineLike } from "./types";
3
+ /** 深度纹理和每个 Mesh 的绘制参数均属于当前 Render,不写入共享 CPU 样式。 */
4
+ declare class DepthManager {
5
+ private readonly pipeline;
6
+ /** @param pipeline 当前 Render 的 GPU 资源 */
7
+ constructor(pipeline: PipelineLike);
8
+ /**
9
+ * 按原始排序分配层级,反向提交只改变访问方向,不重新定义谁在上面。
10
+ * 每个 Mesh 仅上传四个 u32:全局起点、条数、是否反读、补位。
11
+ * @param scene 已准备 drawList 的场景
12
+ */
13
+ prepare(scene: Scene): void;
14
+ /**
15
+ * 复用与颜色附件同尺寸的深度纹理,实际像素尺寸变化才重建。
16
+ * @param width 画布物理像素宽度,不是 CSS 宽度
17
+ * @param height 画布物理像素高度
18
+ * @returns 深度附件,设备尚未初始化时为 undefined
19
+ */
20
+ ensureTexture(width: number, height: number): DepthTextureLike | undefined;
21
+ }
22
+ export default DepthManager;
@@ -0,0 +1,95 @@
1
+ //#region src/scripts/Render/DepthManager.ts
2
+ /** 以 24 位整数层级生成精确可表示的 f32 深度,避免相邻对象因舍入获得相同深度。 */
3
+ var DEPTH_LEVELS = 16777216;
4
+ /** 深度纹理和每个 Mesh 的绘制参数均属于当前 Render,不写入共享 CPU 样式。 */
5
+ var DepthManager = class {
6
+ pipeline;
7
+ /** @param pipeline 当前 Render 的 GPU 资源 */
8
+ constructor(pipeline) {
9
+ this.pipeline = pipeline;
10
+ }
11
+ /**
12
+ * 按原始排序分配层级,反向提交只改变访问方向,不重新定义谁在上面。
13
+ * 每个 Mesh 仅上传四个 u32:全局起点、条数、是否反读、补位。
14
+ * @param scene 已准备 drawList 的场景
15
+ */
16
+ prepare(scene) {
17
+ const device = this.pipeline.device;
18
+ if (device === void 0) return;
19
+ let total = 0;
20
+ for (const mesh of scene.drawList) total += mesh.count;
21
+ if (!Number.isSafeInteger(total) || total >= DEPTH_LEVELS) throw new RangeError("Scene exceeds 16777215 distinct depth levels.");
22
+ let base = 0;
23
+ for (const mesh of scene.drawList) {
24
+ const material = mesh.material;
25
+ const count = mesh.count;
26
+ if (count > 0 && material !== void 0) {
27
+ const reverse = Number(material.depthTest && material.depthWrite && !material.transparent);
28
+ let cached = this.pipeline.buffers.meshDepth.get(mesh.id);
29
+ if (cached === void 0) {
30
+ const data = new Uint32Array([
31
+ base,
32
+ count,
33
+ reverse,
34
+ 0
35
+ ]);
36
+ const buffer = device.createBuffer({
37
+ label: "Mesh " + String(mesh.id) + " Depth Parameters",
38
+ size: 16,
39
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
40
+ });
41
+ device.queue.writeBuffer(buffer, 0, data);
42
+ cached = {
43
+ meshId: mesh.id,
44
+ buffer,
45
+ data
46
+ };
47
+ this.pipeline.buffers.meshDepth.set(mesh.id, cached);
48
+ } else if (cached.data[0] !== base || cached.data[1] !== count || cached.data[2] !== reverse) {
49
+ cached.data.set([
50
+ base,
51
+ count,
52
+ reverse,
53
+ 0
54
+ ]);
55
+ device.queue.writeBuffer(cached.buffer, 0, cached.data);
56
+ }
57
+ }
58
+ base += count;
59
+ }
60
+ }
61
+ /**
62
+ * 复用与颜色附件同尺寸的深度纹理,实际像素尺寸变化才重建。
63
+ * @param width 画布物理像素宽度,不是 CSS 宽度
64
+ * @param height 画布物理像素高度
65
+ * @returns 深度附件,设备尚未初始化时为 undefined
66
+ */
67
+ ensureTexture(width, height) {
68
+ const device = this.pipeline.device;
69
+ if (device === void 0) return void 0;
70
+ const cached = this.pipeline.depthTexture;
71
+ if (cached?.width === width && cached.height === height) return cached;
72
+ const texture = device.createTexture({
73
+ label: "Render Depth Texture",
74
+ size: {
75
+ width,
76
+ height
77
+ },
78
+ format: "depth32float",
79
+ usage: GPUTextureUsage.RENDER_ATTACHMENT
80
+ });
81
+ const resource = {
82
+ texture,
83
+ view: texture.createView(),
84
+ width,
85
+ height
86
+ };
87
+ cached?.texture.destroy();
88
+ this.pipeline.depthTexture = resource;
89
+ return resource;
90
+ }
91
+ };
92
+ //#endregion
93
+ export { DepthManager as default };
94
+
95
+ //# sourceMappingURL=DepthManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DepthManager.js","names":[],"sources":["../../src/scripts/Render/DepthManager.ts"],"sourcesContent":["import type Scene from \"../Scene\";\nimport type { DepthTextureLike, PipelineLike } from \"./types\";\n\n/** 以 24 位整数层级生成精确可表示的 f32 深度,避免相邻对象因舍入获得相同深度。 */\nconst DEPTH_LEVELS: number = 16777216;\n\n/** 深度纹理和每个 Mesh 的绘制参数均属于当前 Render,不写入共享 CPU 样式。 */\nclass DepthManager {\n private readonly pipeline: PipelineLike;\n\n /** @param pipeline 当前 Render 的 GPU 资源 */\n public constructor(pipeline: PipelineLike) { this.pipeline = pipeline; }\n\n /**\n * 按原始排序分配层级,反向提交只改变访问方向,不重新定义谁在上面。\n * 每个 Mesh 仅上传四个 u32:全局起点、条数、是否反读、补位。\n * @param scene 已准备 drawList 的场景\n */\n public prepare(scene: Scene): void {\n const device = this.pipeline.device;\n if (device === undefined) return;\n let total: number = 0;\n for (const mesh of scene.drawList) total += mesh.count;\n if (!Number.isSafeInteger(total) || total >= DEPTH_LEVELS) {\n throw new RangeError(\"Scene exceeds 16777215 distinct depth levels.\");\n }\n let base: number = 0;\n for (const mesh of scene.drawList) {\n const material = mesh.material;\n const count: number = mesh.count;\n if (count > 0 && material !== undefined) {\n const reverse: number = Number(material.depthTest && material.depthWrite && !material.transparent);\n let cached = this.pipeline.buffers.meshDepth.get(mesh.id);\n if (cached === undefined) {\n const data: Uint32Array<ArrayBuffer> = new Uint32Array([base, count, reverse, 0]);\n const buffer = device.createBuffer({\n label: \"Mesh \" + String(mesh.id) + \" Depth Parameters\", size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(buffer, 0, data);\n cached = { meshId: mesh.id, buffer, data };\n this.pipeline.buffers.meshDepth.set(mesh.id, cached);\n } else if (cached.data[0] !== base || cached.data[1] !== count || cached.data[2] !== reverse) {\n cached.data.set([base, count, reverse, 0]);\n device.queue.writeBuffer(cached.buffer, 0, cached.data);\n }\n }\n base += count;\n }\n }\n\n /**\n * 复用与颜色附件同尺寸的深度纹理,实际像素尺寸变化才重建。\n * @param width 画布物理像素宽度,不是 CSS 宽度\n * @param height 画布物理像素高度\n * @returns 深度附件,设备尚未初始化时为 undefined\n */\n public ensureTexture(width: number, height: number): DepthTextureLike | undefined {\n const device = this.pipeline.device;\n if (device === undefined) return undefined;\n const cached = this.pipeline.depthTexture;\n if (cached?.width === width && cached.height === height) return cached;\n const texture = device.createTexture({\n label: \"Render Depth Texture\", size: { width, height },\n format: \"depth32float\", usage: GPUTextureUsage.RENDER_ATTACHMENT,\n });\n const resource: DepthTextureLike = { texture, view: texture.createView(), width, height };\n cached?.texture.destroy();\n this.pipeline.depthTexture = resource;\n return resource;\n }\n}\n\nexport default DepthManager;\n"],"mappings":";;AAIA,IAAM,eAAuB;;AAG7B,IAAM,eAAN,MAAmB;CACf;;CAGA,YAAmB,UAAwB;EAAE,KAAK,WAAW;CAAU;;;;;;CAOvE,QAAe,OAAoB;EAC/B,MAAM,SAAS,KAAK,SAAS;EAC7B,IAAI,WAAW,KAAA,GAAW;EAC1B,IAAI,QAAgB;EACpB,KAAK,MAAM,QAAQ,MAAM,UAAU,SAAS,KAAK;EACjD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,cACzC,MAAM,IAAI,WAAW,+CAA+C;EAExE,IAAI,OAAe;EACnB,KAAK,MAAM,QAAQ,MAAM,UAAU;GAC/B,MAAM,WAAW,KAAK;GACtB,MAAM,QAAgB,KAAK;GAC3B,IAAI,QAAQ,KAAK,aAAa,KAAA,GAAW;IACrC,MAAM,UAAkB,OAAO,SAAS,aAAa,SAAS,cAAc,CAAC,SAAS,WAAW;IACjG,IAAI,SAAS,KAAK,SAAS,QAAQ,UAAU,IAAI,KAAK,EAAE;IACxD,IAAI,WAAW,KAAA,GAAW;KACtB,MAAM,OAAiC,IAAI,YAAY;MAAC;MAAM;MAAO;MAAS;KAAC,CAAC;KAChF,MAAM,SAAS,OAAO,aAAa;MAC/B,OAAO,UAAU,OAAO,KAAK,EAAE,IAAI;MAAqB,MAAM;MAC9D,OAAO,eAAe,UAAU,eAAe;KACnD,CAAC;KACD,OAAO,MAAM,YAAY,QAAQ,GAAG,IAAI;KACxC,SAAS;MAAE,QAAQ,KAAK;MAAI;MAAQ;KAAK;KACzC,KAAK,SAAS,QAAQ,UAAU,IAAI,KAAK,IAAI,MAAM;IACvD,OAAO,IAAI,OAAO,KAAK,OAAO,QAAQ,OAAO,KAAK,OAAO,SAAS,OAAO,KAAK,OAAO,SAAS;KAC1F,OAAO,KAAK,IAAI;MAAC;MAAM;MAAO;MAAS;KAAC,CAAC;KACzC,OAAO,MAAM,YAAY,OAAO,QAAQ,GAAG,OAAO,IAAI;IAC1D;GACJ;GACA,QAAQ;EACZ;CACJ;;;;;;;CAQA,cAAqB,OAAe,QAA8C;EAC9E,MAAM,SAAS,KAAK,SAAS;EAC7B,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,MAAM,SAAS,KAAK,SAAS;EAC7B,IAAI,QAAQ,UAAU,SAAS,OAAO,WAAW,QAAQ,OAAO;EAChE,MAAM,UAAU,OAAO,cAAc;GACjC,OAAO;GAAwB,MAAM;IAAE;IAAO;GAAO;GACrD,QAAQ;GAAgB,OAAO,gBAAgB;EACnD,CAAC;EACD,MAAM,WAA6B;GAAE;GAAS,MAAM,QAAQ,WAAW;GAAG;GAAO;EAAO;EACxF,QAAQ,QAAQ,QAAQ;EACxB,KAAK,SAAS,eAAe;EAC7B,OAAO;CACX;AACJ"}
@@ -0,0 +1,74 @@
1
+ import type { GeoData } from "../Geometry";
2
+ import type { Material2d } from "../global-types";
3
+ import type { MeshLike } from "../Mesh";
4
+ import type Scene from "../Scene";
5
+ import type { TextureResource } from "../Texture/Layers";
6
+ import type { PipelineLike } from "./types";
7
+ interface DestroyManagerLike {
8
+ destroyMesh(mesh: MeshLike | number): boolean;
9
+ destroyTexture(texture: TextureResource | number): boolean;
10
+ destroyMaterial(material: Material2d | number): boolean;
11
+ destroyGeometry(geometry: GeoData | number): boolean;
12
+ trim(scene: Scene): void;
13
+ destroyAll(): void;
14
+ }
15
+ /**
16
+ * 统一负责当前 Render 的 GPU 资源销毁与无引用缓存回收。
17
+ * @class
18
+ */
19
+ declare class DestroyManager implements DestroyManagerLike {
20
+ private readonly pipeline;
21
+ /**
22
+ * 创建销毁管理器。
23
+ * @param pipeline 当前 Render 的共享管线资源
24
+ */
25
+ constructor(pipeline: PipelineLike);
26
+ /**
27
+ * 销毁指定 Mesh 的模型矩阵缓冲及可取得的关联资源。
28
+ * @param mesh Mesh 对象或全局 ID
29
+ * @returns 是否销毁了任意资源
30
+ */
31
+ destroyMesh(mesh: MeshLike | number): boolean;
32
+ /**
33
+ * 销毁指定 Texture 的 GPUTexture 缓存。
34
+ * @param texture Texture 对象或全局 ID
35
+ * @returns 是否找到并销毁了对应资源
36
+ */
37
+ destroyTexture(texture: TextureResource | number): boolean;
38
+ /**
39
+ * 销毁所有关联此 Material 的 Mesh 实例样式缓冲,并在可取得对象时销毁其基础、边框和点型贴图。
40
+ * @param material Material 对象或全局 ID
41
+ * @returns 是否销毁了任意资源
42
+ */
43
+ destroyMaterial(material: Material2d | number): boolean;
44
+ /**
45
+ * 销毁指定 Geometry 的全部 GPUBuffer。
46
+ * @param geometry Geometry 对象或全局 ID
47
+ * @returns 是否找到并销毁了对应资源
48
+ */
49
+ destroyGeometry(geometry: GeoData | number): boolean;
50
+ /**
51
+ * 更新场景资源使用记录并回收所有场景均未引用的缓存。
52
+ * @param scene 需要同步资源记录的场景
53
+ * @returns 无返回值
54
+ */
55
+ trim(scene: Scene): void;
56
+ /**
57
+ * 销毁当前 Render 持有的全部 WebGPU 资源和设备。
58
+ * @returns 无返回值
59
+ */
60
+ destroyAll(): void;
61
+ /**
62
+ * 销毁 Geometry 所有绘制模式已经创建的全部缓冲。
63
+ * @param geometryBuffer Geometry GPU 缓存集合
64
+ * @returns 无返回值
65
+ */
66
+ private destroyGeometryBuffer;
67
+ /**
68
+ * 解除引用某个纹理视图的缓存绑定,不影响其他 Mesh。
69
+ * @param view 即将销毁的 GPU 纹理视图
70
+ */
71
+ private releaseTextureBindings;
72
+ }
73
+ export default DestroyManager;
74
+ export type { DestroyManagerLike };