topazcube 0.1.30 → 0.1.33
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 +18200 -0
- package/dist/Renderer.cjs.map +1 -0
- package/dist/Renderer.js +18183 -0
- package/dist/Renderer.js.map +1 -0
- package/dist/client.cjs +94 -260
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +71 -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} +173 -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 +572 -0
- package/src/renderer/Geometry.js +1049 -0
- package/src/renderer/Material.js +61 -0
- package/src/renderer/Mesh.js +211 -0
- package/src/renderer/Node.js +112 -0
- package/src/renderer/Pipeline.js +643 -0
- package/src/renderer/Renderer.js +1324 -0
- package/src/renderer/Skin.js +792 -0
- package/src/renderer/Texture.js +584 -0
- package/src/renderer/core/AssetManager.js +359 -0
- package/src/renderer/core/CullingSystem.js +307 -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 +546 -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 +2064 -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 +417 -0
- package/src/renderer/rendering/passes/FogPass.js +419 -0
- package/src/renderer/rendering/passes/GBufferPass.js +706 -0
- package/src/renderer/rendering/passes/HiZPass.js +714 -0
- package/src/renderer/rendering/passes/LightingPass.js +739 -0
- package/src/renderer/rendering/passes/ParticlePass.js +835 -0
- package/src/renderer/rendering/passes/PlanarReflectionPass.js +456 -0
- package/src/renderer/rendering/passes/PostProcessPass.js +282 -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 +265 -0
- package/src/renderer/rendering/passes/SSGITilePass.js +296 -0
- package/src/renderer/rendering/passes/ShadowPass.js +1822 -0
- package/src/renderer/rendering/passes/TransparentPass.js +831 -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/depth_copy.wgsl +17 -0
- package/src/renderer/rendering/shaders/geometry.wgsl +550 -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 +525 -0
- package/src/renderer/rendering/shaders/particle_simulate.wgsl +440 -0
- package/src/renderer/rendering/shaders/postproc.wgsl +272 -0
- package/src/renderer/rendering/shaders/render_post.wgsl +289 -0
- package/src/renderer/rendering/shaders/shadow.wgsl +76 -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/utils/BoundingSphere.js +439 -0
- package/src/renderer/utils/Frustum.js +281 -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,333 @@
|
|
|
1
|
+
import { Texture } from "../Texture.js"
|
|
2
|
+
import { mat4 } from "../math.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HistoryBufferManager - Manages A/B double-buffered textures for temporal effects
|
|
6
|
+
*
|
|
7
|
+
* Provides previous frame data for:
|
|
8
|
+
* - SSR (Screen Space Reflections)
|
|
9
|
+
* - SSGI (Screen Space Global Illumination)
|
|
10
|
+
* - Temporal anti-aliasing
|
|
11
|
+
* - Motion blur (future)
|
|
12
|
+
*/
|
|
13
|
+
class HistoryBufferManager {
|
|
14
|
+
constructor(engine) {
|
|
15
|
+
this.engine = engine
|
|
16
|
+
this.frameIndex = 0 // Toggles 0/1 for A/B switching
|
|
17
|
+
this.initialized = false
|
|
18
|
+
this.width = 0
|
|
19
|
+
this.height = 0
|
|
20
|
+
|
|
21
|
+
// Double-buffered textures (A/B swap)
|
|
22
|
+
this.colorHistory = [null, null] // HDR color after lighting (rgba16float)
|
|
23
|
+
this.depthHistory = [null, null] // Linear depth (r32float)
|
|
24
|
+
this.normalHistory = [null, null] // World normals (rgba16float)
|
|
25
|
+
|
|
26
|
+
// Single buffer - written each frame, read next frame
|
|
27
|
+
this.velocityBuffer = null // Motion vectors (rg16float)
|
|
28
|
+
|
|
29
|
+
// Camera matrices history for reprojection
|
|
30
|
+
this.prevView = mat4.create()
|
|
31
|
+
this.prevProj = mat4.create()
|
|
32
|
+
this.prevViewProj = mat4.create()
|
|
33
|
+
this.prevInvViewProj = mat4.create()
|
|
34
|
+
this.prevCameraPosition = [0, 0, 0]
|
|
35
|
+
|
|
36
|
+
// Track if this is the first frame (no valid history)
|
|
37
|
+
this.hasValidHistory = false
|
|
38
|
+
|
|
39
|
+
// Textures pending destruction (wait for GPU to finish using them)
|
|
40
|
+
this._pendingDestroyRing = [[], [], []]
|
|
41
|
+
this._pendingDestroyIndex = 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initialize or resize all history buffers
|
|
46
|
+
* @param {number} width - Buffer width
|
|
47
|
+
* @param {number} height - Buffer height
|
|
48
|
+
*/
|
|
49
|
+
async initialize(width, height) {
|
|
50
|
+
const { device } = this.engine
|
|
51
|
+
|
|
52
|
+
// Skip if already initialized at this size
|
|
53
|
+
if (this.initialized && this.width === width && this.height === height) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Queue old buffers for deferred destruction
|
|
58
|
+
this._queueBuffersForDestruction()
|
|
59
|
+
|
|
60
|
+
this.width = width
|
|
61
|
+
this.height = height
|
|
62
|
+
|
|
63
|
+
// Create A/B color history buffers (HDR)
|
|
64
|
+
for (let i = 0; i < 2; i++) {
|
|
65
|
+
this.colorHistory[i] = await Texture.renderTarget(this.engine, 'rgba16float', width, height)
|
|
66
|
+
this.colorHistory[i].label = `colorHistory${i}`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Create A/B depth history buffers (linear depth as r32float)
|
|
70
|
+
for (let i = 0; i < 2; i++) {
|
|
71
|
+
const depthTex = device.createTexture({
|
|
72
|
+
label: `depthHistory${i}`,
|
|
73
|
+
size: [width, height],
|
|
74
|
+
format: 'r32float',
|
|
75
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
|
76
|
+
})
|
|
77
|
+
this.depthHistory[i] = {
|
|
78
|
+
texture: depthTex,
|
|
79
|
+
view: depthTex.createView(),
|
|
80
|
+
width,
|
|
81
|
+
height,
|
|
82
|
+
format: 'r32float'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Create A/B normal history buffers
|
|
87
|
+
for (let i = 0; i < 2; i++) {
|
|
88
|
+
this.normalHistory[i] = await Texture.renderTarget(this.engine, 'rgba16float', width, height)
|
|
89
|
+
this.normalHistory[i].label = `normalHistory${i}`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Create velocity buffer (motion vectors in pixels)
|
|
93
|
+
const velocityTex = device.createTexture({
|
|
94
|
+
label: 'velocityBuffer',
|
|
95
|
+
size: [width, height],
|
|
96
|
+
format: 'rg16float',
|
|
97
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
98
|
+
})
|
|
99
|
+
this.velocityBuffer = {
|
|
100
|
+
texture: velocityTex,
|
|
101
|
+
view: velocityTex.createView(),
|
|
102
|
+
width,
|
|
103
|
+
height,
|
|
104
|
+
format: 'rg16float'
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this.initialized = true
|
|
108
|
+
this.hasValidHistory = false // Reset - need one frame to build history
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get current frame buffers (write targets)
|
|
113
|
+
* @returns {Object} Current frame buffer references
|
|
114
|
+
*/
|
|
115
|
+
getCurrent() {
|
|
116
|
+
return {
|
|
117
|
+
color: this.colorHistory[this.frameIndex],
|
|
118
|
+
depth: this.depthHistory[this.frameIndex],
|
|
119
|
+
normal: this.normalHistory[this.frameIndex],
|
|
120
|
+
velocity: this.velocityBuffer,
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get previous frame buffers (read sources)
|
|
126
|
+
* @returns {Object} Previous frame buffer and camera data
|
|
127
|
+
*/
|
|
128
|
+
getPrevious() {
|
|
129
|
+
const prevIdx = 1 - this.frameIndex
|
|
130
|
+
return {
|
|
131
|
+
color: this.colorHistory[prevIdx],
|
|
132
|
+
depth: this.depthHistory[prevIdx],
|
|
133
|
+
normal: this.normalHistory[prevIdx],
|
|
134
|
+
velocity: this.velocityBuffer,
|
|
135
|
+
view: this.prevView,
|
|
136
|
+
proj: this.prevProj,
|
|
137
|
+
viewProj: this.prevViewProj,
|
|
138
|
+
invViewProj: this.prevInvViewProj,
|
|
139
|
+
cameraPosition: this.prevCameraPosition,
|
|
140
|
+
hasValidHistory: this.hasValidHistory,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get velocity buffer for GBuffer pass to write motion vectors
|
|
146
|
+
* @returns {Object} Velocity buffer texture
|
|
147
|
+
*/
|
|
148
|
+
getVelocityBuffer() {
|
|
149
|
+
return this.velocityBuffer
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Copy lighting output to current color history
|
|
154
|
+
* Called after lighting pass, before SSR/SSGI
|
|
155
|
+
* @param {GPUCommandEncoder} commandEncoder - Active command encoder
|
|
156
|
+
* @param {Texture} lightingOutput - HDR output from lighting pass
|
|
157
|
+
*/
|
|
158
|
+
copyLightingToHistory(commandEncoder, lightingOutput) {
|
|
159
|
+
if (!this.initialized || !lightingOutput) return
|
|
160
|
+
|
|
161
|
+
// Skip copy if source size doesn't match history size (resize in progress)
|
|
162
|
+
const srcWidth = lightingOutput.texture.width
|
|
163
|
+
const srcHeight = lightingOutput.texture.height
|
|
164
|
+
if (srcWidth !== this.width || srcHeight !== this.height) {
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const current = this.colorHistory[this.frameIndex]
|
|
169
|
+
commandEncoder.copyTextureToTexture(
|
|
170
|
+
{ texture: lightingOutput.texture },
|
|
171
|
+
{ texture: current.texture },
|
|
172
|
+
{ width: this.width, height: this.height }
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Copy GBuffer depth to current depth history
|
|
178
|
+
* Note: Not currently used - particles sample GBuffer depth directly
|
|
179
|
+
* @param {GPUCommandEncoder} commandEncoder - Active command encoder
|
|
180
|
+
* @param {Object} depthTexture - Depth texture from GBuffer
|
|
181
|
+
*/
|
|
182
|
+
copyDepthToHistory(commandEncoder, depthTexture) {
|
|
183
|
+
// Not implemented - particles use GBuffer depth directly via texture_depth_2d
|
|
184
|
+
// If needed in future, would require render pass to convert depth32float to r32float
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Copy GBuffer normals to current normal history
|
|
189
|
+
* @param {GPUCommandEncoder} commandEncoder - Active command encoder
|
|
190
|
+
* @param {Texture} gbufferNormal - Normal from GBuffer
|
|
191
|
+
*/
|
|
192
|
+
copyNormalToHistory(commandEncoder, normalTexture) {
|
|
193
|
+
if (!this.initialized || !normalTexture) return
|
|
194
|
+
|
|
195
|
+
// Skip copy if source size doesn't match history size (resize in progress)
|
|
196
|
+
const srcWidth = normalTexture.texture.width
|
|
197
|
+
const srcHeight = normalTexture.texture.height
|
|
198
|
+
if (srcWidth !== this.width || srcHeight !== this.height) {
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const current = this.normalHistory[this.frameIndex]
|
|
203
|
+
commandEncoder.copyTextureToTexture(
|
|
204
|
+
{ texture: normalTexture.texture },
|
|
205
|
+
{ texture: current.texture },
|
|
206
|
+
{ width: this.width, height: this.height }
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Swap buffers and save camera matrices
|
|
212
|
+
* Call at end of frame, after all rendering
|
|
213
|
+
* @param {Camera} camera - Current frame camera
|
|
214
|
+
*/
|
|
215
|
+
swap(camera) {
|
|
216
|
+
if (!this.initialized) return
|
|
217
|
+
|
|
218
|
+
// Process deferred texture destruction (3 frames delayed)
|
|
219
|
+
this._pendingDestroyIndex = (this._pendingDestroyIndex + 1) % 3
|
|
220
|
+
const toDestroy = this._pendingDestroyRing[this._pendingDestroyIndex]
|
|
221
|
+
for (const tex of toDestroy) {
|
|
222
|
+
tex.destroy()
|
|
223
|
+
}
|
|
224
|
+
this._pendingDestroyRing[this._pendingDestroyIndex] = []
|
|
225
|
+
|
|
226
|
+
// Save current camera matrices as "previous" for next frame
|
|
227
|
+
mat4.copy(this.prevView, camera.view)
|
|
228
|
+
mat4.copy(this.prevProj, camera.proj)
|
|
229
|
+
mat4.copy(this.prevViewProj, camera.viewProj)
|
|
230
|
+
mat4.copy(this.prevInvViewProj, camera.iViewProj)
|
|
231
|
+
this.prevCameraPosition[0] = camera.position[0]
|
|
232
|
+
this.prevCameraPosition[1] = camera.position[1]
|
|
233
|
+
this.prevCameraPosition[2] = camera.position[2]
|
|
234
|
+
|
|
235
|
+
// Swap buffer index for next frame
|
|
236
|
+
this.frameIndex = 1 - this.frameIndex
|
|
237
|
+
|
|
238
|
+
// After first swap, we have valid history
|
|
239
|
+
this.hasValidHistory = true
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if history is valid (at least one frame rendered)
|
|
244
|
+
* @returns {boolean} True if history buffers contain valid data
|
|
245
|
+
*/
|
|
246
|
+
isHistoryValid() {
|
|
247
|
+
return this.hasValidHistory
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get current frame index (0 or 1)
|
|
252
|
+
* @returns {number} Current frame index
|
|
253
|
+
*/
|
|
254
|
+
getFrameIndex() {
|
|
255
|
+
return this.frameIndex
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Resize all buffers
|
|
260
|
+
* @param {number} width - New width
|
|
261
|
+
* @param {number} height - New height
|
|
262
|
+
*/
|
|
263
|
+
async resize(width, height) {
|
|
264
|
+
await this.initialize(width, height)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Queue old buffers for deferred destruction (GPU may still be using them)
|
|
269
|
+
*/
|
|
270
|
+
_queueBuffersForDestruction() {
|
|
271
|
+
const slot = this._pendingDestroyRing[this._pendingDestroyIndex]
|
|
272
|
+
for (let i = 0; i < 2; i++) {
|
|
273
|
+
if (this.colorHistory[i]?.texture) {
|
|
274
|
+
slot.push(this.colorHistory[i].texture)
|
|
275
|
+
this.colorHistory[i] = null
|
|
276
|
+
}
|
|
277
|
+
if (this.depthHistory[i]?.texture) {
|
|
278
|
+
slot.push(this.depthHistory[i].texture)
|
|
279
|
+
this.depthHistory[i] = null
|
|
280
|
+
}
|
|
281
|
+
if (this.normalHistory[i]?.texture) {
|
|
282
|
+
slot.push(this.normalHistory[i].texture)
|
|
283
|
+
this.normalHistory[i] = null
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (this.velocityBuffer?.texture) {
|
|
287
|
+
slot.push(this.velocityBuffer.texture)
|
|
288
|
+
this.velocityBuffer = null
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Destroy all buffer resources immediately
|
|
294
|
+
*/
|
|
295
|
+
_destroyBuffers() {
|
|
296
|
+
for (let i = 0; i < 2; i++) {
|
|
297
|
+
if (this.colorHistory[i]?.texture) {
|
|
298
|
+
this.colorHistory[i].texture.destroy()
|
|
299
|
+
this.colorHistory[i] = null
|
|
300
|
+
}
|
|
301
|
+
if (this.depthHistory[i]?.texture) {
|
|
302
|
+
this.depthHistory[i].texture.destroy()
|
|
303
|
+
this.depthHistory[i] = null
|
|
304
|
+
}
|
|
305
|
+
if (this.normalHistory[i]?.texture) {
|
|
306
|
+
this.normalHistory[i].texture.destroy()
|
|
307
|
+
this.normalHistory[i] = null
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (this.velocityBuffer?.texture) {
|
|
311
|
+
this.velocityBuffer.texture.destroy()
|
|
312
|
+
this.velocityBuffer = null
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Clean up all resources
|
|
318
|
+
*/
|
|
319
|
+
destroy() {
|
|
320
|
+
this._destroyBuffers()
|
|
321
|
+
// Clean up any pending textures in ring buffer
|
|
322
|
+
for (const slot of this._pendingDestroyRing) {
|
|
323
|
+
for (const tex of slot) {
|
|
324
|
+
tex.destroy()
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
this._pendingDestroyRing = [[], [], []]
|
|
328
|
+
this.initialized = false
|
|
329
|
+
this.hasValidHistory = false
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export { HistoryBufferManager }
|