topazcube 0.1.31 → 0.1.35

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 (103) hide show
  1. package/LICENSE.txt +0 -0
  2. package/README.md +0 -0
  3. package/dist/Renderer.cjs +20844 -0
  4. package/dist/Renderer.cjs.map +1 -0
  5. package/dist/Renderer.js +20827 -0
  6. package/dist/Renderer.js.map +1 -0
  7. package/dist/client.cjs +91 -260
  8. package/dist/client.cjs.map +1 -1
  9. package/dist/client.js +68 -215
  10. package/dist/client.js.map +1 -1
  11. package/dist/server.cjs +165 -432
  12. package/dist/server.cjs.map +1 -1
  13. package/dist/server.js +117 -370
  14. package/dist/server.js.map +1 -1
  15. package/dist/terminal.cjs +113 -200
  16. package/dist/terminal.cjs.map +1 -1
  17. package/dist/terminal.js +50 -51
  18. package/dist/terminal.js.map +1 -1
  19. package/dist/utils-CRhi1BDa.cjs +259 -0
  20. package/dist/utils-CRhi1BDa.cjs.map +1 -0
  21. package/dist/utils-D7tXt6-2.js +260 -0
  22. package/dist/utils-D7tXt6-2.js.map +1 -0
  23. package/package.json +19 -15
  24. package/src/{client.ts → network/client.js} +170 -403
  25. package/src/{compress-browser.ts → network/compress-browser.js} +2 -4
  26. package/src/{compress-node.ts → network/compress-node.js} +8 -14
  27. package/src/{server.ts → network/server.js} +229 -317
  28. package/src/{terminal.js → network/terminal.js} +0 -0
  29. package/src/{topazcube.ts → network/topazcube.js} +2 -2
  30. package/src/network/utils.js +375 -0
  31. package/src/renderer/Camera.js +191 -0
  32. package/src/renderer/DebugUI.js +703 -0
  33. package/src/renderer/Geometry.js +1049 -0
  34. package/src/renderer/Material.js +64 -0
  35. package/src/renderer/Mesh.js +211 -0
  36. package/src/renderer/Node.js +112 -0
  37. package/src/renderer/Pipeline.js +645 -0
  38. package/src/renderer/Renderer.js +1496 -0
  39. package/src/renderer/Skin.js +792 -0
  40. package/src/renderer/Texture.js +584 -0
  41. package/src/renderer/core/AssetManager.js +394 -0
  42. package/src/renderer/core/CullingSystem.js +308 -0
  43. package/src/renderer/core/EntityManager.js +541 -0
  44. package/src/renderer/core/InstanceManager.js +343 -0
  45. package/src/renderer/core/ParticleEmitter.js +358 -0
  46. package/src/renderer/core/ParticleSystem.js +564 -0
  47. package/src/renderer/core/SpriteSystem.js +349 -0
  48. package/src/renderer/gltf.js +563 -0
  49. package/src/renderer/math.js +161 -0
  50. package/src/renderer/rendering/HistoryBufferManager.js +333 -0
  51. package/src/renderer/rendering/ProbeCapture.js +1495 -0
  52. package/src/renderer/rendering/ReflectionProbeManager.js +352 -0
  53. package/src/renderer/rendering/RenderGraph.js +2258 -0
  54. package/src/renderer/rendering/passes/AOPass.js +308 -0
  55. package/src/renderer/rendering/passes/AmbientCapturePass.js +593 -0
  56. package/src/renderer/rendering/passes/BasePass.js +101 -0
  57. package/src/renderer/rendering/passes/BloomPass.js +420 -0
  58. package/src/renderer/rendering/passes/CRTPass.js +724 -0
  59. package/src/renderer/rendering/passes/FogPass.js +445 -0
  60. package/src/renderer/rendering/passes/GBufferPass.js +730 -0
  61. package/src/renderer/rendering/passes/HiZPass.js +744 -0
  62. package/src/renderer/rendering/passes/LightingPass.js +753 -0
  63. package/src/renderer/rendering/passes/ParticlePass.js +841 -0
  64. package/src/renderer/rendering/passes/PlanarReflectionPass.js +456 -0
  65. package/src/renderer/rendering/passes/PostProcessPass.js +405 -0
  66. package/src/renderer/rendering/passes/ReflectionPass.js +157 -0
  67. package/src/renderer/rendering/passes/RenderPostPass.js +364 -0
  68. package/src/renderer/rendering/passes/SSGIPass.js +266 -0
  69. package/src/renderer/rendering/passes/SSGITilePass.js +305 -0
  70. package/src/renderer/rendering/passes/ShadowPass.js +2072 -0
  71. package/src/renderer/rendering/passes/TransparentPass.js +831 -0
  72. package/src/renderer/rendering/passes/VolumetricFogPass.js +715 -0
  73. package/src/renderer/rendering/shaders/ao.wgsl +182 -0
  74. package/src/renderer/rendering/shaders/bloom.wgsl +97 -0
  75. package/src/renderer/rendering/shaders/bloom_blur.wgsl +80 -0
  76. package/src/renderer/rendering/shaders/crt.wgsl +455 -0
  77. package/src/renderer/rendering/shaders/depth_copy.wgsl +17 -0
  78. package/src/renderer/rendering/shaders/geometry.wgsl +580 -0
  79. package/src/renderer/rendering/shaders/hiz_reduce.wgsl +114 -0
  80. package/src/renderer/rendering/shaders/light_culling.wgsl +204 -0
  81. package/src/renderer/rendering/shaders/lighting.wgsl +932 -0
  82. package/src/renderer/rendering/shaders/lighting_common.wgsl +143 -0
  83. package/src/renderer/rendering/shaders/particle_render.wgsl +672 -0
  84. package/src/renderer/rendering/shaders/particle_simulate.wgsl +440 -0
  85. package/src/renderer/rendering/shaders/postproc.wgsl +293 -0
  86. package/src/renderer/rendering/shaders/render_post.wgsl +289 -0
  87. package/src/renderer/rendering/shaders/shadow.wgsl +117 -0
  88. package/src/renderer/rendering/shaders/ssgi.wgsl +266 -0
  89. package/src/renderer/rendering/shaders/ssgi_accumulate.wgsl +114 -0
  90. package/src/renderer/rendering/shaders/ssgi_propagate.wgsl +132 -0
  91. package/src/renderer/rendering/shaders/volumetric_blur.wgsl +80 -0
  92. package/src/renderer/rendering/shaders/volumetric_composite.wgsl +80 -0
  93. package/src/renderer/rendering/shaders/volumetric_raymarch.wgsl +634 -0
  94. package/src/renderer/utils/BoundingSphere.js +439 -0
  95. package/src/renderer/utils/Frustum.js +281 -0
  96. package/src/renderer/utils/Raycaster.js +761 -0
  97. package/dist/client.d.cts +0 -211
  98. package/dist/client.d.ts +0 -211
  99. package/dist/server.d.cts +0 -120
  100. package/dist/server.d.ts +0 -120
  101. package/dist/terminal.d.cts +0 -64
  102. package/dist/terminal.d.ts +0 -64
  103. package/src/utils.ts +0 -403
