@rings-webgpu/core 1.0.42 → 1.0.44
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 +51 -24
- package/dist/rings.es.js.map +3 -3
- package/dist/rings.es.max.js +117 -39
- package/dist/rings.umd.js +50 -23
- package/dist/rings.umd.js.map +3 -3
- package/dist/rings.umd.max.js +117 -39
- package/dist/types/gfx/renderJob/GPUContext.d.ts +2 -0
- package/package.json +1 -1
package/dist/rings.es.max.js
CHANGED
|
@@ -1679,21 +1679,47 @@ class Context3D extends CEventDispatcher {
|
|
|
1679
1679
|
this.adapter = await navigator.gpu.requestAdapter({
|
|
1680
1680
|
powerPreference: "high-performance"
|
|
1681
1681
|
// 或 low-power
|
|
1682
|
+
// xrCompatible: canvasConfig?.xrCompatible, // 可选:如果需要 XR 支持
|
|
1682
1683
|
});
|
|
1683
1684
|
if (this.adapter == null) {
|
|
1684
1685
|
throw new Error("Your browser does not support WebGPU!");
|
|
1685
1686
|
}
|
|
1687
|
+
const requiredFeatures = [];
|
|
1688
|
+
const requireFeature = (feature) => {
|
|
1689
|
+
const supported = this.adapter.features.has(feature);
|
|
1690
|
+
if (supported) {
|
|
1691
|
+
requiredFeatures.push(feature);
|
|
1692
|
+
}
|
|
1693
|
+
return supported;
|
|
1694
|
+
};
|
|
1695
|
+
requireFeature("bgra8unorm-storage");
|
|
1696
|
+
requireFeature("depth-clip-control");
|
|
1697
|
+
requireFeature("depth32float-stencil8");
|
|
1698
|
+
requireFeature("indirect-first-instance");
|
|
1699
|
+
requireFeature("rg11b10ufloat-renderable");
|
|
1700
|
+
requireFeature("float32-filterable");
|
|
1701
|
+
requireFeature("float32-blendable");
|
|
1702
|
+
requireFeature("timestamp-query");
|
|
1703
|
+
requireFeature("shader-f16");
|
|
1704
|
+
requireFeature("clip-distances");
|
|
1705
|
+
requireFeature("texture-compression-bc");
|
|
1706
|
+
requireFeature("texture-compression-etc2");
|
|
1707
|
+
requireFeature("texture-compression-astc");
|
|
1708
|
+
const adapterLimits = this.adapter?.limits;
|
|
1709
|
+
const requiredLimits = {};
|
|
1710
|
+
if (adapterLimits) {
|
|
1711
|
+
for (const limitName in adapterLimits) {
|
|
1712
|
+
if (limitName === "minSubgroupSize" || limitName === "maxSubgroupSize") {
|
|
1713
|
+
continue;
|
|
1714
|
+
}
|
|
1715
|
+
requiredLimits[limitName] = adapterLimits[limitName];
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1686
1718
|
this.device = await this.adapter.requestDevice({
|
|
1687
|
-
requiredFeatures
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
"
|
|
1691
|
-
"indirect-first-instance",
|
|
1692
|
-
"rg11b10ufloat-renderable"
|
|
1693
|
-
],
|
|
1694
|
-
requiredLimits: {
|
|
1695
|
-
minUniformBufferOffsetAlignment: 256,
|
|
1696
|
-
maxStorageBufferBindingSize: this.adapter.limits.maxStorageBufferBindingSize
|
|
1719
|
+
requiredFeatures,
|
|
1720
|
+
requiredLimits,
|
|
1721
|
+
defaultQueue: {
|
|
1722
|
+
label: "RingsDefaultQueue"
|
|
1697
1723
|
}
|
|
1698
1724
|
});
|
|
1699
1725
|
if (this.device == null) {
|
|
@@ -1701,15 +1727,18 @@ class Context3D extends CEventDispatcher {
|
|
|
1701
1727
|
}
|
|
1702
1728
|
this._pixelRatio = this.canvasConfig?.devicePixelRatio || window.devicePixelRatio || 1;
|
|
1703
1729
|
this._pixelRatio = Math.min(this._pixelRatio, 2);
|
|
1704
|
-
this.device.label = "
|
|
1730
|
+
this.device.label = "RingsWebGPUDevice";
|
|
1705
1731
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
1706
1732
|
this.context = this.canvas.getContext("webgpu");
|
|
1707
1733
|
this.context.configure({
|
|
1708
1734
|
device: this.device,
|
|
1709
1735
|
format: this.presentationFormat,
|
|
1710
|
-
|
|
1736
|
+
// RENDER_ATTACHMENT is required, COPY_SRC allows scene grab/copy operations
|
|
1737
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST,
|
|
1711
1738
|
alphaMode: "premultiplied",
|
|
1712
|
-
colorSpace:
|
|
1739
|
+
colorSpace: "srgb"
|
|
1740
|
+
// Optional: viewFormats can be added here if needed for SRGB views
|
|
1741
|
+
// viewFormats: [this.presentationFormat + '-srgb']
|
|
1713
1742
|
});
|
|
1714
1743
|
this._resizeEvent = new CResizeEvent(CResizeEvent.RESIZE, {
|
|
1715
1744
|
width: this.windowWidth,
|
|
@@ -22879,11 +22908,23 @@ const GSplat_VS = (
|
|
|
22879
22908
|
let radius = length(vec2f((diagonal1 - diagonal2) * 0.5, offDiagonal));
|
|
22880
22909
|
let lambda1 = mid + radius;
|
|
22881
22910
|
let lambda2 = max(mid - radius, MIN_LAMBDA);
|
|
22911
|
+
|
|
22912
|
+
let vmin = min(MAX_SPLAT_SIZE, min(viewport.x, viewport.y));
|
|
22913
|
+
let l1 = 2.0 * min(sqrt(2.0 * lambda1), vmin);
|
|
22914
|
+
let l2 = 2.0 * min(sqrt(2.0 * lambda2), vmin);
|
|
22915
|
+
|
|
22916
|
+
// if (l1 < 2.0 && l2 < 2.0) {
|
|
22917
|
+
// return discardSplat();
|
|
22918
|
+
// }
|
|
22919
|
+
|
|
22920
|
+
let centerProj = projMat * vec4f(splat_cam, 1.0);
|
|
22921
|
+
let c = centerProj.ww * vec2f(1.0 / viewport.x, 1.0 / viewport.y);
|
|
22922
|
+
|
|
22882
22923
|
let diagonalVector = normalize(vec2f(offDiagonal, lambda1 - diagonal1));
|
|
22883
22924
|
|
|
22884
22925
|
// Calculate axis vectors with size clamping
|
|
22885
|
-
let v1 =
|
|
22886
|
-
let v2 =
|
|
22926
|
+
let v1 = l1 * diagonalVector;
|
|
22927
|
+
let v2 = l2 * vec2f(diagonalVector.y, -diagonalVector.x);
|
|
22887
22928
|
|
|
22888
22929
|
// WebGPU Y-axis flip: WebGPU NDC Y goes from top(-1) to bottom(1), opposite of WebGL
|
|
22889
22930
|
return vec4f(v1.x, -v1.y, v2.x, -v2.y);
|
|
@@ -22949,11 +22990,13 @@ const GSplat_VS = (
|
|
|
22949
22990
|
let v1v2 = calcV1V2(splat_cam.xyz, splatData.covA, splatData.covB, W, viewport, matrix_projection);
|
|
22950
22991
|
|
|
22951
22992
|
// Calculate scale based on alpha (optimized formula)
|
|
22952
|
-
let
|
|
22993
|
+
let t = pow(splat_cam.z + 0.5, 5);
|
|
22994
|
+
let scale = min(1.0, sqrt(-log(1.0 / (255.0 * color.a))) / 2.0);
|
|
22953
22995
|
|
|
22954
22996
|
// Apply visBoost (size multiplier)
|
|
22955
22997
|
let visBoost = materialUniform.tex_params.w;
|
|
22956
|
-
let
|
|
22998
|
+
let expt = exp(-1.0 / t);
|
|
22999
|
+
let v1v2_scaled = v1v2 * (scale * visBoost * expt);
|
|
22957
23000
|
|
|
22958
23001
|
// Pixel coverage culling (vectorized squared length calculation)
|
|
22959
23002
|
let v1v2_sq = v1v2_scaled * v1v2_scaled;
|
|
@@ -22987,7 +23030,7 @@ const GSplat_VS = (
|
|
|
22987
23030
|
|
|
22988
23031
|
var o: VSOut;
|
|
22989
23032
|
o.member = splat_proj + vec4f(offset, 0.0, 0.0);
|
|
22990
|
-
o.vTexCoord = vertex_pos * (scale
|
|
23033
|
+
o.vTexCoord = vertex_pos * (scale);
|
|
22991
23034
|
o.vColor = color;
|
|
22992
23035
|
|
|
22993
23036
|
return o;
|
|
@@ -23001,16 +23044,30 @@ const GSplat_FS = (
|
|
|
23001
23044
|
|
|
23002
23045
|
// Constants
|
|
23003
23046
|
const ALPHA_THRESHOLD: f32 = 0.00392156863; // 1.0 / 255.0
|
|
23004
|
-
const GAUSSIAN_SCALE: f32 = 4.0;
|
|
23047
|
+
// const GAUSSIAN_SCALE: f32 = 4.0;
|
|
23048
|
+
const EXP4 = exp(-4.0);
|
|
23049
|
+
const INV_EXP4 = 1.0 / (1.0 - EXP4);
|
|
23050
|
+
|
|
23051
|
+
fn normExp(x: f32) -> f32 {
|
|
23052
|
+
return (exp(x * -4.0) - EXP4) * INV_EXP4;
|
|
23053
|
+
}
|
|
23005
23054
|
|
|
23006
23055
|
// === evalSplat() - optimized gaussian evaluation ===
|
|
23007
23056
|
fn evalSplat(texCoord: vec2f, color: vec4f) -> vec4f {
|
|
23008
23057
|
let A = dot(texCoord, texCoord);
|
|
23058
|
+
|
|
23059
|
+
if (A > 1.0) {
|
|
23060
|
+
discard;
|
|
23061
|
+
// return vec4f(1.0, 0.0, 0.0, 0.5);
|
|
23062
|
+
}
|
|
23009
23063
|
|
|
23010
23064
|
// Branch-less optimization using select
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23065
|
+
var alpha = normExp(A) * color.a;
|
|
23066
|
+
|
|
23067
|
+
if (alpha < ALPHA_THRESHOLD) {
|
|
23068
|
+
discard;
|
|
23069
|
+
// alpha = 0.5;
|
|
23070
|
+
}
|
|
23014
23071
|
return vec4f(color.rgb, alpha);
|
|
23015
23072
|
}
|
|
23016
23073
|
|
|
@@ -23257,8 +23314,9 @@ let GSplatShader = class extends Shader {
|
|
|
23257
23314
|
pass.cullMode = GPUCullMode.none;
|
|
23258
23315
|
pass.shaderState.transparent = true;
|
|
23259
23316
|
pass.shaderState.blendMode = BlendMode.NORMAL;
|
|
23260
|
-
pass.shaderState.writeMasks = [15,
|
|
23317
|
+
pass.shaderState.writeMasks = [15, 0];
|
|
23261
23318
|
pass.shaderState.castReflection = false;
|
|
23319
|
+
pass.shaderState.depthCompare = GPUCompareFunction.less;
|
|
23262
23320
|
this.addRenderPass(pass);
|
|
23263
23321
|
this.setDefault();
|
|
23264
23322
|
}
|
|
@@ -24007,17 +24065,17 @@ class GSplatGeometry extends GeometryBase {
|
|
|
24007
24065
|
const meshPositions = new Float32Array(12 * batchSize);
|
|
24008
24066
|
for (let i = 0; i < batchSize; ++i) {
|
|
24009
24067
|
meshPositions.set([
|
|
24010
|
-
-
|
|
24011
|
-
-
|
|
24068
|
+
-1,
|
|
24069
|
+
-1,
|
|
24012
24070
|
i,
|
|
24013
|
-
|
|
24014
|
-
-
|
|
24071
|
+
1,
|
|
24072
|
+
-1,
|
|
24015
24073
|
i,
|
|
24016
|
-
|
|
24017
|
-
|
|
24074
|
+
1,
|
|
24075
|
+
1,
|
|
24018
24076
|
i,
|
|
24019
|
-
-
|
|
24020
|
-
|
|
24077
|
+
-1,
|
|
24078
|
+
1,
|
|
24021
24079
|
i
|
|
24022
24080
|
], i * 12);
|
|
24023
24081
|
}
|
|
@@ -25361,7 +25419,6 @@ const PointCloud_FS = (
|
|
|
25361
25419
|
}
|
|
25362
25420
|
|
|
25363
25421
|
o.color = vColor;
|
|
25364
|
-
o.gBuffer = vec4f(0.0);
|
|
25365
25422
|
return o;
|
|
25366
25423
|
}
|
|
25367
25424
|
`
|
|
@@ -25388,7 +25445,7 @@ let PointCloudShader = class extends Shader {
|
|
|
25388
25445
|
pass.cullMode = GPUCullMode.none;
|
|
25389
25446
|
pass.shaderState.transparent = false;
|
|
25390
25447
|
pass.shaderState.blendMode = BlendMode.NORMAL;
|
|
25391
|
-
pass.shaderState.writeMasks = [15,
|
|
25448
|
+
pass.shaderState.writeMasks = [15, 0];
|
|
25392
25449
|
pass.shaderState.castReflection = false;
|
|
25393
25450
|
this.addRenderPass(pass);
|
|
25394
25451
|
this.setDefault();
|
|
@@ -27481,6 +27538,8 @@ class GPUContext {
|
|
|
27481
27538
|
static matrixCount = 0;
|
|
27482
27539
|
static lastRenderPassState;
|
|
27483
27540
|
static LastCommand;
|
|
27541
|
+
static multiTextureViewCache = /* @__PURE__ */ new WeakMap();
|
|
27542
|
+
static swapchainTextureCache = { texture: null, view: null };
|
|
27484
27543
|
static bindPipeline(encoder, renderShader) {
|
|
27485
27544
|
if (GPUContext.lastShader != renderShader) {
|
|
27486
27545
|
GPUContext.lastShader = renderShader;
|
|
@@ -27568,21 +27627,40 @@ class GPUContext {
|
|
|
27568
27627
|
const renderTarget = renderPassState.renderTargets[i];
|
|
27569
27628
|
let att = renderPassState.renderPassDescriptor.colorAttachments[i];
|
|
27570
27629
|
if (renderPassState.multisample > 0 && renderPassState.renderTargets.length == 1) {
|
|
27571
|
-
|
|
27630
|
+
let multiView = this.multiTextureViewCache.get(renderPassState.multiTexture);
|
|
27631
|
+
if (!multiView) {
|
|
27632
|
+
multiView = renderPassState.multiTexture.createView();
|
|
27633
|
+
this.multiTextureViewCache.set(renderPassState.multiTexture, multiView);
|
|
27634
|
+
}
|
|
27635
|
+
att.view = multiView;
|
|
27572
27636
|
att.resolveTarget = renderTarget.getGPUView();
|
|
27573
27637
|
} else {
|
|
27574
|
-
att.view = renderTarget.
|
|
27638
|
+
att.view = renderTarget.getGPUView();
|
|
27575
27639
|
}
|
|
27576
27640
|
}
|
|
27577
27641
|
return command.beginRenderPass(renderPassState.renderPassDescriptor);
|
|
27578
27642
|
} else {
|
|
27579
27643
|
let att0 = renderPassState.renderPassDescriptor.colorAttachments[0];
|
|
27580
27644
|
if (att0) {
|
|
27645
|
+
const swapchainTexture = webGPUContext.context.getCurrentTexture();
|
|
27581
27646
|
if (renderPassState.multisample > 0) {
|
|
27582
|
-
|
|
27583
|
-
|
|
27647
|
+
let multiView = this.multiTextureViewCache.get(renderPassState.multiTexture);
|
|
27648
|
+
if (!multiView) {
|
|
27649
|
+
multiView = renderPassState.multiTexture.createView();
|
|
27650
|
+
this.multiTextureViewCache.set(renderPassState.multiTexture, multiView);
|
|
27651
|
+
}
|
|
27652
|
+
att0.view = multiView;
|
|
27653
|
+
if (this.swapchainTextureCache.texture !== swapchainTexture) {
|
|
27654
|
+
this.swapchainTextureCache.texture = swapchainTexture;
|
|
27655
|
+
this.swapchainTextureCache.view = swapchainTexture.createView();
|
|
27656
|
+
}
|
|
27657
|
+
att0.resolveTarget = this.swapchainTextureCache.view;
|
|
27584
27658
|
} else {
|
|
27585
|
-
|
|
27659
|
+
if (this.swapchainTextureCache.texture !== swapchainTexture) {
|
|
27660
|
+
this.swapchainTextureCache.texture = swapchainTexture;
|
|
27661
|
+
this.swapchainTextureCache.view = swapchainTexture.createView();
|
|
27662
|
+
}
|
|
27663
|
+
att0.view = this.swapchainTextureCache.view;
|
|
27586
27664
|
}
|
|
27587
27665
|
}
|
|
27588
27666
|
return command.beginRenderPass(renderPassState.renderPassDescriptor);
|
|
@@ -42285,7 +42363,7 @@ class PostProcessingComponent extends ComponentBase {
|
|
|
42285
42363
|
}
|
|
42286
42364
|
}
|
|
42287
42365
|
|
|
42288
|
-
const version = "1.0.
|
|
42366
|
+
const version = "1.0.43";
|
|
42289
42367
|
|
|
42290
42368
|
class Engine3D {
|
|
42291
42369
|
/**
|