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.
- package/LICENSE.txt +0 -0
- package/README.md +0 -0
- package/dist/Renderer.cjs +20844 -0
- package/dist/Renderer.cjs.map +1 -0
- package/dist/Renderer.js +20827 -0
- package/dist/Renderer.js.map +1 -0
- package/dist/client.cjs +91 -260
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +68 -215
- package/dist/client.js.map +1 -1
- package/dist/server.cjs +165 -432
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +117 -370
- package/dist/server.js.map +1 -1
- package/dist/terminal.cjs +113 -200
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.js +50 -51
- package/dist/terminal.js.map +1 -1
- package/dist/utils-CRhi1BDa.cjs +259 -0
- package/dist/utils-CRhi1BDa.cjs.map +1 -0
- package/dist/utils-D7tXt6-2.js +260 -0
- package/dist/utils-D7tXt6-2.js.map +1 -0
- package/package.json +19 -15
- package/src/{client.ts → network/client.js} +170 -403
- package/src/{compress-browser.ts → network/compress-browser.js} +2 -4
- package/src/{compress-node.ts → network/compress-node.js} +8 -14
- package/src/{server.ts → network/server.js} +229 -317
- package/src/{terminal.js → network/terminal.js} +0 -0
- package/src/{topazcube.ts → network/topazcube.js} +2 -2
- package/src/network/utils.js +375 -0
- package/src/renderer/Camera.js +191 -0
- package/src/renderer/DebugUI.js +703 -0
- package/src/renderer/Geometry.js +1049 -0
- package/src/renderer/Material.js +64 -0
- package/src/renderer/Mesh.js +211 -0
- package/src/renderer/Node.js +112 -0
- package/src/renderer/Pipeline.js +645 -0
- package/src/renderer/Renderer.js +1496 -0
- package/src/renderer/Skin.js +792 -0
- package/src/renderer/Texture.js +584 -0
- package/src/renderer/core/AssetManager.js +394 -0
- package/src/renderer/core/CullingSystem.js +308 -0
- package/src/renderer/core/EntityManager.js +541 -0
- package/src/renderer/core/InstanceManager.js +343 -0
- package/src/renderer/core/ParticleEmitter.js +358 -0
- package/src/renderer/core/ParticleSystem.js +564 -0
- package/src/renderer/core/SpriteSystem.js +349 -0
- package/src/renderer/gltf.js +563 -0
- package/src/renderer/math.js +161 -0
- package/src/renderer/rendering/HistoryBufferManager.js +333 -0
- package/src/renderer/rendering/ProbeCapture.js +1495 -0
- package/src/renderer/rendering/ReflectionProbeManager.js +352 -0
- package/src/renderer/rendering/RenderGraph.js +2258 -0
- package/src/renderer/rendering/passes/AOPass.js +308 -0
- package/src/renderer/rendering/passes/AmbientCapturePass.js +593 -0
- package/src/renderer/rendering/passes/BasePass.js +101 -0
- package/src/renderer/rendering/passes/BloomPass.js +420 -0
- package/src/renderer/rendering/passes/CRTPass.js +724 -0
- package/src/renderer/rendering/passes/FogPass.js +445 -0
- package/src/renderer/rendering/passes/GBufferPass.js +730 -0
- package/src/renderer/rendering/passes/HiZPass.js +744 -0
- package/src/renderer/rendering/passes/LightingPass.js +753 -0
- package/src/renderer/rendering/passes/ParticlePass.js +841 -0
- package/src/renderer/rendering/passes/PlanarReflectionPass.js +456 -0
- package/src/renderer/rendering/passes/PostProcessPass.js +405 -0
- package/src/renderer/rendering/passes/ReflectionPass.js +157 -0
- package/src/renderer/rendering/passes/RenderPostPass.js +364 -0
- package/src/renderer/rendering/passes/SSGIPass.js +266 -0
- package/src/renderer/rendering/passes/SSGITilePass.js +305 -0
- package/src/renderer/rendering/passes/ShadowPass.js +2072 -0
- package/src/renderer/rendering/passes/TransparentPass.js +831 -0
- package/src/renderer/rendering/passes/VolumetricFogPass.js +715 -0
- package/src/renderer/rendering/shaders/ao.wgsl +182 -0
- package/src/renderer/rendering/shaders/bloom.wgsl +97 -0
- package/src/renderer/rendering/shaders/bloom_blur.wgsl +80 -0
- package/src/renderer/rendering/shaders/crt.wgsl +455 -0
- package/src/renderer/rendering/shaders/depth_copy.wgsl +17 -0
- package/src/renderer/rendering/shaders/geometry.wgsl +580 -0
- package/src/renderer/rendering/shaders/hiz_reduce.wgsl +114 -0
- package/src/renderer/rendering/shaders/light_culling.wgsl +204 -0
- package/src/renderer/rendering/shaders/lighting.wgsl +932 -0
- package/src/renderer/rendering/shaders/lighting_common.wgsl +143 -0
- package/src/renderer/rendering/shaders/particle_render.wgsl +672 -0
- package/src/renderer/rendering/shaders/particle_simulate.wgsl +440 -0
- package/src/renderer/rendering/shaders/postproc.wgsl +293 -0
- package/src/renderer/rendering/shaders/render_post.wgsl +289 -0
- package/src/renderer/rendering/shaders/shadow.wgsl +117 -0
- package/src/renderer/rendering/shaders/ssgi.wgsl +266 -0
- package/src/renderer/rendering/shaders/ssgi_accumulate.wgsl +114 -0
- package/src/renderer/rendering/shaders/ssgi_propagate.wgsl +132 -0
- package/src/renderer/rendering/shaders/volumetric_blur.wgsl +80 -0
- package/src/renderer/rendering/shaders/volumetric_composite.wgsl +80 -0
- package/src/renderer/rendering/shaders/volumetric_raymarch.wgsl +634 -0
- package/src/renderer/utils/BoundingSphere.js +439 -0
- package/src/renderer/utils/Frustum.js +281 -0
- package/src/renderer/utils/Raycaster.js +761 -0
- package/dist/client.d.cts +0 -211
- package/dist/client.d.ts +0 -211
- package/dist/server.d.cts +0 -120
- package/dist/server.d.ts +0 -120
- package/dist/terminal.d.cts +0 -64
- package/dist/terminal.d.ts +0 -64
- 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 }
|