@@ -0,0 +1,305 @@
1
+ import { BasePass } from "./BasePass.js"
2
+
3
+ import ssgiAccumulateWGSL from "../shaders/ssgi_accumulate.wgsl"
4
+ import ssgiPropagateWGSL from "../shaders/ssgi_propagate.wgsl"
5
+
6
+ /**
7
+ * SSGITilePass - Two-pass tile-based light propagation
8
+ *
9
+ * Pass 1 (Accumulate): For each tile, average the light content from prev HDR + boosted emissive
10
+ * Pass 2 (Propagate): For each tile, collect indirect light from all other tiles in 4 directions
11
+ *
12
+ * Input: Previous frame HDR, GBuffer emissive
13
+ * Output: Propagated directional light buffer (4 directions per tile)
14
+ */
15
+
16
+ const TILE_SIZE = 64
17
+
18
+ class SSGITilePass extends BasePass {
19
+ constructor(engine = null) {
20
+ super('SSGITile', engine)
21
+
22
+ // Compute pipelines
23
+ this.accumulatePipeline = null
24
+ this.propagatePipeline = null
25
+
26
+ // Bind group layouts
27
+ this.accumulateBGL = null
28
+ this.propagateBGL = null
29
+
30
+ // Buffers
31
+ this.tileAccumBuffer = null // Accumulated light per tile (vec4f per tile)
32
+ this.tilePropagateBuffer = null // Propagated directional light (4 directions per tile)
33
+
34
+ // Tile grid dimensions
35
+ this.tileCountX = 0
36
+ this.tileCountY = 0
37
+
38
+ // Stored render dimensions (from resize)
39
+ this.renderWidth = 0
40
+ this.renderHeight = 0
41
+
42
+ // Input textures
43
+ this.prevHDRTexture = null
44
+ this.emissiveTexture = null
45
+
46
+ // Uniform buffer
47
+ this.uniformBuffer = null
48
+
49
+ // Sampler for HDR texture
50
+ this.sampler = null
51
+ }
52
+
53
+ /**
54
+ * Set the previous frame HDR texture
55
+ */
56
+ setPrevHDRTexture(texture) {
57
+ this.prevHDRTexture = texture
58
+ }
59
+
60
+ /**
61
+ * Set the emissive texture from GBuffer
62
+ */
63
+ setEmissiveTexture(texture) {
64
+ this.emissiveTexture = texture
65
+ }
66
+
67
+ async _init() {
68
+ const { device, canvas } = this.engine
69
+
70
+ this.sampler = device.createSampler({
71
+ label: 'SSGI Tile Sampler',
72
+ minFilter: 'linear',
73
+ magFilter: 'linear',
74
+ })
75
+
76
+ await this._createResources(canvas.width, canvas.height)
77
+ }
78
+
79
+ async _createResources(width, height) {
80
+ const { device } = this.engine
81
+
82
+ // Store render dimensions for use in _execute
83
+ this.renderWidth = width
84
+ this.renderHeight = height
85
+
86
+ // Calculate tile grid dimensions
87
+ this.tileCountX = Math.ceil(width / TILE_SIZE)
88
+ this.tileCountY = Math.ceil(height / TILE_SIZE)
89
+ const totalTiles = this.tileCountX * this.tileCountY
90
+
91
+ // Destroy old buffers
92
+ if (this.tileAccumBuffer) this.tileAccumBuffer.destroy()
93
+ if (this.tilePropagateBuffer) this.tilePropagateBuffer.destroy()
94
+ if (this.uniformBuffer) this.uniformBuffer.destroy()
95
+
96
+ // Create tile accumulation buffer (1 vec4f per tile - RGB + weight)
97
+ this.tileAccumBuffer = device.createBuffer({
98
+ label: 'SSGI Tile Accum Buffer',
99
+ size: totalTiles * 4 * 4, // tiles × 4 floats × 4 bytes
100
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
101
+ })
102
+
103
+ // Create propagated light buffer (4 directions per tile × vec4f)
104
+ // Directions: 0=left, 1=right, 2=up, 3=down
105
+ this.tilePropagateBuffer = device.createBuffer({
106
+ label: 'SSGI Tile Propagate Buffer',
107
+ size: totalTiles * 4 * 4 * 4, // tiles × 4 directions × 4 floats × 4 bytes
108
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
109
+ })
110
+
111
+ // Create uniform buffer
112
+ this.uniformBuffer = device.createBuffer({
113
+ label: 'SSGI Tile Uniforms',
114
+ size: 32, // 8 floats
115
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
116
+ })
117
+
118
+ // Create accumulate pipeline
119
+ const accumulateModule = device.createShaderModule({
120
+ label: 'SSGI Accumulate Shader',
121
+ code: ssgiAccumulateWGSL,
122
+ })
123
+
124
+ this.accumulateBGL = device.createBindGroupLayout({
125
+ label: 'SSGI Accumulate BGL',
126
+ entries: [
127
+ { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },
128
+ { binding: 1, visibility: GPUShaderStage.COMPUTE, texture: { sampleType: 'float' } },
129
+ { binding: 2, visibility: GPUShaderStage.COMPUTE, texture: { sampleType: 'float' } },
130
+ { binding: 3, visibility: GPUShaderStage.COMPUTE, sampler: { type: 'filtering' } },
131
+ { binding: 4, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },
132
+ ],
133
+ })
134
+
135
+ // Create propagate pipeline shader module
136
+ const propagateModule = device.createShaderModule({
137
+ label: 'SSGI Propagate Shader',
138
+ code: ssgiPropagateWGSL,
139
+ })
140
+
141
+ this.propagateBGL = device.createBindGroupLayout({
142
+ label: 'SSGI Propagate BGL',
143
+ entries: [
144
+ { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },
145
+ { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } },
146
+ { binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },
147
+ ],
148
+ })
149
+
150
+ // Create both compute pipelines in parallel for faster initialization
151
+ const [accumulatePipeline, propagatePipeline] = await Promise.all([
152
+ device.createComputePipelineAsync({
153
+ label: 'SSGI Accumulate Pipeline',
154
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.accumulateBGL] }),
155
+ compute: { module: accumulateModule, entryPoint: 'main' },
156
+ }),
157
+ device.createComputePipelineAsync({
158
+ label: 'SSGI Propagate Pipeline',
159
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.propagateBGL] }),
160
+ compute: { module: propagateModule, entryPoint: 'main' },
161
+ })
162
+ ])
163
+
164
+ this.accumulatePipeline = accumulatePipeline
165
+ this.propagatePipeline = propagatePipeline
166
+
167
+ this._needsRebuild = false
168
+ }
169
+
170
+ async _execute(context) {
171
+ const { device } = this.engine
172
+
173
+ // Check if SSGI is enabled
174
+ const ssgiSettings = this.settings?.ssgi
175
+ if (!ssgiSettings?.enabled) {
176
+ return
177
+ }
178
+
179
+ // Rebuild if needed (use stored render dimensions, not canvas)
180
+ if (this._needsRebuild) {
181
+ await this._createResources(this.renderWidth, this.renderHeight)
182
+ }
183
+
184
+ // Check required textures
185
+ if (!this.prevHDRTexture || !this.emissiveTexture) {
186
+ return
187
+ }
188
+
189
+ if (!this.accumulatePipeline || !this.propagatePipeline) {
190
+ return
191
+ }
192
+
193
+ // Use stored render dimensions, not canvas dimensions
194
+ const width = this.renderWidth
195
+ const height = this.renderHeight
196
+ const emissiveBoost = ssgiSettings.emissiveBoost ?? 2.0
197
+ const maxBrightness = ssgiSettings.maxBrightness ?? 4.0
198
+
199
+ // Update uniforms
200
+ device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([
201
+ width,
202
+ height,
203
+ this.tileCountX,
204
+ this.tileCountY,
205
+ TILE_SIZE,
206
+ emissiveBoost,
207
+ maxBrightness,
208
+ 0, // padding
209
+ ]))
210
+
211
+ // Clear buffers
212
+ const clearAccum = new Float32Array(this.tileCountX * this.tileCountY * 4)
213
+ device.queue.writeBuffer(this.tileAccumBuffer, 0, clearAccum)
214
+ const clearPropagate = new Float32Array(this.tileCountX * this.tileCountY * 4 * 4)
215
+ device.queue.writeBuffer(this.tilePropagateBuffer, 0, clearPropagate)
216
+
217
+ // === PASS 1: Accumulate light per tile ===
218
+ const accumulateBindGroup = device.createBindGroup({
219
+ label: 'SSGI Accumulate Bind Group',
220
+ layout: this.accumulateBGL,
221
+ entries: [
222
+ { binding: 0, resource: { buffer: this.uniformBuffer } },
223
+ { binding: 1, resource: this.prevHDRTexture.view },
224
+ { binding: 2, resource: this.emissiveTexture.view },
225
+ { binding: 3, resource: this.sampler },
226
+ { binding: 4, resource: { buffer: this.tileAccumBuffer } },
227
+ ],
228
+ })
229
+
230
+ const commandEncoder = device.createCommandEncoder({ label: 'SSGI Tile Pass' })
231
+
232
+ const accumulatePass = commandEncoder.beginComputePass({ label: 'SSGI Accumulate' })
233
+ accumulatePass.setPipeline(this.accumulatePipeline)
234
+ accumulatePass.setBindGroup(0, accumulateBindGroup)
235
+ accumulatePass.dispatchWorkgroups(this.tileCountX, this.tileCountY, 1)
236
+ accumulatePass.end()
237
+
238
+ // === PASS 2: Propagate light between tiles ===
239
+ const propagateBindGroup = device.createBindGroup({
240
+ label: 'SSGI Propagate Bind Group',
241
+ layout: this.propagateBGL,
242
+ entries: [
243
+ { binding: 0, resource: { buffer: this.uniformBuffer } },
244
+ { binding: 1, resource: { buffer: this.tileAccumBuffer } },
245
+ { binding: 2, resource: { buffer: this.tilePropagateBuffer } },
246
+ ],
247
+ })
248
+
249
+ const propagatePass = commandEncoder.beginComputePass({ label: 'SSGI Propagate' })
250
+ propagatePass.setPipeline(this.propagatePipeline)
251
+ propagatePass.setBindGroup(0, propagateBindGroup)
252
+ propagatePass.dispatchWorkgroups(this.tileCountX, this.tileCountY, 1)
253
+ propagatePass.end()
254
+
255
+ device.queue.submit([commandEncoder.finish()])
256
+ }
257
+
258
+ /**
259
+ * Get the propagated light buffer for SSGIPass to sample from
260
+ */
261
+ getPropagateBuffer() {
262
+ return this.tilePropagateBuffer
263
+ }
264
+
265
+ /**
266
+ * Get the accumulated light buffer (for debugging)
267
+ */
268
+ getAccumBuffer() {
269
+ return this.tileAccumBuffer
270
+ }
271
+
272
+ /**
273
+ * Get tile grid dimensions
274
+ */
275
+ getTileInfo() {
276
+ return {
277
+ tileCountX: this.tileCountX,
278
+ tileCountY: this.tileCountY,
279
+ tileSize: TILE_SIZE,
280
+ }
281
+ }
282
+
283
+ async _resize(width, height) {
284
+ await this._createResources(width, height)
285
+ }
286
+
287
+ _destroy() {
288
+ if (this.tileAccumBuffer) {
289
+ this.tileAccumBuffer.destroy()
290
+ this.tileAccumBuffer = null
291
+ }
292
+ if (this.tilePropagateBuffer) {
293
+ this.tilePropagateBuffer.destroy()
294
+ this.tilePropagateBuffer = null
295
+ }
296
+ if (this.uniformBuffer) {
297
+ this.uniformBuffer.destroy()
298
+ this.uniformBuffer = null
299
+ }
300
+ this.accumulatePipeline = null
301
+ this.propagatePipeline = null
302
+ }
303
+ }
304
+
305
+ export { SSGITilePass, TILE_SIZE }