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,349 @@
|
|
|
1
|
+
import { Texture } from "../Texture.js"
|
|
2
|
+
import { Material } from "../Material.js"
|
|
3
|
+
import { Mesh } from "../Mesh.js"
|
|
4
|
+
import { Geometry } from "../Geometry.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* SpriteSystem - Manages sprite entities for billboard rendering
|
|
8
|
+
*
|
|
9
|
+
* Handles:
|
|
10
|
+
* - Parsing sprite definitions (texture path, frames per row)
|
|
11
|
+
* - Loading and caching sprite textures
|
|
12
|
+
* - Computing UV transforms for sprite sheet frames
|
|
13
|
+
* - Animating sprites based on frame property
|
|
14
|
+
* - Creating sprite materials and meshes
|
|
15
|
+
*/
|
|
16
|
+
class SpriteSystem {
|
|
17
|
+
constructor(engine) {
|
|
18
|
+
this.engine = engine
|
|
19
|
+
|
|
20
|
+
// Cache for loaded sprite textures: textureUrl -> Texture
|
|
21
|
+
this._textureCache = new Map()
|
|
22
|
+
|
|
23
|
+
// Cache for sprite materials: key -> Material
|
|
24
|
+
this._materialCache = new Map()
|
|
25
|
+
|
|
26
|
+
// Cache for sprite geometries: pivot -> Geometry
|
|
27
|
+
this._geometryCache = new Map()
|
|
28
|
+
|
|
29
|
+
// Active sprite entity tracking for animation
|
|
30
|
+
this._spriteEntities = new Map() // entityId -> spriteData
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse a sprite definition string
|
|
35
|
+
* Format: "texture.png" or "texture.png|8" (texture|framesPerRow)
|
|
36
|
+
* @param {string} spriteString - Sprite definition
|
|
37
|
+
* @returns {{ url: string, framesPerRow: number }}
|
|
38
|
+
*/
|
|
39
|
+
parseSprite(spriteString) {
|
|
40
|
+
if (!spriteString || typeof spriteString !== 'string') {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const parts = spriteString.split('|')
|
|
45
|
+
return {
|
|
46
|
+
url: parts[0],
|
|
47
|
+
framesPerRow: parts.length > 1 ? parseInt(parts[1], 10) : 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Parse a frame animation string
|
|
53
|
+
* Format: integer frame OR "startFrame|endFrame|fps"
|
|
54
|
+
* @param {number|string} frame - Frame definition
|
|
55
|
+
* @returns {{ currentFrame: number, startFrame: number, endFrame: number, fps: number, isAnimated: boolean }}
|
|
56
|
+
*/
|
|
57
|
+
parseFrame(frame) {
|
|
58
|
+
// Check for animated format first: "startFrame|endFrame|fps"
|
|
59
|
+
if (typeof frame === 'string' && frame.includes('|')) {
|
|
60
|
+
const parts = frame.split('|')
|
|
61
|
+
const start = parseInt(parts[0], 10) || 0
|
|
62
|
+
const end = parseInt(parts[1], 10) || start
|
|
63
|
+
const fps = parseFloat(parts[2]) || 30
|
|
64
|
+
return {
|
|
65
|
+
currentFrame: start,
|
|
66
|
+
startFrame: start,
|
|
67
|
+
endFrame: end,
|
|
68
|
+
fps,
|
|
69
|
+
isAnimated: true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Single frame (number or numeric string)
|
|
74
|
+
if (typeof frame === 'number') {
|
|
75
|
+
return {
|
|
76
|
+
currentFrame: frame,
|
|
77
|
+
startFrame: frame,
|
|
78
|
+
endFrame: frame,
|
|
79
|
+
fps: 0,
|
|
80
|
+
isAnimated: false
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (typeof frame === 'string' && !isNaN(parseInt(frame, 10))) {
|
|
85
|
+
const f = parseInt(frame, 10)
|
|
86
|
+
return {
|
|
87
|
+
currentFrame: f,
|
|
88
|
+
startFrame: f,
|
|
89
|
+
endFrame: f,
|
|
90
|
+
fps: 0,
|
|
91
|
+
isAnimated: false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Default: frame 0
|
|
96
|
+
return {
|
|
97
|
+
currentFrame: 0,
|
|
98
|
+
startFrame: 0,
|
|
99
|
+
endFrame: 0,
|
|
100
|
+
fps: 0,
|
|
101
|
+
isAnimated: false
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Compute UV offset and scale for a frame in a sprite sheet
|
|
107
|
+
* @param {number} frame - Frame index (0-based)
|
|
108
|
+
* @param {number} framesPerRow - Number of frames per row in the sheet
|
|
109
|
+
* @param {number} [totalFrames] - Optional total frames (for non-square sheets)
|
|
110
|
+
* @returns {{ offset: [number, number], scale: [number, number] }}
|
|
111
|
+
*/
|
|
112
|
+
computeFrameUV(frame, framesPerRow, totalFrames = null) {
|
|
113
|
+
if (framesPerRow <= 1) {
|
|
114
|
+
// Single frame - full texture
|
|
115
|
+
return {
|
|
116
|
+
offset: [0, 0],
|
|
117
|
+
scale: [1, 1]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const col = frame % framesPerRow
|
|
122
|
+
const row = Math.floor(frame / framesPerRow)
|
|
123
|
+
|
|
124
|
+
// Calculate number of rows based on totalFrames or assume single row
|
|
125
|
+
// For sprite sheets like 256x32 with 8 frames, there's only 1 row
|
|
126
|
+
// so scaleY should be 1 (full height), not 1/8
|
|
127
|
+
const numRows = totalFrames ? Math.ceil(totalFrames / framesPerRow) : (row + 1)
|
|
128
|
+
const scaleX = 1.0 / framesPerRow
|
|
129
|
+
const scaleY = 1.0 / Math.max(1, numRows)
|
|
130
|
+
|
|
131
|
+
// X offset is straightforward: column * frame width
|
|
132
|
+
const xOffset = col * scaleX
|
|
133
|
+
|
|
134
|
+
// Y offset with flipY: top of image is at v=1, bottom at v=0
|
|
135
|
+
// For single-row sheets, yOffset is 0 and scaleY is 1
|
|
136
|
+
// For multi-row sheets, calculate based on row
|
|
137
|
+
const yOffset = row * scaleY
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
offset: [xOffset, yOffset],
|
|
141
|
+
scale: [scaleX, scaleY]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get or load a sprite texture
|
|
147
|
+
* @param {string} url - Texture URL
|
|
148
|
+
* @returns {Promise<Texture>}
|
|
149
|
+
*/
|
|
150
|
+
async loadTexture(url) {
|
|
151
|
+
if (this._textureCache.has(url)) {
|
|
152
|
+
return this._textureCache.get(url)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const texture = await Texture.fromImage(this.engine, url, {
|
|
156
|
+
srgb: true,
|
|
157
|
+
generateMips: true,
|
|
158
|
+
flipY: true
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
this._textureCache.set(url, texture)
|
|
162
|
+
return texture
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get or create a material for a sprite type
|
|
167
|
+
* @param {string} textureUrl - Texture URL
|
|
168
|
+
* @param {number} roughness - Roughness value (0-1)
|
|
169
|
+
* @param {string} pivot - Pivot mode
|
|
170
|
+
* @returns {Material}
|
|
171
|
+
*/
|
|
172
|
+
async getSpriteMaterial(textureUrl, roughness = 0.7, pivot = 'center') {
|
|
173
|
+
const key = `sprite:${textureUrl}:${pivot}:r${roughness.toFixed(2)}`
|
|
174
|
+
|
|
175
|
+
if (this._materialCache.has(key)) {
|
|
176
|
+
return this._materialCache.get(key)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Load sprite texture
|
|
180
|
+
const albedoTexture = await this.loadTexture(textureUrl)
|
|
181
|
+
|
|
182
|
+
// Create default textures for other slots
|
|
183
|
+
const normalTexture = await Texture.fromRGBA(this.engine, 0.5, 0.5, 1.0, 1.0) // Flat normal
|
|
184
|
+
const aoTexture = await Texture.fromRGBA(this.engine, 1.0, 1.0, 1.0, 1.0) // No AO
|
|
185
|
+
const rmTexture = await Texture.fromRGBA(this.engine, 0.0, roughness, 0.0, 1.0) // Roughness, no metallic
|
|
186
|
+
const emissionTexture = await Texture.fromRGBA(this.engine, 0.0, 0.0, 0.0, 1.0) // No emission
|
|
187
|
+
|
|
188
|
+
const material = new Material(
|
|
189
|
+
[albedoTexture, normalTexture, aoTexture, rmTexture, emissionTexture],
|
|
190
|
+
{
|
|
191
|
+
billboardMode: this._pivotToMode(pivot),
|
|
192
|
+
spriteRoughness: roughness
|
|
193
|
+
},
|
|
194
|
+
key,
|
|
195
|
+
this.engine
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
// Enable alpha hash for cutout transparency
|
|
199
|
+
material.alphaHash = true
|
|
200
|
+
material.alphaHashScale = 1.0
|
|
201
|
+
|
|
202
|
+
this._materialCache.set(key, material)
|
|
203
|
+
return material
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get or create billboard quad geometry for a pivot mode
|
|
208
|
+
* @param {string} pivot - Pivot mode: 'center', 'bottom', 'horizontal'
|
|
209
|
+
* @returns {Geometry}
|
|
210
|
+
*/
|
|
211
|
+
getGeometry(pivot = 'center') {
|
|
212
|
+
if (this._geometryCache.has(pivot)) {
|
|
213
|
+
return this._geometryCache.get(pivot)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const geometry = Geometry.billboardQuad(this.engine, pivot)
|
|
217
|
+
this._geometryCache.set(pivot, geometry)
|
|
218
|
+
return geometry
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Convert pivot string to billboard mode number
|
|
223
|
+
* @param {string} pivot - Pivot mode
|
|
224
|
+
* @returns {number}
|
|
225
|
+
*/
|
|
226
|
+
_pivotToMode(pivot) {
|
|
227
|
+
switch (pivot) {
|
|
228
|
+
case 'center': return 1
|
|
229
|
+
case 'bottom': return 2
|
|
230
|
+
case 'horizontal': return 3
|
|
231
|
+
default: return 0
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Register a sprite entity for animation tracking
|
|
237
|
+
* @param {string} entityId - Entity ID
|
|
238
|
+
* @param {Object} entity - Entity object
|
|
239
|
+
*/
|
|
240
|
+
registerEntity(entityId, entity) {
|
|
241
|
+
if (!entity.sprite) return
|
|
242
|
+
|
|
243
|
+
const spriteInfo = this.parseSprite(entity.sprite)
|
|
244
|
+
if (!spriteInfo) return
|
|
245
|
+
|
|
246
|
+
const frameInfo = this.parseFrame(entity.frame || 0)
|
|
247
|
+
|
|
248
|
+
this._spriteEntities.set(entityId, {
|
|
249
|
+
entity,
|
|
250
|
+
spriteInfo,
|
|
251
|
+
frameInfo,
|
|
252
|
+
animTime: 0
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Unregister a sprite entity
|
|
258
|
+
* @param {string} entityId - Entity ID
|
|
259
|
+
*/
|
|
260
|
+
unregisterEntity(entityId) {
|
|
261
|
+
this._spriteEntities.delete(entityId)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Update sprite animations
|
|
266
|
+
* @param {number} dt - Delta time in seconds
|
|
267
|
+
*/
|
|
268
|
+
update(dt) {
|
|
269
|
+
for (const [entityId, data] of this._spriteEntities) {
|
|
270
|
+
const { entity, spriteInfo, frameInfo } = data
|
|
271
|
+
|
|
272
|
+
if (!frameInfo.isAnimated) continue
|
|
273
|
+
|
|
274
|
+
// Advance animation time
|
|
275
|
+
data.animTime += dt * frameInfo.fps
|
|
276
|
+
|
|
277
|
+
// Calculate current frame (loop by default)
|
|
278
|
+
const frameCount = frameInfo.endFrame - frameInfo.startFrame + 1
|
|
279
|
+
const frameOffset = Math.floor(data.animTime) % frameCount
|
|
280
|
+
frameInfo.currentFrame = frameInfo.startFrame + frameOffset
|
|
281
|
+
|
|
282
|
+
// Update entity's UV transform
|
|
283
|
+
const uv = this.computeFrameUV(frameInfo.currentFrame, spriteInfo.framesPerRow)
|
|
284
|
+
entity._uvTransform = [uv.offset[0], uv.offset[1], uv.scale[0], uv.scale[1]]
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get instance data for a sprite entity
|
|
290
|
+
* @param {Object} entity - Entity with sprite properties
|
|
291
|
+
* @returns {{ uvTransform: [number, number, number, number], color: [number, number, number, number] }}
|
|
292
|
+
*/
|
|
293
|
+
getSpriteInstanceData(entity) {
|
|
294
|
+
// If entity has pre-computed _uvTransform (from animation), use it
|
|
295
|
+
if (entity._uvTransform) {
|
|
296
|
+
return {
|
|
297
|
+
uvTransform: entity._uvTransform,
|
|
298
|
+
color: entity.color || [1, 1, 1, 1]
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Otherwise compute from sprite properties
|
|
303
|
+
const spriteInfo = this.parseSprite(entity.sprite)
|
|
304
|
+
if (!spriteInfo) {
|
|
305
|
+
return {
|
|
306
|
+
uvTransform: [0, 0, 1, 1],
|
|
307
|
+
color: entity.color || [1, 1, 1, 1]
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const frameInfo = this.parseFrame(entity.frame || 0)
|
|
312
|
+
const uv = this.computeFrameUV(frameInfo.currentFrame, spriteInfo.framesPerRow)
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
uvTransform: [uv.offset[0], uv.offset[1], uv.scale[0], uv.scale[1]],
|
|
316
|
+
color: entity.color || [1, 1, 1, 1]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Create a complete sprite asset (geometry + material + mesh)
|
|
322
|
+
* @param {string} spriteString - Sprite definition
|
|
323
|
+
* @param {string} pivot - Pivot mode
|
|
324
|
+
* @param {number} roughness - Roughness value
|
|
325
|
+
* @returns {Promise<{ geometry: Geometry, material: Material, mesh: Mesh }>}
|
|
326
|
+
*/
|
|
327
|
+
async createSpriteAsset(spriteString, pivot = 'center', roughness = 0.7) {
|
|
328
|
+
const spriteInfo = this.parseSprite(spriteString)
|
|
329
|
+
if (!spriteInfo) return null
|
|
330
|
+
|
|
331
|
+
const geometry = this.getGeometry(pivot)
|
|
332
|
+
const material = await this.getSpriteMaterial(spriteInfo.url, roughness, pivot)
|
|
333
|
+
const mesh = new Mesh(this.engine, geometry, material)
|
|
334
|
+
|
|
335
|
+
return { geometry, material, mesh, spriteInfo }
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Destroy and clean up resources
|
|
340
|
+
*/
|
|
341
|
+
destroy() {
|
|
342
|
+
this._textureCache.clear()
|
|
343
|
+
this._materialCache.clear()
|
|
344
|
+
this._geometryCache.clear()
|
|
345
|
+
this._spriteEntities.clear()
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export { SpriteSystem }
|