@rings-webgpu/core 1.0.37 → 1.0.39
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/dist/rings.es.js +92 -92
- package/dist/rings.es.js.map +3 -3
- package/dist/rings.es.max.js +269 -99
- package/dist/rings.umd.js +104 -104
- package/dist/rings.umd.js.map +3 -3
- package/dist/rings.umd.max.js +269 -99
- package/dist/types/components/renderer/GSplatStreamRenderer.d.ts +4 -3
- package/dist/types/textures/Float16ArrayTexture.d.ts +3 -1
- package/dist/types/textures/Uint32ArrayTexture.d.ts +1 -1
- package/dist/types/textures/Uint8ArrayTexture.d.ts +1 -1
- package/package.json +1 -1
package/dist/rings.umd.max.js
CHANGED
|
@@ -24088,10 +24088,44 @@ struct InstanceData {
|
|
|
24088
24088
|
}
|
|
24089
24089
|
return this;
|
|
24090
24090
|
}
|
|
24091
|
-
updateTexture(width, height, data) {
|
|
24091
|
+
updateTexture(width, height, data, startRow, rowCount) {
|
|
24092
24092
|
let device = webGPUContext.device;
|
|
24093
24093
|
const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
|
|
24094
24094
|
this.mipmapCount = Math.floor(Math.log2(width) );
|
|
24095
|
+
if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
|
|
24096
|
+
const updateHeight = rowCount;
|
|
24097
|
+
const updateOffset = startRow * width * 4;
|
|
24098
|
+
const updateData = data.subarray(updateOffset, updateOffset + updateHeight * width * 4);
|
|
24099
|
+
const neededSize = updateData.byteLength;
|
|
24100
|
+
if (!this._dataBuffer || this._dataBuffer.size < neededSize) {
|
|
24101
|
+
this._dataBuffer && this._dataBuffer.destroy();
|
|
24102
|
+
this._dataBuffer = device.createBuffer({
|
|
24103
|
+
size: neededSize,
|
|
24104
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
|
|
24105
|
+
});
|
|
24106
|
+
}
|
|
24107
|
+
device.queue.writeBuffer(this._dataBuffer, 0, updateData.buffer, updateData.byteOffset, updateData.byteLength);
|
|
24108
|
+
const commandEncoder2 = GPUContext.beginCommandEncoder();
|
|
24109
|
+
commandEncoder2.copyBufferToTexture(
|
|
24110
|
+
{
|
|
24111
|
+
buffer: this._dataBuffer,
|
|
24112
|
+
bytesPerRow,
|
|
24113
|
+
offset: 0
|
|
24114
|
+
},
|
|
24115
|
+
{
|
|
24116
|
+
texture: this.getGPUTexture(),
|
|
24117
|
+
origin: [0, startRow, 0]
|
|
24118
|
+
// Start at row startRow
|
|
24119
|
+
},
|
|
24120
|
+
{
|
|
24121
|
+
width,
|
|
24122
|
+
height: updateHeight,
|
|
24123
|
+
depthOrArrayLayers: 1
|
|
24124
|
+
}
|
|
24125
|
+
);
|
|
24126
|
+
GPUContext.endCommandEncoder(commandEncoder2);
|
|
24127
|
+
return;
|
|
24128
|
+
}
|
|
24095
24129
|
this._dataBuffer && this._dataBuffer.destroy();
|
|
24096
24130
|
this._dataBuffer = null;
|
|
24097
24131
|
const textureDataBuffer = this._dataBuffer = device.createBuffer({
|
|
@@ -24147,9 +24181,28 @@ struct InstanceData {
|
|
|
24147
24181
|
this.gpuSampler = device.createSampler({});
|
|
24148
24182
|
return this;
|
|
24149
24183
|
}
|
|
24150
|
-
updateTexture(width, height, data) {
|
|
24184
|
+
updateTexture(width, height, data, startRow, rowCount) {
|
|
24151
24185
|
let device = webGPUContext.device;
|
|
24152
24186
|
const bytesPerRow = width * 4 * 4;
|
|
24187
|
+
if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
|
|
24188
|
+
const updateHeight = rowCount;
|
|
24189
|
+
const updateOffset = startRow * width * 4;
|
|
24190
|
+
const updateData = data.subarray(updateOffset, updateOffset + updateHeight * width * 4);
|
|
24191
|
+
device.queue.writeTexture(
|
|
24192
|
+
{
|
|
24193
|
+
texture: this.getGPUTexture(),
|
|
24194
|
+
origin: [0, startRow, 0]
|
|
24195
|
+
// Start at row startRow
|
|
24196
|
+
},
|
|
24197
|
+
updateData.buffer,
|
|
24198
|
+
{
|
|
24199
|
+
bytesPerRow,
|
|
24200
|
+
offset: updateData.byteOffset
|
|
24201
|
+
},
|
|
24202
|
+
{ width, height: updateHeight, depthOrArrayLayers: 1 }
|
|
24203
|
+
);
|
|
24204
|
+
return;
|
|
24205
|
+
}
|
|
24153
24206
|
device.queue.writeTexture(
|
|
24154
24207
|
{ texture: this.getGPUTexture() },
|
|
24155
24208
|
data.buffer,
|
|
@@ -24196,30 +24249,37 @@ struct InstanceData {
|
|
|
24196
24249
|
}
|
|
24197
24250
|
}
|
|
24198
24251
|
|
|
24199
|
-
const _floatView = new Float32Array(1);
|
|
24200
|
-
const _int32View = new Int32Array(_floatView.buffer);
|
|
24201
|
-
|
|
24202
|
-
|
|
24203
|
-
|
|
24204
|
-
|
|
24205
|
-
|
|
24206
|
-
|
|
24207
|
-
|
|
24208
|
-
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24252
|
+
const _floatView$1 = new Float32Array(1);
|
|
24253
|
+
const _int32View$1 = new Int32Array(_floatView$1.buffer);
|
|
24254
|
+
function batchConvertToHalfFloat(src, dst, offset, length) {
|
|
24255
|
+
for (let i = 0; i < length; i++) {
|
|
24256
|
+
const val = src[offset + i];
|
|
24257
|
+
_floatView$1[0] = val;
|
|
24258
|
+
const x = _int32View$1[0];
|
|
24259
|
+
let bits = x >> 16 & 32768;
|
|
24260
|
+
let m = x >> 12 & 2047;
|
|
24261
|
+
const e = x >> 23 & 255;
|
|
24262
|
+
if (e < 103) {
|
|
24263
|
+
dst[offset + i] = bits;
|
|
24264
|
+
continue;
|
|
24265
|
+
}
|
|
24266
|
+
if (e > 142) {
|
|
24267
|
+
bits |= 31744;
|
|
24268
|
+
bits |= (e == 255 ? 1 : 0) && x & 8388607;
|
|
24269
|
+
dst[offset + i] = bits;
|
|
24270
|
+
continue;
|
|
24271
|
+
}
|
|
24272
|
+
if (e < 114) {
|
|
24273
|
+
m |= 2048;
|
|
24274
|
+
bits |= (m >> 114 - e) + (m >> 113 - e & 1);
|
|
24275
|
+
dst[offset + i] = bits;
|
|
24276
|
+
continue;
|
|
24277
|
+
}
|
|
24278
|
+
bits |= e - 112 << 10 | m >> 1;
|
|
24279
|
+
bits += m & 1;
|
|
24280
|
+
dst[offset + i] = bits;
|
|
24217
24281
|
}
|
|
24218
|
-
|
|
24219
|
-
bits += m & 1;
|
|
24220
|
-
return bits;
|
|
24221
|
-
};
|
|
24222
|
-
|
|
24282
|
+
}
|
|
24223
24283
|
class Float16ArrayTexture extends Texture {
|
|
24224
24284
|
uint16Array;
|
|
24225
24285
|
floatArray;
|
|
@@ -24248,8 +24308,10 @@ struct InstanceData {
|
|
|
24248
24308
|
* @param height 纹理高度
|
|
24249
24309
|
* @param numbers 像素数据数组
|
|
24250
24310
|
* @param mipmap 是否生成Mipmap
|
|
24311
|
+
* @param startRow 起始行(部分更新)
|
|
24312
|
+
* @param rowCount 更新的行数(部分更新)
|
|
24251
24313
|
*/
|
|
24252
|
-
updateTexture(width, height, numbers, mipmap = true) {
|
|
24314
|
+
updateTexture(width, height, numbers, mipmap = true, startRow, rowCount) {
|
|
24253
24315
|
if (width != this.width || height != this.height) {
|
|
24254
24316
|
this._dataBuffer && this._dataBuffer.destroy();
|
|
24255
24317
|
this._dataBuffer = null;
|
|
@@ -24262,22 +24324,70 @@ struct InstanceData {
|
|
|
24262
24324
|
this.format = GPUTextureFormat.rgba16float;
|
|
24263
24325
|
this.mipmapCount = Math.floor(mipmap ? Math.log2(width) : 1);
|
|
24264
24326
|
this.createTextureDescriptor(width, height, this.mipmapCount, this.format);
|
|
24327
|
+
if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
|
|
24328
|
+
const updateHeight = rowCount;
|
|
24329
|
+
const updateOffset = startRow * width * 4;
|
|
24330
|
+
const updateLength = updateHeight * width * 4;
|
|
24331
|
+
if (!this.uint16Array || this.uint16Array.length < updateOffset + updateLength) {
|
|
24332
|
+
if (!this.uint16Array || this.uint16Array.length < numbers.length) {
|
|
24333
|
+
this.uint16Array = new Uint16Array(numbers.length);
|
|
24334
|
+
}
|
|
24335
|
+
}
|
|
24336
|
+
const uint16Array2 = this.uint16Array;
|
|
24337
|
+
batchConvertToHalfFloat(numbers, uint16Array2, updateOffset, updateLength);
|
|
24338
|
+
const updateData = uint16Array2.subarray(updateOffset, updateOffset + updateLength);
|
|
24339
|
+
const neededSize2 = updateData.byteLength;
|
|
24340
|
+
if (!this._dataBuffer || this._dataBuffer.size < neededSize2) {
|
|
24341
|
+
this._dataBuffer && this._dataBuffer.destroy();
|
|
24342
|
+
this._dataBuffer = device.createBuffer({
|
|
24343
|
+
size: neededSize2,
|
|
24344
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
|
|
24345
|
+
});
|
|
24346
|
+
}
|
|
24347
|
+
device.queue.writeBuffer(this._dataBuffer, 0, updateData.buffer, updateData.byteOffset, updateData.byteLength);
|
|
24348
|
+
const commandEncoder2 = GPUContext.beginCommandEncoder();
|
|
24349
|
+
commandEncoder2.copyBufferToTexture(
|
|
24350
|
+
{
|
|
24351
|
+
buffer: this._dataBuffer,
|
|
24352
|
+
bytesPerRow,
|
|
24353
|
+
offset: 0
|
|
24354
|
+
},
|
|
24355
|
+
{
|
|
24356
|
+
texture: this.getGPUTexture(),
|
|
24357
|
+
origin: [0, startRow, 0]
|
|
24358
|
+
// Start at row startRow
|
|
24359
|
+
},
|
|
24360
|
+
{
|
|
24361
|
+
width,
|
|
24362
|
+
height: updateHeight,
|
|
24363
|
+
depthOrArrayLayers: 1
|
|
24364
|
+
}
|
|
24365
|
+
);
|
|
24366
|
+
if (!this.useMipmap) {
|
|
24367
|
+
this.samplerBindingLayout.type = `filtering`;
|
|
24368
|
+
this.textureBindingLayout.sampleType = `float`;
|
|
24369
|
+
}
|
|
24370
|
+
GPUContext.endCommandEncoder(commandEncoder2);
|
|
24371
|
+
return;
|
|
24372
|
+
}
|
|
24265
24373
|
if (!this.uint16Array || this.uint16Array.length != numbers.length) {
|
|
24266
24374
|
this.uint16Array = new Uint16Array(numbers.length);
|
|
24267
24375
|
}
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24376
|
+
const uint16Array = this.uint16Array;
|
|
24377
|
+
batchConvertToHalfFloat(numbers, uint16Array, 0, numbers.length);
|
|
24378
|
+
const neededSize = uint16Array.byteLength;
|
|
24379
|
+
if (!this._dataBuffer || this._dataBuffer.size < neededSize) {
|
|
24380
|
+
this._dataBuffer && this._dataBuffer.destroy();
|
|
24381
|
+
this._dataBuffer = device.createBuffer({
|
|
24382
|
+
size: neededSize,
|
|
24383
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
|
|
24384
|
+
});
|
|
24271
24385
|
}
|
|
24272
|
-
|
|
24273
|
-
size: uint16Array.byteLength,
|
|
24274
|
-
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
|
|
24275
|
-
});
|
|
24276
|
-
device.queue.writeBuffer(textureDataBuffer, 0, uint16Array);
|
|
24386
|
+
device.queue.writeBuffer(this._dataBuffer, 0, uint16Array.buffer, uint16Array.byteOffset, uint16Array.byteLength);
|
|
24277
24387
|
const commandEncoder = GPUContext.beginCommandEncoder();
|
|
24278
24388
|
commandEncoder.copyBufferToTexture(
|
|
24279
24389
|
{
|
|
24280
|
-
buffer:
|
|
24390
|
+
buffer: this._dataBuffer,
|
|
24281
24391
|
bytesPerRow
|
|
24282
24392
|
},
|
|
24283
24393
|
{
|
|
@@ -24300,6 +24410,30 @@ struct InstanceData {
|
|
|
24300
24410
|
}
|
|
24301
24411
|
}
|
|
24302
24412
|
|
|
24413
|
+
const _floatView = new Float32Array(1);
|
|
24414
|
+
const _int32View = new Int32Array(_floatView.buffer);
|
|
24415
|
+
let toHalfFloat = function(val) {
|
|
24416
|
+
_floatView[0] = val;
|
|
24417
|
+
const x = _int32View[0];
|
|
24418
|
+
let bits = x >> 16 & 32768;
|
|
24419
|
+
let m = x >> 12 & 2047;
|
|
24420
|
+
const e = x >> 23 & 255;
|
|
24421
|
+
if (e < 103) return bits;
|
|
24422
|
+
if (e > 142) {
|
|
24423
|
+
bits |= 31744;
|
|
24424
|
+
bits |= (e == 255 ? 1 : 0) && x & 8388607;
|
|
24425
|
+
return bits;
|
|
24426
|
+
}
|
|
24427
|
+
if (e < 114) {
|
|
24428
|
+
m |= 2048;
|
|
24429
|
+
bits |= (m >> 114 - e) + (m >> 113 - e & 1);
|
|
24430
|
+
return bits;
|
|
24431
|
+
}
|
|
24432
|
+
bits |= e - 112 << 10 | m >> 1;
|
|
24433
|
+
bits += m & 1;
|
|
24434
|
+
return bits;
|
|
24435
|
+
};
|
|
24436
|
+
|
|
24303
24437
|
var __getOwnPropDesc$m = Object.getOwnPropertyDescriptor;
|
|
24304
24438
|
var __decorateClass$m = (decorators, target, key, kind) => {
|
|
24305
24439
|
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$m(target, key) : target;
|
|
@@ -42158,7 +42292,7 @@ else if (typeof exports === 'object')
|
|
|
42158
42292
|
}
|
|
42159
42293
|
}
|
|
42160
42294
|
|
|
42161
|
-
const version = "1.0.
|
|
42295
|
+
const version = "1.0.38";
|
|
42162
42296
|
|
|
42163
42297
|
class Engine3D {
|
|
42164
42298
|
/**
|
|
@@ -54367,13 +54501,48 @@ fn frag(){
|
|
|
54367
54501
|
// Splat count and texture dimensions
|
|
54368
54502
|
totalCount = 0;
|
|
54369
54503
|
size = new Vector2();
|
|
54370
|
-
|
|
54504
|
+
localBoundBox = new BoundingBox();
|
|
54505
|
+
// public worldBoundBox: BoundingBox = new BoundingBox();
|
|
54506
|
+
get worldBoundBox() {
|
|
54507
|
+
const boundBox = new BoundingBox();
|
|
54508
|
+
boundBox.makeEmpty();
|
|
54509
|
+
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
54510
|
+
const m = worldMatrix.rawData;
|
|
54511
|
+
const localMin = this.localBoundBox.min;
|
|
54512
|
+
const localMax = this.localBoundBox.max;
|
|
54513
|
+
const corners = [
|
|
54514
|
+
[localMin.x, localMin.y, localMin.z],
|
|
54515
|
+
// 0: min, min, min
|
|
54516
|
+
[localMax.x, localMin.y, localMin.z],
|
|
54517
|
+
// 1: max, min, min
|
|
54518
|
+
[localMin.x, localMax.y, localMin.z],
|
|
54519
|
+
// 2: min, max, min
|
|
54520
|
+
[localMax.x, localMax.y, localMin.z],
|
|
54521
|
+
// 3: max, max, min
|
|
54522
|
+
[localMin.x, localMin.y, localMax.z],
|
|
54523
|
+
// 4: min, min, max
|
|
54524
|
+
[localMax.x, localMin.y, localMax.z],
|
|
54525
|
+
// 5: max, min, max
|
|
54526
|
+
[localMin.x, localMax.y, localMax.z],
|
|
54527
|
+
// 6: min, max, max
|
|
54528
|
+
[localMax.x, localMax.y, localMax.z]
|
|
54529
|
+
// 7: max, max, max
|
|
54530
|
+
];
|
|
54531
|
+
for (const [x, y, z] of corners) {
|
|
54532
|
+
const wx = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
54533
|
+
const wy = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
54534
|
+
const wz = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
54535
|
+
boundBox.expandByPoint(new Vector3(wx, wy, wz));
|
|
54536
|
+
}
|
|
54537
|
+
return boundBox;
|
|
54538
|
+
}
|
|
54371
54539
|
// GPU textures for splat data
|
|
54372
54540
|
splatColor;
|
|
54373
54541
|
transformA;
|
|
54374
54542
|
transformB;
|
|
54375
54543
|
texParams;
|
|
54376
54544
|
// [numSplats, texWidth, validCount, visBoost]
|
|
54545
|
+
_texParamDirty = true;
|
|
54377
54546
|
splatOrder;
|
|
54378
54547
|
// Material and geometry
|
|
54379
54548
|
gsplatMaterial;
|
|
@@ -54388,8 +54557,7 @@ fn frag(){
|
|
|
54388
54557
|
// R32U: size.x * size.y
|
|
54389
54558
|
_positions;
|
|
54390
54559
|
// xyz per splat (local space)
|
|
54391
|
-
_worldPositions;
|
|
54392
|
-
// xyz per splat (world space, cached)
|
|
54560
|
+
// private _worldPositions: Float32Array; // xyz per splat (world space, cached)
|
|
54393
54561
|
// Tracking which splats have been set
|
|
54394
54562
|
_splatSetFlags;
|
|
54395
54563
|
// Track which indices have data
|
|
@@ -54449,8 +54617,7 @@ fn frag(){
|
|
|
54449
54617
|
}
|
|
54450
54618
|
this._positions = new Float32Array(totalCount * 3);
|
|
54451
54619
|
this._positions.fill(0);
|
|
54452
|
-
this.
|
|
54453
|
-
this._worldPositions.fill(0);
|
|
54620
|
+
this.localBoundBox.makeEmpty();
|
|
54454
54621
|
this._splatSetFlags = new Array(totalCount).fill(false);
|
|
54455
54622
|
this._validCount = 0;
|
|
54456
54623
|
this.texParams = new Float32Array([this._validCount, this.size.x, 0, 1]);
|
|
@@ -54499,6 +54666,7 @@ fn frag(){
|
|
|
54499
54666
|
this._positions[index * 3 + 0] = data.position[0];
|
|
54500
54667
|
this._positions[index * 3 + 1] = data.position[1];
|
|
54501
54668
|
this._positions[index * 3 + 2] = data.position[2];
|
|
54669
|
+
this.localBoundBox.expandByPoint(new Vector3(data.position[0], data.position[1], data.position[2]));
|
|
54502
54670
|
const SH_C0 = 0.28209479177387814;
|
|
54503
54671
|
let r = 0.5, g = 0.5, b = 0.5;
|
|
54504
54672
|
if (data.sh && data.sh.coeffs && data.sh.coeffs.length >= 3) {
|
|
@@ -54516,8 +54684,6 @@ fn frag(){
|
|
|
54516
54684
|
if (!wasSet) {
|
|
54517
54685
|
this._splatSetFlags[index] = true;
|
|
54518
54686
|
this._validCount++;
|
|
54519
|
-
this.texParams[2] = this._validCount;
|
|
54520
|
-
this._centersSent = false;
|
|
54521
54687
|
}
|
|
54522
54688
|
this._pendingUpdates.add(index);
|
|
54523
54689
|
}
|
|
@@ -54605,14 +54771,32 @@ fn frag(){
|
|
|
54605
54771
|
/**
|
|
54606
54772
|
* Flush pending updates to GPU
|
|
54607
54773
|
* Updates GPU textures with all pending changes
|
|
54774
|
+
* Uses partial updates when possible for better performance
|
|
54608
54775
|
*/
|
|
54609
54776
|
flushUpdates() {
|
|
54610
54777
|
if (this._pendingUpdates.size === 0) return;
|
|
54611
54778
|
const w = this.size.x | 0;
|
|
54612
54779
|
const h = this.size.y | 0;
|
|
54613
|
-
|
|
54614
|
-
|
|
54615
|
-
|
|
54780
|
+
const pendingIndices = Array.from(this._pendingUpdates);
|
|
54781
|
+
if (pendingIndices.length === 0) return;
|
|
54782
|
+
let minRow = h;
|
|
54783
|
+
let maxRow = 0;
|
|
54784
|
+
for (const index of pendingIndices) {
|
|
54785
|
+
const row = Math.floor(index / w);
|
|
54786
|
+
if (row < minRow) minRow = row;
|
|
54787
|
+
if (row > maxRow) maxRow = row;
|
|
54788
|
+
}
|
|
54789
|
+
const rowCount = maxRow - minRow + 1;
|
|
54790
|
+
const updateRatio = rowCount / h;
|
|
54791
|
+
if (updateRatio < 0.5 && rowCount < h) {
|
|
54792
|
+
this.splatColor.updateTexture(w, h, this._colorData, minRow, rowCount);
|
|
54793
|
+
this.transformA.updateTexture(w, h, this._transformAData, minRow, rowCount);
|
|
54794
|
+
this.transformB.updateTexture(w, h, this._transformBData, false, minRow, rowCount);
|
|
54795
|
+
} else {
|
|
54796
|
+
this.splatColor.updateTexture(w, h, this._colorData);
|
|
54797
|
+
this.transformA.updateTexture(w, h, this._transformAData);
|
|
54798
|
+
this.transformB.updateTexture(w, h, this._transformBData, false);
|
|
54799
|
+
}
|
|
54616
54800
|
this.updatePendingWorldPositions();
|
|
54617
54801
|
this._pendingUpdates.clear();
|
|
54618
54802
|
}
|
|
@@ -54638,55 +54822,22 @@ fn frag(){
|
|
|
54638
54822
|
* Update splat sorting before rendering
|
|
54639
54823
|
* Uses the same logic as GSplatRenderer for reliable sorting
|
|
54640
54824
|
*/
|
|
54641
|
-
onBeforeUpdate(view) {
|
|
54642
|
-
|
|
54643
|
-
|
|
54644
|
-
|
|
54645
|
-
|
|
54646
|
-
|
|
54647
|
-
}
|
|
54825
|
+
// public onBeforeUpdate(view?: View3D) {
|
|
54826
|
+
// if (this._validCount > 0 && view?.camera) {
|
|
54827
|
+
// if (view.camera.viewMatrix) {
|
|
54828
|
+
// this.scheduleOrder(view.camera.viewMatrix);
|
|
54829
|
+
// }
|
|
54830
|
+
// }
|
|
54831
|
+
// }
|
|
54648
54832
|
/**
|
|
54649
54833
|
* Update world space positions when transform changes
|
|
54650
54834
|
*/
|
|
54651
54835
|
updateWorldPositions() {
|
|
54652
54836
|
if (!this._positions || this._validCount === 0) return;
|
|
54653
|
-
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
54654
|
-
const localPos = this._positions;
|
|
54655
|
-
const count = this._validCount;
|
|
54656
|
-
const m = worldMatrix.rawData;
|
|
54657
|
-
this.worldBoundBox.makeEmpty();
|
|
54658
|
-
for (let i = 0; i < count; i++) {
|
|
54659
|
-
if (!this._splatSetFlags[i]) continue;
|
|
54660
|
-
const idx = i * 3;
|
|
54661
|
-
const x = localPos[idx + 0];
|
|
54662
|
-
const y = localPos[idx + 1];
|
|
54663
|
-
const z = localPos[idx + 2];
|
|
54664
|
-
this._worldPositions[idx + 0] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
54665
|
-
this._worldPositions[idx + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
54666
|
-
this._worldPositions[idx + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
54667
|
-
this.worldBoundBox.expandByPoint(new Vector3(this._worldPositions[idx + 0], this._worldPositions[idx + 1], this._worldPositions[idx + 2]));
|
|
54668
|
-
}
|
|
54669
54837
|
this._centersSent = false;
|
|
54670
54838
|
}
|
|
54671
54839
|
updatePendingWorldPositions() {
|
|
54672
54840
|
if (!this._positions || this._validCount === 0) return;
|
|
54673
|
-
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
54674
|
-
const localPos = this._positions;
|
|
54675
|
-
this._validCount;
|
|
54676
|
-
const m = worldMatrix.rawData;
|
|
54677
|
-
const pendingUpdates = Array.from(this._pendingUpdates.values());
|
|
54678
|
-
for (let i = 0; i < pendingUpdates.length; i++) {
|
|
54679
|
-
const ii = pendingUpdates[i];
|
|
54680
|
-
if (!this._splatSetFlags[ii]) continue;
|
|
54681
|
-
const idx = ii * 3;
|
|
54682
|
-
const x = localPos[idx + 0];
|
|
54683
|
-
const y = localPos[idx + 1];
|
|
54684
|
-
const z = localPos[idx + 2];
|
|
54685
|
-
this._worldPositions[idx + 0] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
54686
|
-
this._worldPositions[idx + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
54687
|
-
this._worldPositions[idx + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
54688
|
-
this.worldBoundBox.expandByPoint(new Vector3(this._worldPositions[idx + 0], this._worldPositions[idx + 1], this._worldPositions[idx + 2]));
|
|
54689
|
-
}
|
|
54690
54841
|
this._centersSent = false;
|
|
54691
54842
|
}
|
|
54692
54843
|
/**
|
|
@@ -54696,7 +54847,7 @@ fn frag(){
|
|
|
54696
54847
|
scheduleOrder(viewMatrix) {
|
|
54697
54848
|
if (this._validCount === 0) return;
|
|
54698
54849
|
const transformChanged = this.object3D.transform.localChange;
|
|
54699
|
-
if (transformChanged
|
|
54850
|
+
if (transformChanged) {
|
|
54700
54851
|
this.updateWorldPositions();
|
|
54701
54852
|
}
|
|
54702
54853
|
const r = viewMatrix.rawData;
|
|
@@ -54751,21 +54902,25 @@ fn frag(){
|
|
|
54751
54902
|
}
|
|
54752
54903
|
this.splatOrder.updateTexture(this.size.x, this.size.y, this._orderData);
|
|
54753
54904
|
const valid = Math.max(0, Math.min(this._validCount, ev.data.count | 0));
|
|
54754
|
-
this.
|
|
54755
|
-
this.texParams[0] = valid;
|
|
54905
|
+
this.setCount(valid);
|
|
54756
54906
|
this._updateTexParams();
|
|
54757
54907
|
const newInstanceCount = Math.ceil(valid / this._batchSize);
|
|
54758
54908
|
this.instanceCount = newInstanceCount;
|
|
54759
54909
|
};
|
|
54760
54910
|
const centers = new Float32Array(this._validCount * 3);
|
|
54761
|
-
const worldPos = this._worldPositions || this._positions;
|
|
54762
54911
|
let centerIdx = 0;
|
|
54912
|
+
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
54913
|
+
const localPos = this._positions;
|
|
54914
|
+
const m = worldMatrix.rawData;
|
|
54763
54915
|
for (let i = 0; i < this._validCount; i++) {
|
|
54764
54916
|
if (this._splatSetFlags[i]) {
|
|
54765
54917
|
const srcIdx = i * 3;
|
|
54766
|
-
|
|
54767
|
-
|
|
54768
|
-
|
|
54918
|
+
const x = localPos[srcIdx + 0];
|
|
54919
|
+
const y = localPos[srcIdx + 1];
|
|
54920
|
+
const z = localPos[srcIdx + 2];
|
|
54921
|
+
centers[centerIdx * 3 + 0] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
54922
|
+
centers[centerIdx * 3 + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
54923
|
+
centers[centerIdx * 3 + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
54769
54924
|
centerIdx++;
|
|
54770
54925
|
}
|
|
54771
54926
|
}
|
|
@@ -54781,14 +54936,19 @@ fn frag(){
|
|
|
54781
54936
|
}
|
|
54782
54937
|
if (!this._centersSent && this._sortWorker) {
|
|
54783
54938
|
const centers = new Float32Array(this._validCount * 3);
|
|
54784
|
-
const worldPos = this._worldPositions || this._positions;
|
|
54785
54939
|
let centerIdx = 0;
|
|
54940
|
+
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
54941
|
+
const localPos = this._positions;
|
|
54942
|
+
const m = worldMatrix.rawData;
|
|
54786
54943
|
for (let i = 0; i < this._validCount; i++) {
|
|
54787
54944
|
if (this._splatSetFlags[i]) {
|
|
54788
54945
|
const srcIdx = i * 3;
|
|
54789
|
-
|
|
54790
|
-
|
|
54791
|
-
|
|
54946
|
+
const x = localPos[srcIdx + 0];
|
|
54947
|
+
const y = localPos[srcIdx + 1];
|
|
54948
|
+
const z = localPos[srcIdx + 2];
|
|
54949
|
+
centers[centerIdx * 3 + 0] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
54950
|
+
centers[centerIdx * 3 + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
54951
|
+
centers[centerIdx * 3 + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
54792
54952
|
centerIdx++;
|
|
54793
54953
|
}
|
|
54794
54954
|
}
|
|
@@ -54948,12 +55108,17 @@ fn frag(){
|
|
|
54948
55108
|
*/
|
|
54949
55109
|
setVisBoost(v) {
|
|
54950
55110
|
this.texParams[3] = Math.max(0, v);
|
|
55111
|
+
this._texParamDirty = true;
|
|
54951
55112
|
}
|
|
54952
55113
|
setCount(c) {
|
|
54953
55114
|
this.texParams[0] = Math.max(0, c);
|
|
55115
|
+
this._texParamDirty = true;
|
|
54954
55116
|
}
|
|
54955
55117
|
_updateTexParams() {
|
|
54956
|
-
|
|
55118
|
+
if (this._texParamDirty) {
|
|
55119
|
+
this.gsplatMaterial.setTexParams(this.texParams);
|
|
55120
|
+
this._texParamDirty = false;
|
|
55121
|
+
}
|
|
54957
55122
|
}
|
|
54958
55123
|
/**
|
|
54959
55124
|
* Set sort throttle interval (milliseconds)
|
|
@@ -55013,6 +55178,11 @@ fn frag(){
|
|
|
55013
55178
|
* Update node before rendering
|
|
55014
55179
|
*/
|
|
55015
55180
|
nodeUpdate(view, passType, renderPassState, clusterLightingBuffer) {
|
|
55181
|
+
if (this._validCount > 0 && view?.camera) {
|
|
55182
|
+
if (view.camera.viewMatrix) {
|
|
55183
|
+
this.scheduleOrder(view.camera.viewMatrix);
|
|
55184
|
+
}
|
|
55185
|
+
}
|
|
55016
55186
|
if (this._pendingUpdates.size > 0 && this._frameCount >= 60) {
|
|
55017
55187
|
this.flushUpdates();
|
|
55018
55188
|
}
|
|
@@ -55020,6 +55190,7 @@ fn frag(){
|
|
|
55020
55190
|
this._frameCount = 0;
|
|
55021
55191
|
}
|
|
55022
55192
|
this._frameCount++;
|
|
55193
|
+
this._updateTexParams();
|
|
55023
55194
|
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
55024
55195
|
this.gsplatMaterial.setTransformMatrix(worldMatrix);
|
|
55025
55196
|
const currentParams = `${this._minPixelCoverage},${this._maxPixelCoverage},${this._maxPixelCullDistance},${this._batchSize}`;
|
|
@@ -55101,7 +55272,6 @@ fn frag(){
|
|
|
55101
55272
|
this.splatOrder = null;
|
|
55102
55273
|
}
|
|
55103
55274
|
this._positions = null;
|
|
55104
|
-
this._worldPositions = null;
|
|
55105
55275
|
this._orderData = null;
|
|
55106
55276
|
this._colorData = null;
|
|
55107
55277
|
this._transformAData = null;
|
|
@@ -29,11 +29,13 @@ export type SplatData = {
|
|
|
29
29
|
export declare class GSplatStreamRenderer extends RenderNode {
|
|
30
30
|
totalCount: number;
|
|
31
31
|
size: Vector2;
|
|
32
|
-
|
|
32
|
+
localBoundBox: BoundingBox;
|
|
33
|
+
get worldBoundBox(): BoundingBox;
|
|
33
34
|
splatColor: Uint8ArrayTexture;
|
|
34
35
|
transformA: Uint32ArrayTexture;
|
|
35
36
|
transformB: Float16ArrayTexture;
|
|
36
37
|
texParams: Float32Array;
|
|
38
|
+
private _texParamDirty;
|
|
37
39
|
splatOrder: R32UintTexture;
|
|
38
40
|
gsplatMaterial: GSplatMaterial;
|
|
39
41
|
private _colorData;
|
|
@@ -41,7 +43,6 @@ export declare class GSplatStreamRenderer extends RenderNode {
|
|
|
41
43
|
private _transformBData;
|
|
42
44
|
private _orderData;
|
|
43
45
|
private _positions;
|
|
44
|
-
private _worldPositions;
|
|
45
46
|
private _splatSetFlags;
|
|
46
47
|
private _validCount;
|
|
47
48
|
private _sortWorker;
|
|
@@ -83,6 +84,7 @@ export declare class GSplatStreamRenderer extends RenderNode {
|
|
|
83
84
|
/**
|
|
84
85
|
* Flush pending updates to GPU
|
|
85
86
|
* Updates GPU textures with all pending changes
|
|
87
|
+
* Uses partial updates when possible for better performance
|
|
86
88
|
*/
|
|
87
89
|
flushUpdates(): void;
|
|
88
90
|
/**
|
|
@@ -103,7 +105,6 @@ export declare class GSplatStreamRenderer extends RenderNode {
|
|
|
103
105
|
* Update splat sorting before rendering
|
|
104
106
|
* Uses the same logic as GSplatRenderer for reliable sorting
|
|
105
107
|
*/
|
|
106
|
-
onBeforeUpdate(view?: View3D): void;
|
|
107
108
|
/**
|
|
108
109
|
* Update world space positions when transform changes
|
|
109
110
|
*/
|
|
@@ -23,6 +23,8 @@ export declare class Float16ArrayTexture extends Texture {
|
|
|
23
23
|
* @param height 纹理高度
|
|
24
24
|
* @param numbers 像素数据数组
|
|
25
25
|
* @param mipmap 是否生成Mipmap
|
|
26
|
+
* @param startRow 起始行(部分更新)
|
|
27
|
+
* @param rowCount 更新的行数(部分更新)
|
|
26
28
|
*/
|
|
27
|
-
updateTexture(width: number, height: number, numbers: number[], mipmap?: boolean): void;
|
|
29
|
+
updateTexture(width: number, height: number, numbers: number[], mipmap?: boolean, startRow?: number, rowCount?: number): void;
|
|
28
30
|
}
|
|
@@ -7,5 +7,5 @@ import { Texture } from "../gfx/graphics/webGpu/core/texture/Texture";
|
|
|
7
7
|
export declare class Uint32ArrayTexture extends Texture {
|
|
8
8
|
private _dataBuffer;
|
|
9
9
|
create(width: number, height: number, data: Uint32Array): this;
|
|
10
|
-
updateTexture(width: number, height: number, data: Uint32Array): void;
|
|
10
|
+
updateTexture(width: number, height: number, data: Uint32Array, startRow?: number, rowCount?: number): void;
|
|
11
11
|
}
|
|
@@ -2,5 +2,5 @@ import { Texture } from "../gfx/graphics/webGpu/core/texture/Texture";
|
|
|
2
2
|
export declare class Uint8ArrayTexture extends Texture {
|
|
3
3
|
private _dataBuffer;
|
|
4
4
|
create(width: number, height: number, data: Uint8Array, useMipmap?: boolean): this;
|
|
5
|
-
updateTexture(width: number, height: number, data: Uint8Array): void;
|
|
5
|
+
updateTexture(width: number, height: number, data: Uint8Array, startRow?: number, rowCount?: number): void;
|
|
6
6
|
}
|