@rings-webgpu/core 1.0.12 → 1.0.14
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 +313 -353
- package/dist/rings.es.js.map +3 -3
- package/dist/rings.es.max.js +495 -347
- package/dist/rings.umd.js +308 -348
- package/dist/rings.umd.js.map +3 -3
- package/dist/rings.umd.max.js +496 -346
- package/dist/types/components/anim/morphAnim/MorphTargetData.d.ts +1 -0
- package/dist/types/components/renderer/GSplatRenderer.d.ts +16 -5
- package/dist/types/gfx/renderJob/jobs/RendererJob.d.ts +2 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/materials/GSplatMaterial.d.ts +4 -2
- package/dist/types/shape/GSplatGeometry.d.ts +13 -0
- package/dist/types/textures/R32UintTexture.d.ts +11 -0
- package/package.json +1 -1
package/dist/rings.umd.max.js
CHANGED
|
@@ -22685,140 +22685,119 @@ struct InstanceData {
|
|
|
22685
22685
|
/* wgsl */
|
|
22686
22686
|
`
|
|
22687
22687
|
#include "GlobalUniform"
|
|
22688
|
-
|
|
22689
|
-
struct VSOut {
|
|
22690
|
-
@location(auto) vColor : vec4f,
|
|
22691
|
-
@location(auto) vTexCoord : vec2f,
|
|
22692
|
-
@builtin(position) member : vec4f
|
|
22693
|
-
};
|
|
22694
|
-
|
|
22695
|
-
// ===== SPLAT CORE VS (from PlayCanvas shader-generator-gsplat.js) =====
|
|
22696
|
-
|
|
22697
|
-
// Uniforms (mapped to WebGPU bindings)
|
|
22698
|
-
// matrix_model, matrix_view, matrix_projection -> GlobalUniform + MaterialUniform
|
|
22699
|
-
// viewport -> calculated from globalUniform.windowWidth/Height
|
|
22700
|
-
// tex_params -> materialUniform.tex_params
|
|
22701
22688
|
|
|
22702
|
-
|
|
22703
|
-
|
|
22704
|
-
|
|
22705
|
-
|
|
22689
|
+
// Constants
|
|
22690
|
+
const ALPHA_THRESHOLD: f32 = 0.00392156863; // 1.0 / 255.0
|
|
22691
|
+
const COV_COMPENSATION: f32 = 0.3;
|
|
22692
|
+
const MAX_SPLAT_SIZE: f32 = 1024.0;
|
|
22693
|
+
const MIN_LAMBDA: f32 = 0.1;
|
|
22694
|
+
const LOG_255: f32 = 5.541263545; // log(255.0) - natural log for WGSL
|
|
22706
22695
|
|
|
22707
22696
|
struct MaterialUniform {
|
|
22708
|
-
tex_params: vec4f, // numSplats, textureWidth, validCount, visBoost
|
|
22709
22697
|
modelMatrix: mat4x4<f32>,
|
|
22710
|
-
|
|
22698
|
+
tex_params: vec4<f32>, // [numSplats, texWidth, validCount, visBoost]
|
|
22699
|
+
pixelCull: vec4<f32>, // [minPixels, maxPixels, maxPixelCullDistance, batchSize]
|
|
22700
|
+
};
|
|
22701
|
+
@group(1) @binding(0) var<uniform> materialUniform: MaterialUniform;
|
|
22702
|
+
|
|
22703
|
+
struct VSOut {
|
|
22704
|
+
@builtin(position) member: vec4<f32>,
|
|
22705
|
+
@location(0) vColor: vec4<f32>,
|
|
22706
|
+
@location(1) vTexCoord: vec2<f32>,
|
|
22711
22707
|
};
|
|
22712
|
-
@group(1) @binding(3) var<uniform> materialUniform : MaterialUniform;
|
|
22713
22708
|
|
|
22714
|
-
//
|
|
22715
|
-
var
|
|
22716
|
-
var
|
|
22717
|
-
var
|
|
22718
|
-
var
|
|
22709
|
+
// Textures (like PlayCanvas)
|
|
22710
|
+
@group(1) @binding(1) var splatColor: texture_2d<f32>;
|
|
22711
|
+
@group(1) @binding(2) var transformA: texture_2d<u32>;
|
|
22712
|
+
@group(1) @binding(3) var transformB: texture_2d<f32>;
|
|
22713
|
+
@group(1) @binding(4) var splatOrder: texture_2d<u32>;
|
|
22719
22714
|
|
|
22720
|
-
|
|
22721
|
-
|
|
22722
|
-
|
|
22723
|
-
|
|
22724
|
-
|
|
22725
|
-
|
|
22726
|
-
|
|
22727
|
-
|
|
22728
|
-
|
|
22729
|
-
|
|
22730
|
-
|
|
22731
|
-
|
|
22732
|
-
|
|
22733
|
-
}
|
|
22715
|
+
struct SplatData {
|
|
22716
|
+
center: vec3f,
|
|
22717
|
+
covA: vec3f,
|
|
22718
|
+
covB: vec3f,
|
|
22719
|
+
};
|
|
22720
|
+
|
|
22721
|
+
// Helper function to discard splat
|
|
22722
|
+
fn discardSplat() -> VSOut {
|
|
22723
|
+
var o: VSOut;
|
|
22724
|
+
o.member = vec4f(0.0, 0.0, 2.0, 1.0);
|
|
22725
|
+
o.vColor = vec4f(0.0);
|
|
22726
|
+
o.vTexCoord = vec2f(0.0);
|
|
22727
|
+
return o;
|
|
22734
22728
|
}
|
|
22735
22729
|
|
|
22736
|
-
// === calcSplatUV() - returns
|
|
22737
|
-
fn calcSplatUV(
|
|
22738
|
-
let numSplats = u32(materialUniform.tex_params.x);
|
|
22739
|
-
let textureWidth = u32(materialUniform.tex_params.y);
|
|
22740
|
-
|
|
22741
|
-
// calculate splat index
|
|
22742
|
-
orderId = instance_id;
|
|
22743
|
-
|
|
22744
|
-
if (orderId >= numSplats) {
|
|
22745
|
-
return false;
|
|
22746
|
-
}
|
|
22747
|
-
|
|
22730
|
+
// === calcSplatUV() - returns optional UV ===
|
|
22731
|
+
fn calcSplatUV(orderId: u32, textureWidth: u32, numSplats: u32) -> vec2<i32> {
|
|
22748
22732
|
let orderUV = vec2<i32>(
|
|
22749
22733
|
i32(orderId % textureWidth),
|
|
22750
22734
|
i32(orderId / textureWidth)
|
|
22751
22735
|
);
|
|
22752
22736
|
|
|
22753
|
-
|
|
22754
|
-
|
|
22755
|
-
splatUV = vec2<i32>(
|
|
22737
|
+
let splatId = textureLoad(splatOrder, orderUV, 0).r;
|
|
22738
|
+
return vec2<i32>(
|
|
22756
22739
|
i32(splatId % textureWidth),
|
|
22757
22740
|
i32(splatId / textureWidth)
|
|
22758
22741
|
);
|
|
22759
|
-
|
|
22760
|
-
return true;
|
|
22761
22742
|
}
|
|
22762
22743
|
|
|
22763
|
-
// ===
|
|
22764
|
-
fn
|
|
22765
|
-
|
|
22766
|
-
return vec3f(bitcast<f32>(tA.x), bitcast<f32>(tA.y), bitcast<f32>(tA.z));
|
|
22767
|
-
}
|
|
22768
|
-
|
|
22769
|
-
// Struct to return covA and covB
|
|
22770
|
-
struct CovarianceData {
|
|
22771
|
-
covA: vec3f,
|
|
22772
|
-
covB: vec3f,
|
|
22773
|
-
};
|
|
22774
|
-
|
|
22775
|
-
// === getCovariance() - returns struct ===
|
|
22776
|
-
fn getCovariance() -> CovarianceData {
|
|
22777
|
-
let tB = textureLoad(transformB, splatUV, 0);
|
|
22744
|
+
// === getSplatData() - unified texture loading ===
|
|
22745
|
+
fn getSplatData(splatUV: vec2<i32>) -> SplatData {
|
|
22746
|
+
var data: SplatData;
|
|
22778
22747
|
|
|
22779
|
-
//
|
|
22748
|
+
// Load both textures once
|
|
22749
|
+
let tA = textureLoad(transformA, splatUV, 0);
|
|
22750
|
+
let tB = textureLoad(transformB, splatUV, 0);
|
|
22780
22751
|
let tC = unpack2x16float(tA.w);
|
|
22781
22752
|
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
result.covB = vec3f(tC.x, tC.y, tB.w);
|
|
22753
|
+
// Extract center
|
|
22754
|
+
data.center = vec3f(bitcast<f32>(tA.x), bitcast<f32>(tA.y), bitcast<f32>(tA.z));
|
|
22785
22755
|
|
|
22786
|
-
|
|
22756
|
+
// Extract covariance
|
|
22757
|
+
data.covA = tB.xyz;
|
|
22758
|
+
data.covB = vec3f(tC.x, tC.y, tB.w);
|
|
22759
|
+
|
|
22760
|
+
return data;
|
|
22787
22761
|
}
|
|
22788
22762
|
|
|
22789
22763
|
// === calcV1V2() - returns vec4 ===
|
|
22790
22764
|
fn calcV1V2(splat_cam: vec3f, covA: vec3f, covB: vec3f, W: mat3x3f, viewport: vec2f, projMat: mat4x4f) -> vec4f {
|
|
22765
|
+
// Construct symmetric covariance matrix
|
|
22791
22766
|
let Vrk = mat3x3f(
|
|
22792
22767
|
vec3f(covA.x, covA.y, covA.z),
|
|
22793
22768
|
vec3f(covA.y, covB.x, covB.y),
|
|
22794
22769
|
vec3f(covA.z, covB.y, covB.z)
|
|
22795
22770
|
);
|
|
22796
22771
|
|
|
22772
|
+
// Calculate Jacobian
|
|
22797
22773
|
let focal = viewport.x * projMat[0][0];
|
|
22798
|
-
|
|
22799
|
-
let J1 = focal
|
|
22800
|
-
let J2 = -J1
|
|
22774
|
+
let inv_z = 1.0 / splat_cam.z;
|
|
22775
|
+
let J1 = focal * inv_z;
|
|
22776
|
+
let J2 = -J1 * inv_z * splat_cam.xy;
|
|
22801
22777
|
let J = mat3x3f(
|
|
22802
22778
|
vec3f(J1, 0.0, J2.x),
|
|
22803
22779
|
vec3f(0.0, J1, J2.y),
|
|
22804
22780
|
vec3f(0.0, 0.0, 0.0)
|
|
22805
22781
|
);
|
|
22806
22782
|
|
|
22783
|
+
// Project covariance to screen space
|
|
22807
22784
|
let T = W * J;
|
|
22808
22785
|
let cov = transpose(T) * Vrk * T;
|
|
22809
22786
|
|
|
22810
|
-
|
|
22787
|
+
// Eigenvalue decomposition with compensation
|
|
22788
|
+
let diagonal1 = cov[0][0] + COV_COMPENSATION;
|
|
22811
22789
|
let offDiagonal = cov[0][1];
|
|
22812
|
-
let diagonal2 = cov[1][1] +
|
|
22790
|
+
let diagonal2 = cov[1][1] + COV_COMPENSATION;
|
|
22813
22791
|
|
|
22814
22792
|
let mid = 0.5 * (diagonal1 + diagonal2);
|
|
22815
|
-
let radius = length(vec2f((diagonal1 - diagonal2)
|
|
22793
|
+
let radius = length(vec2f((diagonal1 - diagonal2) * 0.5, offDiagonal));
|
|
22816
22794
|
let lambda1 = mid + radius;
|
|
22817
|
-
let lambda2 = max(mid - radius,
|
|
22795
|
+
let lambda2 = max(mid - radius, MIN_LAMBDA);
|
|
22818
22796
|
let diagonalVector = normalize(vec2f(offDiagonal, lambda1 - diagonal1));
|
|
22819
22797
|
|
|
22820
|
-
|
|
22821
|
-
let
|
|
22798
|
+
// Calculate axis vectors with size clamping
|
|
22799
|
+
let v1 = min(sqrt(2.0 * lambda1), MAX_SPLAT_SIZE) * diagonalVector;
|
|
22800
|
+
let v2 = min(sqrt(2.0 * lambda2), MAX_SPLAT_SIZE) * vec2f(diagonalVector.y, -diagonalVector.x);
|
|
22822
22801
|
|
|
22823
22802
|
// WebGPU Y-axis flip: WebGPU NDC Y goes from top(-1) to bottom(1), opposite of WebGL
|
|
22824
22803
|
return vec4f(v1.x, -v1.y, v2.x, -v2.y);
|
|
@@ -22829,117 +22808,100 @@ struct InstanceData {
|
|
|
22829
22808
|
@vertex
|
|
22830
22809
|
fn VertMain(
|
|
22831
22810
|
@builtin(vertex_index) vid : u32,
|
|
22832
|
-
@builtin(instance_index) iid : u32
|
|
22811
|
+
@builtin(instance_index) iid : u32,
|
|
22812
|
+
@location(0) position: vec3<f32> // vertex_position from mesh (x, y, local_index)
|
|
22833
22813
|
) -> VSOut {
|
|
22834
|
-
|
|
22835
|
-
let
|
|
22836
|
-
|
|
22837
|
-
// Vertex position array (PlayCanvas uses attribute vec3 with x,y in [-1,1])
|
|
22838
|
-
let vertex_position = array<vec2f, 4>(
|
|
22839
|
-
vec2f(-2.0, -2.0),
|
|
22840
|
-
vec2f( 2.0, -2.0),
|
|
22841
|
-
vec2f(-2.0, 2.0),
|
|
22842
|
-
vec2f( 2.0, 2.0)
|
|
22843
|
-
);
|
|
22844
|
-
let vertex_pos = vertex_position[vid & 3u];
|
|
22814
|
+
// Calculate splat ID
|
|
22815
|
+
let batchSize = u32(materialUniform.pixelCull.w);
|
|
22816
|
+
let orderId = iid * batchSize + u32(position.z);
|
|
22845
22817
|
|
|
22846
|
-
//
|
|
22847
|
-
|
|
22848
|
-
|
|
22849
|
-
|
|
22850
|
-
|
|
22851
|
-
return o;
|
|
22818
|
+
// Early bounds check
|
|
22819
|
+
let textureWidth = u32(materialUniform.tex_params.y);
|
|
22820
|
+
let numSplats = u32(materialUniform.tex_params.x);
|
|
22821
|
+
if (orderId >= numSplats) {
|
|
22822
|
+
return discardSplat();
|
|
22852
22823
|
}
|
|
22853
22824
|
|
|
22854
|
-
//
|
|
22855
|
-
let
|
|
22825
|
+
// Calculate splat UV and load all data in one go
|
|
22826
|
+
let splatUV = calcSplatUV(orderId, textureWidth, numSplats);
|
|
22827
|
+
let splatData = getSplatData(splatUV);
|
|
22828
|
+
|
|
22829
|
+
// Load color early for alpha test
|
|
22830
|
+
let color = textureLoad(splatColor, splatUV, 0);
|
|
22831
|
+
if (color.a < ALPHA_THRESHOLD) {
|
|
22832
|
+
return discardSplat();
|
|
22833
|
+
}
|
|
22856
22834
|
|
|
22857
|
-
//
|
|
22835
|
+
// Transform matrices
|
|
22836
|
+
let matrix_model = materialUniform.modelMatrix;
|
|
22858
22837
|
let matrix_view = globalUniform.viewMat;
|
|
22859
22838
|
let matrix_projection = globalUniform.projMat;
|
|
22860
|
-
let matrix_model = materialUniform.modelMatrix;
|
|
22861
|
-
|
|
22862
22839
|
let model_view = matrix_view * matrix_model;
|
|
22863
|
-
let splat_cam = model_view * vec4f(center, 1.0);
|
|
22864
|
-
let splat_proj = matrix_projection * splat_cam;
|
|
22865
22840
|
|
|
22866
|
-
//
|
|
22867
|
-
|
|
22868
|
-
|
|
22869
|
-
|
|
22870
|
-
|
|
22871
|
-
return
|
|
22841
|
+
// Transform center to camera and clip space
|
|
22842
|
+
let splat_cam = model_view * vec4f(splatData.center, 1.0);
|
|
22843
|
+
|
|
22844
|
+
// Early depth culling
|
|
22845
|
+
if (splat_cam.z <= 0.0) {
|
|
22846
|
+
return discardSplat();
|
|
22872
22847
|
}
|
|
22873
22848
|
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
22877
|
-
let
|
|
22878
|
-
|
|
22879
|
-
|
|
22849
|
+
let splat_proj = matrix_projection * splat_cam;
|
|
22850
|
+
|
|
22851
|
+
// Frustum culling with NDC check
|
|
22852
|
+
let inv_w = 1.0 / splat_proj.w;
|
|
22853
|
+
let ndc = splat_proj.xyz * inv_w;
|
|
22854
|
+
if (ndc.x < -1.0 || ndc.x > 1.0 ||
|
|
22855
|
+
ndc.y < -1.0 || ndc.y > 1.0 ||
|
|
22880
22856
|
ndc.z < 0.0 || ndc.z > 1.0) {
|
|
22881
|
-
|
|
22882
|
-
o.vColor = vec4f(0.0);
|
|
22883
|
-
o.vTexCoord = vec2f(0.0);
|
|
22884
|
-
return o;
|
|
22857
|
+
return discardSplat();
|
|
22885
22858
|
}
|
|
22886
22859
|
|
|
22887
|
-
//
|
|
22888
|
-
let cov_data = getCovariance();
|
|
22889
|
-
|
|
22860
|
+
// Calculate v1v2 (screen-space ellipse axes)
|
|
22890
22861
|
let viewport = vec2f(globalUniform.windowWidth, globalUniform.windowHeight);
|
|
22891
|
-
let
|
|
22862
|
+
let W = transpose(mat3x3f(model_view[0].xyz, model_view[1].xyz, model_view[2].xyz));
|
|
22863
|
+
let v1v2 = calcV1V2(splat_cam.xyz, splatData.covA, splatData.covB, W, viewport, matrix_projection);
|
|
22892
22864
|
|
|
22893
|
-
//
|
|
22894
|
-
let
|
|
22895
|
-
|
|
22896
|
-
// calculate scale based on alpha
|
|
22897
|
-
let scale = min(1.0, sqrt(-log(1.0 / 255.0 / color.a)) / 2.0);
|
|
22865
|
+
// Calculate scale based on alpha (optimized formula)
|
|
22866
|
+
let scale = min(1.0, sqrt(LOG_255 + log(color.a)) * 0.5);
|
|
22898
22867
|
|
|
22899
|
-
//
|
|
22868
|
+
// Apply visBoost (size multiplier)
|
|
22900
22869
|
let visBoost = materialUniform.tex_params.w;
|
|
22901
|
-
|
|
22870
|
+
let v1v2_scaled = v1v2 * (scale * visBoost);
|
|
22902
22871
|
|
|
22903
|
-
// Pixel coverage culling (
|
|
22904
|
-
let
|
|
22905
|
-
let
|
|
22872
|
+
// Pixel coverage culling (vectorized squared length calculation)
|
|
22873
|
+
let v1v2_sq = v1v2_scaled * v1v2_scaled;
|
|
22874
|
+
let v1_len_sq = v1v2_sq.x + v1v2_sq.y;
|
|
22875
|
+
let v2_len_sq = v1v2_sq.z + v1v2_sq.w;
|
|
22906
22876
|
|
|
22907
22877
|
let minPixels = materialUniform.pixelCull.x;
|
|
22908
22878
|
let maxPixels = materialUniform.pixelCull.y;
|
|
22909
|
-
let maxPixelCullDistance = materialUniform.pixelCull.z;
|
|
22910
22879
|
|
|
22911
|
-
// Early out tiny splats
|
|
22880
|
+
// Early out tiny splats
|
|
22912
22881
|
if (v1_len_sq < minPixels && v2_len_sq < minPixels) {
|
|
22913
|
-
|
|
22914
|
-
o.vColor = vec4f(0.0);
|
|
22915
|
-
o.vTexCoord = vec2f(0.0);
|
|
22916
|
-
return o;
|
|
22882
|
+
return discardSplat();
|
|
22917
22883
|
}
|
|
22918
22884
|
|
|
22919
|
-
// Cull oversized splats
|
|
22920
|
-
// Only apply to splats close to camera (distance-based condition)
|
|
22885
|
+
// Cull oversized splats
|
|
22921
22886
|
if (maxPixels > 0.0) {
|
|
22922
|
-
|
|
22887
|
+
let maxPixelCullDistance = materialUniform.pixelCull.z;
|
|
22923
22888
|
let splatDistance = length(splat_cam.xyz);
|
|
22924
|
-
|
|
22925
|
-
// Only cull oversized splats if they are close to camera
|
|
22926
22889
|
if (maxPixelCullDistance <= 0.0 || splatDistance < maxPixelCullDistance) {
|
|
22927
22890
|
let maxAxisSq = maxPixels * maxPixels;
|
|
22928
22891
|
if (v1_len_sq > maxAxisSq || v2_len_sq > maxAxisSq) {
|
|
22929
|
-
|
|
22930
|
-
o.vColor = vec4f(0.0);
|
|
22931
|
-
o.vTexCoord = vec2f(0.0);
|
|
22932
|
-
return o;
|
|
22892
|
+
return discardSplat();
|
|
22933
22893
|
}
|
|
22934
22894
|
}
|
|
22935
22895
|
}
|
|
22936
22896
|
|
|
22937
|
-
//
|
|
22938
|
-
|
|
22939
|
-
|
|
22940
|
-
|
|
22941
|
-
o.vTexCoord = vertex_pos * scale / 2.0;
|
|
22897
|
+
// Final position calculation (optimized)
|
|
22898
|
+
let vertex_pos = position.xy;
|
|
22899
|
+
let inv_viewport = 1.0 / viewport;
|
|
22900
|
+
let offset = (vertex_pos.x * v1v2_scaled.xy + vertex_pos.y * v1v2_scaled.zw) * inv_viewport * splat_proj.w;
|
|
22942
22901
|
|
|
22902
|
+
var o: VSOut;
|
|
22903
|
+
o.member = splat_proj + vec4f(offset, 0.0, 0.0);
|
|
22904
|
+
o.vTexCoord = vertex_pos * (scale * 0.5);
|
|
22943
22905
|
o.vColor = color;
|
|
22944
22906
|
|
|
22945
22907
|
return o;
|
|
@@ -22950,31 +22912,29 @@ struct InstanceData {
|
|
|
22950
22912
|
/* wgsl */
|
|
22951
22913
|
`
|
|
22952
22914
|
#include "FragmentOutput"
|
|
22915
|
+
|
|
22916
|
+
// Constants
|
|
22917
|
+
const ALPHA_THRESHOLD: f32 = 0.00392156863; // 1.0 / 255.0
|
|
22918
|
+
const GAUSSIAN_SCALE: f32 = 4.0;
|
|
22953
22919
|
|
|
22954
|
-
// === evalSplat() -
|
|
22920
|
+
// === evalSplat() - optimized gaussian evaluation ===
|
|
22955
22921
|
fn evalSplat(texCoord: vec2f, color: vec4f) -> vec4f {
|
|
22956
22922
|
let A = dot(texCoord, texCoord);
|
|
22957
|
-
if (A > 1.0) {
|
|
22958
|
-
discard;
|
|
22959
|
-
}
|
|
22960
22923
|
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
}
|
|
22924
|
+
// Branch-less optimization using select
|
|
22925
|
+
let gaussian = exp(-A * GAUSSIAN_SCALE) * color.a;
|
|
22926
|
+
let alpha = select(gaussian, 0.0, A > 1.0 || gaussian < ALPHA_THRESHOLD);
|
|
22965
22927
|
|
|
22966
|
-
|
|
22967
|
-
return vec4f(color.rgb, B);
|
|
22928
|
+
return vec4f(color.rgb, alpha);
|
|
22968
22929
|
}
|
|
22969
|
-
|
|
22970
|
-
// === main() - like PlayCanvas splatMainFS ===
|
|
22930
|
+
|
|
22971
22931
|
@fragment
|
|
22972
|
-
fn FragMain(
|
|
22973
|
-
|
|
22974
|
-
|
|
22932
|
+
fn FragMain(
|
|
22933
|
+
@location(0) vColor: vec4<f32>,
|
|
22934
|
+
@location(1) vTexCoord: vec2<f32>
|
|
22935
|
+
) -> FragmentOutput {
|
|
22975
22936
|
var o: FragmentOutput;
|
|
22976
|
-
o.color =
|
|
22977
|
-
o.gBuffer = vec4f(0.0);
|
|
22937
|
+
o.color = evalSplat(vTexCoord, vColor);
|
|
22978
22938
|
return o;
|
|
22979
22939
|
}
|
|
22980
22940
|
`
|
|
@@ -23199,12 +23159,13 @@ struct InstanceData {
|
|
|
23199
23159
|
const pass = new RenderShaderPass("gsplat_vs_dc", "gsplat_fs_dc");
|
|
23200
23160
|
pass.passType = PassType.COLOR;
|
|
23201
23161
|
pass.setShaderEntry("VertMain", "FragMain");
|
|
23202
|
-
pass.topology = GPUPrimitiveTopology.
|
|
23162
|
+
pass.topology = GPUPrimitiveTopology.triangle_list;
|
|
23203
23163
|
pass.depthWriteEnabled = false;
|
|
23204
|
-
pass.cullMode =
|
|
23164
|
+
pass.cullMode = GPUCullMode.none;
|
|
23205
23165
|
pass.shaderState.transparent = true;
|
|
23206
23166
|
pass.shaderState.blendMode = BlendMode.NORMAL;
|
|
23207
23167
|
pass.shaderState.writeMasks = [15, 15];
|
|
23168
|
+
pass.shaderState.castReflection = false;
|
|
23208
23169
|
this.addRenderPass(pass);
|
|
23209
23170
|
this.setDefault();
|
|
23210
23171
|
}
|
|
@@ -23223,6 +23184,7 @@ struct InstanceData {
|
|
|
23223
23184
|
], exports.GSplatShader);
|
|
23224
23185
|
|
|
23225
23186
|
class GSplatMaterial extends Material {
|
|
23187
|
+
_pixelCullArray = new Float32Array(4);
|
|
23226
23188
|
constructor() {
|
|
23227
23189
|
super();
|
|
23228
23190
|
ShaderLib.register("gsplat_vs_dc", GSplat_VS);
|
|
@@ -23238,6 +23200,7 @@ struct InstanceData {
|
|
|
23238
23200
|
if (splatOrder) {
|
|
23239
23201
|
pass.setTexture("splatOrder", splatOrder);
|
|
23240
23202
|
}
|
|
23203
|
+
pass.shaderState.depthCompare = GPUCompareFunction.less;
|
|
23241
23204
|
}
|
|
23242
23205
|
/**
|
|
23243
23206
|
* Set the model matrix for transforming splats to world space
|
|
@@ -23252,9 +23215,13 @@ struct InstanceData {
|
|
|
23252
23215
|
* @param maxPixels Maximum pixel coverage (cull oversized splats), default: 0 (disabled)
|
|
23253
23216
|
* @param maxPixelCullDistance Only cull oversized splats within this distance, 0 = always cull
|
|
23254
23217
|
*/
|
|
23255
|
-
setPixelCulling(minPixels, maxPixels, maxPixelCullDistance = 0) {
|
|
23218
|
+
setPixelCulling(minPixels, maxPixels, maxPixelCullDistance = 0, batchSize = 128) {
|
|
23219
|
+
this._pixelCullArray[0] = minPixels;
|
|
23220
|
+
this._pixelCullArray[1] = maxPixels;
|
|
23221
|
+
this._pixelCullArray[2] = maxPixelCullDistance;
|
|
23222
|
+
this._pixelCullArray[3] = batchSize;
|
|
23256
23223
|
const pass = this.shader.getDefaultColorShader();
|
|
23257
|
-
pass.setUniform("pixelCull",
|
|
23224
|
+
pass.setUniform("pixelCull", this._pixelCullArray);
|
|
23258
23225
|
}
|
|
23259
23226
|
}
|
|
23260
23227
|
|
|
@@ -23912,108 +23879,47 @@ struct InstanceData {
|
|
|
23912
23879
|
}
|
|
23913
23880
|
}
|
|
23914
23881
|
|
|
23915
|
-
class
|
|
23916
|
-
|
|
23917
|
-
|
|
23918
|
-
segmentW;
|
|
23919
|
-
segmentH;
|
|
23920
|
-
up;
|
|
23921
|
-
constructor(width, height, segmentW = 1, segmentH = 1, up = Vector3.Y_AXIS) {
|
|
23882
|
+
class GSplatGeometry extends GeometryBase {
|
|
23883
|
+
batchSize;
|
|
23884
|
+
constructor(batchSize = 128) {
|
|
23922
23885
|
super();
|
|
23923
|
-
this.
|
|
23924
|
-
|
|
23925
|
-
|
|
23926
|
-
|
|
23927
|
-
|
|
23928
|
-
|
|
23929
|
-
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
23934
|
-
|
|
23935
|
-
|
|
23936
|
-
|
|
23937
|
-
|
|
23938
|
-
|
|
23939
|
-
|
|
23940
|
-
|
|
23941
|
-
|
|
23942
|
-
let
|
|
23943
|
-
|
|
23944
|
-
|
|
23945
|
-
|
|
23946
|
-
|
|
23947
|
-
|
|
23948
|
-
|
|
23949
|
-
|
|
23950
|
-
|
|
23951
|
-
|
|
23952
|
-
|
|
23953
|
-
|
|
23954
|
-
|
|
23955
|
-
var indexU = 0;
|
|
23956
|
-
for (var yi = 0; yi <= this.segmentH; ++yi) {
|
|
23957
|
-
for (var xi = 0; xi <= this.segmentW; ++xi) {
|
|
23958
|
-
x = (xi / this.segmentW - 0.5) * this.width;
|
|
23959
|
-
y = (yi / this.segmentH - 0.5) * this.height;
|
|
23960
|
-
switch (axis) {
|
|
23961
|
-
case Vector3.Y_AXIS:
|
|
23962
|
-
position_arr[indexP++] = x;
|
|
23963
|
-
position_arr[indexP++] = 0;
|
|
23964
|
-
position_arr[indexP++] = y;
|
|
23965
|
-
normal_arr[indexN++] = 0;
|
|
23966
|
-
normal_arr[indexN++] = 1;
|
|
23967
|
-
normal_arr[indexN++] = 0;
|
|
23968
|
-
break;
|
|
23969
|
-
case Vector3.Z_AXIS:
|
|
23970
|
-
position_arr[indexP++] = x;
|
|
23971
|
-
position_arr[indexP++] = -y;
|
|
23972
|
-
position_arr[indexP++] = 0;
|
|
23973
|
-
normal_arr[indexN++] = 0;
|
|
23974
|
-
normal_arr[indexN++] = 0;
|
|
23975
|
-
normal_arr[indexN++] = 1;
|
|
23976
|
-
break;
|
|
23977
|
-
case Vector3.X_AXIS:
|
|
23978
|
-
position_arr[indexP++] = 0;
|
|
23979
|
-
position_arr[indexP++] = x;
|
|
23980
|
-
position_arr[indexP++] = y;
|
|
23981
|
-
normal_arr[indexN++] = 1;
|
|
23982
|
-
normal_arr[indexN++] = 0;
|
|
23983
|
-
normal_arr[indexN++] = 0;
|
|
23984
|
-
break;
|
|
23985
|
-
default:
|
|
23986
|
-
position_arr[indexP++] = x;
|
|
23987
|
-
position_arr[indexP++] = 0;
|
|
23988
|
-
position_arr[indexP++] = y;
|
|
23989
|
-
normal_arr[indexN++] = 0;
|
|
23990
|
-
normal_arr[indexN++] = 1;
|
|
23991
|
-
normal_arr[indexN++] = 0;
|
|
23992
|
-
break;
|
|
23993
|
-
}
|
|
23994
|
-
uv_arr[indexU++] = xi / this.segmentW;
|
|
23995
|
-
uv_arr[indexU++] = yi / this.segmentH;
|
|
23996
|
-
if (xi != this.segmentW && yi != this.segmentH) {
|
|
23997
|
-
base = xi + yi * tw;
|
|
23998
|
-
indices_arr[numIndices++] = base + 1;
|
|
23999
|
-
indices_arr[numIndices++] = base;
|
|
24000
|
-
indices_arr[numIndices++] = base + tw;
|
|
24001
|
-
indices_arr[numIndices++] = base + 1;
|
|
24002
|
-
indices_arr[numIndices++] = base + tw;
|
|
24003
|
-
indices_arr[numIndices++] = base + tw + 1;
|
|
24004
|
-
}
|
|
24005
|
-
}
|
|
24006
|
-
}
|
|
24007
|
-
this.setIndices(indices_arr);
|
|
24008
|
-
this.setAttribute(VertexAttributeName.position, position_arr);
|
|
24009
|
-
this.setAttribute(VertexAttributeName.normal, normal_arr);
|
|
24010
|
-
this.setAttribute(VertexAttributeName.uv, uv_arr);
|
|
24011
|
-
this.setAttribute(VertexAttributeName.TEXCOORD_1, uv_arr);
|
|
23886
|
+
this.batchSize = batchSize;
|
|
23887
|
+
const meshPositions = new Float32Array(12 * batchSize);
|
|
23888
|
+
for (let i = 0; i < batchSize; ++i) {
|
|
23889
|
+
meshPositions.set([
|
|
23890
|
+
-2,
|
|
23891
|
+
-2,
|
|
23892
|
+
i,
|
|
23893
|
+
2,
|
|
23894
|
+
-2,
|
|
23895
|
+
i,
|
|
23896
|
+
2,
|
|
23897
|
+
2,
|
|
23898
|
+
i,
|
|
23899
|
+
-2,
|
|
23900
|
+
2,
|
|
23901
|
+
i
|
|
23902
|
+
], i * 12);
|
|
23903
|
+
}
|
|
23904
|
+
const meshIndices = new Uint32Array(6 * batchSize);
|
|
23905
|
+
for (let i = 0; i < batchSize; ++i) {
|
|
23906
|
+
const b = i * 4;
|
|
23907
|
+
meshIndices.set([
|
|
23908
|
+
0 + b,
|
|
23909
|
+
1 + b,
|
|
23910
|
+
2 + b,
|
|
23911
|
+
0 + b,
|
|
23912
|
+
2 + b,
|
|
23913
|
+
3 + b
|
|
23914
|
+
], i * 6);
|
|
23915
|
+
}
|
|
23916
|
+
this.setAttribute(VertexAttributeName.position, meshPositions);
|
|
23917
|
+
this.setIndices(meshIndices);
|
|
24012
23918
|
this.addSubGeometry({
|
|
24013
23919
|
indexStart: 0,
|
|
24014
|
-
indexCount:
|
|
23920
|
+
indexCount: meshIndices.length,
|
|
24015
23921
|
vertexStart: 0,
|
|
24016
|
-
vertexCount:
|
|
23922
|
+
vertexCount: meshPositions.length / 3,
|
|
24017
23923
|
firstStart: 0,
|
|
24018
23924
|
index: 0,
|
|
24019
23925
|
topology: 0
|
|
@@ -24117,18 +24023,49 @@ struct InstanceData {
|
|
|
24117
24023
|
updateTexture(width, height, data) {
|
|
24118
24024
|
let device = webGPUContext.device;
|
|
24119
24025
|
const bytesPerRow = width * 4 * 4;
|
|
24120
|
-
|
|
24026
|
+
device.queue.writeTexture(
|
|
24027
|
+
{ texture: this.getGPUTexture() },
|
|
24028
|
+
data.buffer,
|
|
24029
|
+
{ bytesPerRow },
|
|
24030
|
+
{ width, height, depthOrArrayLayers: 1 }
|
|
24031
|
+
);
|
|
24032
|
+
}
|
|
24033
|
+
}
|
|
24034
|
+
|
|
24035
|
+
class R32UintTexture extends Texture {
|
|
24036
|
+
_dataBuffer;
|
|
24037
|
+
create(width, height, data) {
|
|
24038
|
+
let device = webGPUContext.device;
|
|
24039
|
+
const bytesPerRow = width * 4;
|
|
24040
|
+
this.format = GPUTextureFormat.r32uint;
|
|
24041
|
+
const mipmapCount = 1;
|
|
24042
|
+
this.createTextureDescriptor(width, height, mipmapCount, this.format);
|
|
24043
|
+
const textureDataBuffer = this._dataBuffer = device.createBuffer({
|
|
24121
24044
|
size: data.byteLength,
|
|
24122
24045
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
|
|
24123
24046
|
});
|
|
24124
|
-
device.queue.writeBuffer(
|
|
24047
|
+
device.queue.writeBuffer(textureDataBuffer, 0, data.buffer);
|
|
24125
24048
|
const encoder = device.createCommandEncoder();
|
|
24126
24049
|
encoder.copyBufferToTexture(
|
|
24127
|
-
{ buffer:
|
|
24050
|
+
{ buffer: textureDataBuffer, bytesPerRow },
|
|
24128
24051
|
{ texture: this.getGPUTexture() },
|
|
24129
24052
|
{ width, height, depthOrArrayLayers: 1 }
|
|
24130
24053
|
);
|
|
24131
24054
|
device.queue.submit([encoder.finish()]);
|
|
24055
|
+
this.samplerBindingLayout.type = `non-filtering`;
|
|
24056
|
+
this.textureBindingLayout.sampleType = `uint`;
|
|
24057
|
+
this.gpuSampler = device.createSampler({});
|
|
24058
|
+
return this;
|
|
24059
|
+
}
|
|
24060
|
+
updateTexture(width, height, data) {
|
|
24061
|
+
let device = webGPUContext.device;
|
|
24062
|
+
const bytesPerRow = width * 4;
|
|
24063
|
+
device.queue.writeTexture(
|
|
24064
|
+
{ texture: this.getGPUTexture() },
|
|
24065
|
+
data.buffer,
|
|
24066
|
+
{ bytesPerRow },
|
|
24067
|
+
{ width, height, depthOrArrayLayers: 1 }
|
|
24068
|
+
);
|
|
24132
24069
|
}
|
|
24133
24070
|
}
|
|
24134
24071
|
|
|
@@ -24270,14 +24207,15 @@ struct InstanceData {
|
|
|
24270
24207
|
// Web Worker for sorting
|
|
24271
24208
|
_sortWorker;
|
|
24272
24209
|
_lastSentTime = 0;
|
|
24273
|
-
_minIntervalMs =
|
|
24274
|
-
// No throttle for immediate sorting
|
|
24210
|
+
_minIntervalMs = 16;
|
|
24275
24211
|
_centersSent = false;
|
|
24276
24212
|
_lastViewMatrixHash = 0;
|
|
24277
24213
|
// Adaptive sorting optimization
|
|
24278
24214
|
_lastCameraSpeed = 0;
|
|
24279
24215
|
_adaptiveSorting = true;
|
|
24280
24216
|
// Enable adaptive sorting by default
|
|
24217
|
+
_lastPixelCullParams = "";
|
|
24218
|
+
_texturesInitialized = false;
|
|
24281
24219
|
// LOD (Level of Detail) system
|
|
24282
24220
|
_lodEnabled = false;
|
|
24283
24221
|
_lodDistances = [5, 10, 20, 40];
|
|
@@ -24299,6 +24237,11 @@ struct InstanceData {
|
|
|
24299
24237
|
get fullCount() {
|
|
24300
24238
|
return this._fullCount;
|
|
24301
24239
|
}
|
|
24240
|
+
// Batched rendering
|
|
24241
|
+
_batchSize = 128;
|
|
24242
|
+
// Splats per draw call
|
|
24243
|
+
instanceCount = 0;
|
|
24244
|
+
// For InstanceDrawComponent compatibility
|
|
24302
24245
|
constructor() {
|
|
24303
24246
|
super();
|
|
24304
24247
|
}
|
|
@@ -24314,24 +24257,20 @@ struct InstanceData {
|
|
|
24314
24257
|
this.texParams = new Float32Array([this.count, this.size.x, this.count, 1]);
|
|
24315
24258
|
this._positions = asset.position;
|
|
24316
24259
|
const total = this.size.x * this.size.y;
|
|
24317
|
-
this._orderData = new Uint32Array(total
|
|
24260
|
+
this._orderData = new Uint32Array(total);
|
|
24318
24261
|
for (let i = 0; i < total; i++) {
|
|
24319
|
-
|
|
24320
|
-
|
|
24321
|
-
|
|
24322
|
-
this._orderData[base + 1] = 0;
|
|
24323
|
-
this._orderData[base + 2] = 0;
|
|
24324
|
-
this._orderData[base + 3] = 0;
|
|
24325
|
-
}
|
|
24326
|
-
this.splatOrder = new Uint32ArrayTexture().create(this.size.x, this.size.y, this._orderData);
|
|
24262
|
+
this._orderData[i] = i < this.count ? i : this.count > 0 ? this.count - 1 : 0;
|
|
24263
|
+
}
|
|
24264
|
+
this.splatOrder = new R32UintTexture().create(this.size.x, this.size.y, this._orderData);
|
|
24327
24265
|
this.splatOrder.name = "splatOrder";
|
|
24328
24266
|
this.splatOrder.minFilter = "nearest";
|
|
24329
24267
|
this.splatOrder.magFilter = "nearest";
|
|
24330
24268
|
this.splatOrder.addressModeU = "clamp-to-edge";
|
|
24331
24269
|
this.splatOrder.addressModeV = "clamp-to-edge";
|
|
24332
24270
|
this.gsplatMaterial = new GSplatMaterial();
|
|
24333
|
-
this.geometry = new
|
|
24271
|
+
this.geometry = new GSplatGeometry(this._batchSize);
|
|
24334
24272
|
this.materials = [this.gsplatMaterial];
|
|
24273
|
+
this.instanceCount = 0;
|
|
24335
24274
|
}
|
|
24336
24275
|
/**
|
|
24337
24276
|
* Update splat sorting before rendering
|
|
@@ -24408,12 +24347,7 @@ struct InstanceData {
|
|
|
24408
24347
|
this.texParams[2] = Math.min(this.texParams[0], this.count);
|
|
24409
24348
|
const total = this.size.x * this.size.y;
|
|
24410
24349
|
for (let i = 0; i < total; i++) {
|
|
24411
|
-
|
|
24412
|
-
const base = i * 4;
|
|
24413
|
-
this._orderData[base + 0] = src;
|
|
24414
|
-
this._orderData[base + 1] = 0;
|
|
24415
|
-
this._orderData[base + 2] = 0;
|
|
24416
|
-
this._orderData[base + 3] = 0;
|
|
24350
|
+
this._orderData[i] = i < this.count ? i : this.count > 0 ? this.count - 1 : 0;
|
|
24417
24351
|
}
|
|
24418
24352
|
this.splatOrder.updateTexture(this.size.x, this.size.y, this._orderData);
|
|
24419
24353
|
if (this._sortWorker) {
|
|
@@ -24440,6 +24374,7 @@ struct InstanceData {
|
|
|
24440
24374
|
} else {
|
|
24441
24375
|
this._centersSent = false;
|
|
24442
24376
|
}
|
|
24377
|
+
this.instanceCount = 0;
|
|
24443
24378
|
}
|
|
24444
24379
|
/**
|
|
24445
24380
|
* Set visibility boost factor (material uniform tex_params.w)
|
|
@@ -24503,6 +24438,18 @@ struct InstanceData {
|
|
|
24503
24438
|
distanceEnabled: this._maxPixelCullDistance > 0
|
|
24504
24439
|
};
|
|
24505
24440
|
}
|
|
24441
|
+
/**
|
|
24442
|
+
* Get batching statistics
|
|
24443
|
+
*/
|
|
24444
|
+
getBatchingStats() {
|
|
24445
|
+
return {
|
|
24446
|
+
enabled: true,
|
|
24447
|
+
batchSize: this._batchSize,
|
|
24448
|
+
instanceCount: this.instanceCount,
|
|
24449
|
+
splatCount: this.count,
|
|
24450
|
+
reduction: this.count > 0 ? (1 - this.instanceCount / this.count) * 100 : 0
|
|
24451
|
+
};
|
|
24452
|
+
}
|
|
24506
24453
|
/**
|
|
24507
24454
|
* Calculate texture size for given splat count
|
|
24508
24455
|
*/
|
|
@@ -24725,18 +24672,20 @@ struct InstanceData {
|
|
|
24725
24672
|
const indices = new Uint32Array(newOrder);
|
|
24726
24673
|
const total = this.size.x * this.size.y;
|
|
24727
24674
|
const count = this.count;
|
|
24728
|
-
this._orderData
|
|
24729
|
-
|
|
24730
|
-
|
|
24731
|
-
|
|
24732
|
-
|
|
24733
|
-
|
|
24734
|
-
|
|
24735
|
-
this._orderData
|
|
24675
|
+
if (!this._orderData || this._orderData.length !== total) {
|
|
24676
|
+
this._orderData = new Uint32Array(total);
|
|
24677
|
+
}
|
|
24678
|
+
const validCount = Math.min(count, indices.length);
|
|
24679
|
+
this._orderData.set(indices.subarray(0, validCount), 0);
|
|
24680
|
+
if (validCount < total) {
|
|
24681
|
+
const lastIndex = count > 0 ? count - 1 : 0;
|
|
24682
|
+
this._orderData.fill(lastIndex, validCount, total);
|
|
24736
24683
|
}
|
|
24737
24684
|
this.splatOrder.updateTexture(this.size.x, this.size.y, this._orderData);
|
|
24738
24685
|
const valid = Math.max(0, Math.min(this.count, ev.data.count | 0));
|
|
24739
24686
|
this.texParams[2] = valid;
|
|
24687
|
+
const newInstanceCount = Math.ceil(valid / this._batchSize);
|
|
24688
|
+
this.instanceCount = newInstanceCount;
|
|
24740
24689
|
};
|
|
24741
24690
|
const worldPos = this._worldPositions || this._positions;
|
|
24742
24691
|
const centers = this._mapping ? new Float32Array(this._mapping.length * 3) : new Float32Array(worldPos);
|
|
@@ -24939,30 +24888,22 @@ struct InstanceData {
|
|
|
24939
24888
|
nodeUpdate(view, passType, renderPassState, clusterLightingBuffer) {
|
|
24940
24889
|
const worldMatrix = this.object3D.transform.worldMatrix;
|
|
24941
24890
|
this.gsplatMaterial.setTransformMatrix(worldMatrix);
|
|
24942
|
-
this.
|
|
24943
|
-
this.
|
|
24944
|
-
this.
|
|
24945
|
-
this.
|
|
24946
|
-
|
|
24947
|
-
|
|
24948
|
-
this.
|
|
24949
|
-
|
|
24950
|
-
|
|
24951
|
-
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
24956
|
-
for (let mat of this.materials) {
|
|
24957
|
-
const passes = mat.getPass(passType);
|
|
24958
|
-
if (!passes || passes.length === 0) continue;
|
|
24959
|
-
for (const pass of passes) {
|
|
24960
|
-
if (!pass.pipeline) continue;
|
|
24961
|
-
pass.apply(this.geometry, rendererPassState);
|
|
24962
|
-
GPUContext.bindPipeline(encoder, pass);
|
|
24963
|
-
GPUContext.draw(encoder, 4, this.count, 0, 0);
|
|
24964
|
-
}
|
|
24891
|
+
const currentParams = `${this._minPixelCoverage},${this._maxPixelCoverage},${this._maxPixelCullDistance},${this._batchSize}`;
|
|
24892
|
+
if (currentParams !== this._lastPixelCullParams) {
|
|
24893
|
+
this.gsplatMaterial.setPixelCulling(this._minPixelCoverage, this._maxPixelCoverage, this._maxPixelCullDistance, this._batchSize);
|
|
24894
|
+
this._lastPixelCullParams = currentParams;
|
|
24895
|
+
}
|
|
24896
|
+
if (!this._texturesInitialized) {
|
|
24897
|
+
this.gsplatMaterial.setSplatTextures(
|
|
24898
|
+
this.splatColor,
|
|
24899
|
+
this.transformA,
|
|
24900
|
+
this.transformB,
|
|
24901
|
+
this.texParams,
|
|
24902
|
+
this.splatOrder
|
|
24903
|
+
);
|
|
24904
|
+
this._texturesInitialized = true;
|
|
24965
24905
|
}
|
|
24906
|
+
super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
|
|
24966
24907
|
}
|
|
24967
24908
|
/**
|
|
24968
24909
|
* Render pass (fallback)
|
|
@@ -24976,7 +24917,28 @@ struct InstanceData {
|
|
|
24976
24917
|
if (!pass.pipeline) continue;
|
|
24977
24918
|
pass.apply(this.geometry, renderContext.rendererPassState || renderContext);
|
|
24978
24919
|
GPUContext.bindPipeline(encoder, pass);
|
|
24979
|
-
GPUContext.
|
|
24920
|
+
GPUContext.bindGeometryBuffer(encoder, this.geometry);
|
|
24921
|
+
const subGeometry = this.geometry.subGeometries[0];
|
|
24922
|
+
const lodInfo = subGeometry.lodLevels[0];
|
|
24923
|
+
if (this.instanceCount > 0) {
|
|
24924
|
+
GPUContext.drawIndexed(
|
|
24925
|
+
encoder,
|
|
24926
|
+
lodInfo.indexCount,
|
|
24927
|
+
this.instanceCount,
|
|
24928
|
+
lodInfo.indexStart,
|
|
24929
|
+
0,
|
|
24930
|
+
0
|
|
24931
|
+
);
|
|
24932
|
+
} else {
|
|
24933
|
+
GPUContext.drawIndexed(
|
|
24934
|
+
encoder,
|
|
24935
|
+
lodInfo.indexCount,
|
|
24936
|
+
1,
|
|
24937
|
+
lodInfo.indexStart,
|
|
24938
|
+
0,
|
|
24939
|
+
0
|
|
24940
|
+
);
|
|
24941
|
+
}
|
|
24980
24942
|
}
|
|
24981
24943
|
}
|
|
24982
24944
|
}
|
|
@@ -24988,6 +24950,31 @@ struct InstanceData {
|
|
|
24988
24950
|
this._sortWorker.terminate();
|
|
24989
24951
|
this._sortWorker = null;
|
|
24990
24952
|
}
|
|
24953
|
+
if (this.splatColor) {
|
|
24954
|
+
this.splatColor.destroy(force);
|
|
24955
|
+
this.splatColor = null;
|
|
24956
|
+
}
|
|
24957
|
+
if (this.transformA) {
|
|
24958
|
+
this.transformA.destroy(force);
|
|
24959
|
+
this.transformA = null;
|
|
24960
|
+
}
|
|
24961
|
+
if (this.transformB) {
|
|
24962
|
+
this.transformB.destroy(force);
|
|
24963
|
+
this.transformB = null;
|
|
24964
|
+
}
|
|
24965
|
+
if (this.splatOrder) {
|
|
24966
|
+
this.splatOrder.destroy(force);
|
|
24967
|
+
this.splatOrder = null;
|
|
24968
|
+
}
|
|
24969
|
+
if (this.gsplatMaterial) {
|
|
24970
|
+
this.gsplatMaterial.destroy(force);
|
|
24971
|
+
this.gsplatMaterial = null;
|
|
24972
|
+
}
|
|
24973
|
+
this._positions = null;
|
|
24974
|
+
this._worldPositions = null;
|
|
24975
|
+
this._orderData = null;
|
|
24976
|
+
this.texParams = null;
|
|
24977
|
+
this._mapping = null;
|
|
24991
24978
|
super.destroy(force);
|
|
24992
24979
|
}
|
|
24993
24980
|
};
|
|
@@ -26895,6 +26882,43 @@ struct InstanceData {
|
|
|
26895
26882
|
usage
|
|
26896
26883
|
);
|
|
26897
26884
|
}
|
|
26885
|
+
destroy(force) {
|
|
26886
|
+
if (this._computeConfigBuffer) {
|
|
26887
|
+
this._computeConfigBuffer.destroy(force);
|
|
26888
|
+
this._computeConfigBuffer = null;
|
|
26889
|
+
}
|
|
26890
|
+
if (this._morphInfluenceBuffer) {
|
|
26891
|
+
this._morphInfluenceBuffer.destroy(force);
|
|
26892
|
+
this._morphInfluenceBuffer = null;
|
|
26893
|
+
}
|
|
26894
|
+
if (this._computeShader) {
|
|
26895
|
+
this._computeShader.destroy(force);
|
|
26896
|
+
this._computeShader = null;
|
|
26897
|
+
}
|
|
26898
|
+
if (this._positionAttrDataGroup) {
|
|
26899
|
+
if (this._positionAttrDataGroup.input) {
|
|
26900
|
+
this._positionAttrDataGroup.input.destroy(force);
|
|
26901
|
+
}
|
|
26902
|
+
if (this._positionAttrDataGroup.output) {
|
|
26903
|
+
this._positionAttrDataGroup.output.destroy(force);
|
|
26904
|
+
}
|
|
26905
|
+
this._positionAttrDataGroup = null;
|
|
26906
|
+
}
|
|
26907
|
+
if (this._normalAttrDataGroup) {
|
|
26908
|
+
if (this._normalAttrDataGroup.input) {
|
|
26909
|
+
this._normalAttrDataGroup.input.destroy(force);
|
|
26910
|
+
}
|
|
26911
|
+
if (this._normalAttrDataGroup.output) {
|
|
26912
|
+
this._normalAttrDataGroup.output.destroy(force);
|
|
26913
|
+
}
|
|
26914
|
+
this._normalAttrDataGroup = null;
|
|
26915
|
+
}
|
|
26916
|
+
this._computeConfigArray = null;
|
|
26917
|
+
this._morphInfluenceArray = null;
|
|
26918
|
+
this._collectMorphTargetData = null;
|
|
26919
|
+
this._blendTarget = null;
|
|
26920
|
+
this._computeShaders = null;
|
|
26921
|
+
}
|
|
26898
26922
|
}
|
|
26899
26923
|
|
|
26900
26924
|
var __defProp = Object.defineProperty;
|
|
@@ -27006,6 +27030,10 @@ struct InstanceData {
|
|
|
27006
27030
|
super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
|
|
27007
27031
|
}
|
|
27008
27032
|
destroy(force) {
|
|
27033
|
+
if (this.morphData) {
|
|
27034
|
+
this.morphData.destroy(force);
|
|
27035
|
+
this.morphData = null;
|
|
27036
|
+
}
|
|
27009
27037
|
super.destroy(force);
|
|
27010
27038
|
}
|
|
27011
27039
|
};
|
|
@@ -27512,6 +27540,115 @@ struct InstanceData {
|
|
|
27512
27540
|
}
|
|
27513
27541
|
}
|
|
27514
27542
|
|
|
27543
|
+
class PlaneGeometry extends GeometryBase {
|
|
27544
|
+
width;
|
|
27545
|
+
height;
|
|
27546
|
+
segmentW;
|
|
27547
|
+
segmentH;
|
|
27548
|
+
up;
|
|
27549
|
+
constructor(width, height, segmentW = 1, segmentH = 1, up = Vector3.Y_AXIS) {
|
|
27550
|
+
super();
|
|
27551
|
+
this.width = width;
|
|
27552
|
+
this.height = height;
|
|
27553
|
+
this.segmentW = segmentW;
|
|
27554
|
+
this.segmentH = segmentH;
|
|
27555
|
+
this.up = up;
|
|
27556
|
+
this.buildGeometry(this.up);
|
|
27557
|
+
}
|
|
27558
|
+
buildGeometry(axis) {
|
|
27559
|
+
var x, y;
|
|
27560
|
+
var numIndices;
|
|
27561
|
+
var base;
|
|
27562
|
+
var tw = this.segmentW + 1;
|
|
27563
|
+
(this.segmentH + 1) * tw;
|
|
27564
|
+
this.bounds = new BoundingBox(
|
|
27565
|
+
Vector3.ZERO.clone(),
|
|
27566
|
+
new Vector3(this.width, 1, this.height)
|
|
27567
|
+
);
|
|
27568
|
+
numIndices = this.segmentH * this.segmentW * 6;
|
|
27569
|
+
let vertexCount = (this.segmentW + 1) * (this.segmentH + 1);
|
|
27570
|
+
let position_arr = new Float32Array(vertexCount * 3);
|
|
27571
|
+
let normal_arr = new Float32Array(vertexCount * 3);
|
|
27572
|
+
let uv_arr = new Float32Array(vertexCount * 2);
|
|
27573
|
+
let indices_arr;
|
|
27574
|
+
let totalIndexCount = this.segmentW * this.segmentH * 2 * 3;
|
|
27575
|
+
if (totalIndexCount >= Uint16Array.length) {
|
|
27576
|
+
indices_arr = new Uint32Array(this.segmentW * this.segmentH * 2 * 3);
|
|
27577
|
+
} else {
|
|
27578
|
+
indices_arr = new Uint16Array(this.segmentW * this.segmentH * 2 * 3);
|
|
27579
|
+
}
|
|
27580
|
+
numIndices = 0;
|
|
27581
|
+
var indexP = 0;
|
|
27582
|
+
var indexN = 0;
|
|
27583
|
+
var indexU = 0;
|
|
27584
|
+
for (var yi = 0; yi <= this.segmentH; ++yi) {
|
|
27585
|
+
for (var xi = 0; xi <= this.segmentW; ++xi) {
|
|
27586
|
+
x = (xi / this.segmentW - 0.5) * this.width;
|
|
27587
|
+
y = (yi / this.segmentH - 0.5) * this.height;
|
|
27588
|
+
switch (axis) {
|
|
27589
|
+
case Vector3.Y_AXIS:
|
|
27590
|
+
position_arr[indexP++] = x;
|
|
27591
|
+
position_arr[indexP++] = 0;
|
|
27592
|
+
position_arr[indexP++] = y;
|
|
27593
|
+
normal_arr[indexN++] = 0;
|
|
27594
|
+
normal_arr[indexN++] = 1;
|
|
27595
|
+
normal_arr[indexN++] = 0;
|
|
27596
|
+
break;
|
|
27597
|
+
case Vector3.Z_AXIS:
|
|
27598
|
+
position_arr[indexP++] = x;
|
|
27599
|
+
position_arr[indexP++] = -y;
|
|
27600
|
+
position_arr[indexP++] = 0;
|
|
27601
|
+
normal_arr[indexN++] = 0;
|
|
27602
|
+
normal_arr[indexN++] = 0;
|
|
27603
|
+
normal_arr[indexN++] = 1;
|
|
27604
|
+
break;
|
|
27605
|
+
case Vector3.X_AXIS:
|
|
27606
|
+
position_arr[indexP++] = 0;
|
|
27607
|
+
position_arr[indexP++] = x;
|
|
27608
|
+
position_arr[indexP++] = y;
|
|
27609
|
+
normal_arr[indexN++] = 1;
|
|
27610
|
+
normal_arr[indexN++] = 0;
|
|
27611
|
+
normal_arr[indexN++] = 0;
|
|
27612
|
+
break;
|
|
27613
|
+
default:
|
|
27614
|
+
position_arr[indexP++] = x;
|
|
27615
|
+
position_arr[indexP++] = 0;
|
|
27616
|
+
position_arr[indexP++] = y;
|
|
27617
|
+
normal_arr[indexN++] = 0;
|
|
27618
|
+
normal_arr[indexN++] = 1;
|
|
27619
|
+
normal_arr[indexN++] = 0;
|
|
27620
|
+
break;
|
|
27621
|
+
}
|
|
27622
|
+
uv_arr[indexU++] = xi / this.segmentW;
|
|
27623
|
+
uv_arr[indexU++] = yi / this.segmentH;
|
|
27624
|
+
if (xi != this.segmentW && yi != this.segmentH) {
|
|
27625
|
+
base = xi + yi * tw;
|
|
27626
|
+
indices_arr[numIndices++] = base + 1;
|
|
27627
|
+
indices_arr[numIndices++] = base;
|
|
27628
|
+
indices_arr[numIndices++] = base + tw;
|
|
27629
|
+
indices_arr[numIndices++] = base + 1;
|
|
27630
|
+
indices_arr[numIndices++] = base + tw;
|
|
27631
|
+
indices_arr[numIndices++] = base + tw + 1;
|
|
27632
|
+
}
|
|
27633
|
+
}
|
|
27634
|
+
}
|
|
27635
|
+
this.setIndices(indices_arr);
|
|
27636
|
+
this.setAttribute(VertexAttributeName.position, position_arr);
|
|
27637
|
+
this.setAttribute(VertexAttributeName.normal, normal_arr);
|
|
27638
|
+
this.setAttribute(VertexAttributeName.uv, uv_arr);
|
|
27639
|
+
this.setAttribute(VertexAttributeName.TEXCOORD_1, uv_arr);
|
|
27640
|
+
this.addSubGeometry({
|
|
27641
|
+
indexStart: 0,
|
|
27642
|
+
indexCount: indices_arr.length,
|
|
27643
|
+
vertexStart: 0,
|
|
27644
|
+
vertexCount: 0,
|
|
27645
|
+
firstStart: 0,
|
|
27646
|
+
index: 0,
|
|
27647
|
+
topology: 0
|
|
27648
|
+
});
|
|
27649
|
+
}
|
|
27650
|
+
}
|
|
27651
|
+
|
|
27515
27652
|
var __getOwnPropDesc$g = Object.getOwnPropertyDescriptor;
|
|
27516
27653
|
var __decorateClass$g = (decorators, target, key, kind) => {
|
|
27517
27654
|
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$g(target, key) : target;
|
|
@@ -30486,7 +30623,15 @@ struct InstanceData {
|
|
|
30486
30623
|
shadowMapPassRenderer;
|
|
30487
30624
|
pointLightShadowRenderer;
|
|
30488
30625
|
ddgiProbeRenderer;
|
|
30489
|
-
|
|
30626
|
+
_postRenderer;
|
|
30627
|
+
get postRenderer() {
|
|
30628
|
+
if (!this._postRenderer) {
|
|
30629
|
+
let gbufferFrame = GBufferFrame.getGBufferFrame("ColorPassGBuffer");
|
|
30630
|
+
this._postRenderer = this.addRenderer(PostRenderer);
|
|
30631
|
+
this._postRenderer.setRenderStates(gbufferFrame);
|
|
30632
|
+
}
|
|
30633
|
+
return this._postRenderer;
|
|
30634
|
+
}
|
|
30490
30635
|
clusterLightingRender;
|
|
30491
30636
|
reflectionRenderer;
|
|
30492
30637
|
occlusionSystem;
|
|
@@ -30510,7 +30655,9 @@ struct InstanceData {
|
|
|
30510
30655
|
}
|
|
30511
30656
|
this.shadowMapPassRenderer = new ShadowMapPassRenderer();
|
|
30512
30657
|
this.pointLightShadowRenderer = new PointLightShadowRenderer();
|
|
30513
|
-
|
|
30658
|
+
if (Engine3D.setting.render.postProcessing.fxaa.enable) {
|
|
30659
|
+
this.addPost(new FXAAPost());
|
|
30660
|
+
}
|
|
30514
30661
|
}
|
|
30515
30662
|
addRenderer(c, param) {
|
|
30516
30663
|
let renderer;
|
|
@@ -30540,11 +30687,6 @@ struct InstanceData {
|
|
|
30540
30687
|
this.pauseRender = false;
|
|
30541
30688
|
}
|
|
30542
30689
|
addPost(post) {
|
|
30543
|
-
if (!this.postRenderer) {
|
|
30544
|
-
let gbufferFrame = GBufferFrame.getGBufferFrame("ColorPassGBuffer");
|
|
30545
|
-
this.postRenderer = this.addRenderer(PostRenderer);
|
|
30546
|
-
this.postRenderer.setRenderStates(gbufferFrame);
|
|
30547
|
-
}
|
|
30548
30690
|
if (post instanceof PostBase) {
|
|
30549
30691
|
this.postRenderer.attachPost(this.view, post);
|
|
30550
30692
|
}
|
|
@@ -30562,15 +30704,21 @@ struct InstanceData {
|
|
|
30562
30704
|
renderFrame() {
|
|
30563
30705
|
let view = this._view;
|
|
30564
30706
|
ProfilerUtil.startView(view);
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
|
|
30568
|
-
|
|
30569
|
-
if (this.
|
|
30707
|
+
if (this.clusterLightingRender) {
|
|
30708
|
+
GlobalBindGroup.getLightEntries(view.scene).update(view);
|
|
30709
|
+
GlobalBindGroup.getReflectionEntries(view.scene).update(view);
|
|
30710
|
+
}
|
|
30711
|
+
if (Engine3D.setting.occlusionQuery.enable && this.occlusionSystem) {
|
|
30712
|
+
this.occlusionSystem.update(view.camera, view.scene);
|
|
30713
|
+
}
|
|
30714
|
+
if (this.clusterLightingRender) {
|
|
30715
|
+
this.clusterLightingRender.render(view, this.occlusionSystem);
|
|
30716
|
+
}
|
|
30717
|
+
if (Engine3D.setting.shadow.enable && this.shadowMapPassRenderer) {
|
|
30570
30718
|
ShadowLightsCollect.update(view);
|
|
30571
30719
|
this.shadowMapPassRenderer.render(view, this.occlusionSystem);
|
|
30572
30720
|
}
|
|
30573
|
-
if (this.pointLightShadowRenderer) {
|
|
30721
|
+
if (Engine3D.setting.shadow.enable && this.pointLightShadowRenderer) {
|
|
30574
30722
|
this.pointLightShadowRenderer.render(view, this.occlusionSystem);
|
|
30575
30723
|
}
|
|
30576
30724
|
if (this.depthPassRenderer) {
|
|
@@ -40791,7 +40939,7 @@ fn CsMain( @builtin(workgroup_id) workgroup_id : vec3<u32> , @builtin(global_inv
|
|
|
40791
40939
|
}
|
|
40792
40940
|
}
|
|
40793
40941
|
|
|
40794
|
-
const version = "1.0.
|
|
40942
|
+
const version = "1.0.14";
|
|
40795
40943
|
|
|
40796
40944
|
class Engine3D {
|
|
40797
40945
|
/**
|
|
@@ -66579,6 +66727,7 @@ fn frag(){
|
|
|
66579
66727
|
exports.GPUVertexFormat = GPUVertexFormat;
|
|
66580
66728
|
exports.GPUVertexStepMode = GPUVertexStepMode;
|
|
66581
66729
|
exports.GSplatFormat = GSplatFormat;
|
|
66730
|
+
exports.GSplatGeometry = GSplatGeometry;
|
|
66582
66731
|
exports.GSplatMaterial = GSplatMaterial;
|
|
66583
66732
|
exports.GSplat_FS = GSplat_FS;
|
|
66584
66733
|
exports.GSplat_VS = GSplat_VS;
|
|
@@ -66827,6 +66976,7 @@ fn frag(){
|
|
|
66827
66976
|
exports.Quad_frag_wgsl = Quad_frag_wgsl;
|
|
66828
66977
|
exports.Quad_vert_wgsl = Quad_vert_wgsl;
|
|
66829
66978
|
exports.Quaternion = Quaternion;
|
|
66979
|
+
exports.R32UintTexture = R32UintTexture;
|
|
66830
66980
|
exports.RADIANS_TO_DEGREES = RADIANS_TO_DEGREES;
|
|
66831
66981
|
exports.RGBEErrorCode = RGBEErrorCode;
|
|
66832
66982
|
exports.RGBEHeader = RGBEHeader;
|