@d5techs/3dgs-lib 1.4.38 → 1.4.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/3dgs-lib.cjs +256 -0
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +256 -0
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/App.d.ts +11 -0
- package/dist/core/SkyboxRenderer.d.ts +24 -0
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/3dgs-lib.js
CHANGED
|
@@ -2076,6 +2076,228 @@ class SceneAidsRenderer {
|
|
|
2076
2076
|
this.axesBindGroup = null;
|
|
2077
2077
|
}
|
|
2078
2078
|
}
|
|
2079
|
+
const WGSL = (
|
|
2080
|
+
/* wgsl */
|
|
2081
|
+
`
|
|
2082
|
+
struct Uniforms {
|
|
2083
|
+
invViewProjNoTrans: mat4x4<f32>,
|
|
2084
|
+
};
|
|
2085
|
+
|
|
2086
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
2087
|
+
@group(0) @binding(1) var cubeSampler: sampler;
|
|
2088
|
+
@group(0) @binding(2) var cubeTexture: texture_cube<f32>;
|
|
2089
|
+
|
|
2090
|
+
struct VSOut {
|
|
2091
|
+
@builtin(position) position: vec4<f32>,
|
|
2092
|
+
@location(0) dir: vec3<f32>,
|
|
2093
|
+
};
|
|
2094
|
+
|
|
2095
|
+
@vertex
|
|
2096
|
+
fn vs(@builtin(vertex_index) vi: u32) -> VSOut {
|
|
2097
|
+
let positions = array<vec2<f32>, 3>(
|
|
2098
|
+
vec2<f32>(-1.0, -1.0),
|
|
2099
|
+
vec2<f32>(3.0, -1.0),
|
|
2100
|
+
vec2<f32>(-1.0, 3.0),
|
|
2101
|
+
);
|
|
2102
|
+
var out: VSOut;
|
|
2103
|
+
let p = positions[vi];
|
|
2104
|
+
out.position = vec4<f32>(p, 0.0, 1.0);
|
|
2105
|
+
let unprojected = uniforms.invViewProjNoTrans * vec4<f32>(p, 1.0, 1.0);
|
|
2106
|
+
out.dir = unprojected.xyz / unprojected.w;
|
|
2107
|
+
return out;
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
@fragment
|
|
2111
|
+
fn fs(input: VSOut) -> @location(0) vec4<f32> {
|
|
2112
|
+
return textureSample(cubeTexture, cubeSampler, normalize(input.dir));
|
|
2113
|
+
}
|
|
2114
|
+
`
|
|
2115
|
+
);
|
|
2116
|
+
class SkyboxRenderer {
|
|
2117
|
+
constructor(device, format, depthFormat) {
|
|
2118
|
+
__publicField(this, "device");
|
|
2119
|
+
__publicField(this, "format");
|
|
2120
|
+
__publicField(this, "depthFormat");
|
|
2121
|
+
__publicField(this, "shaderModule");
|
|
2122
|
+
__publicField(this, "bindGroupLayout");
|
|
2123
|
+
__publicField(this, "pipelineLayout");
|
|
2124
|
+
__publicField(this, "pipeline");
|
|
2125
|
+
__publicField(this, "uniformBuffer");
|
|
2126
|
+
__publicField(this, "sampler");
|
|
2127
|
+
__publicField(this, "scratchViewNoTrans", new Float32Array(16));
|
|
2128
|
+
__publicField(this, "scratchVp", new Float32Array(16));
|
|
2129
|
+
__publicField(this, "scratchInv", new Float32Array(16));
|
|
2130
|
+
__publicField(this, "cubeTexture", null);
|
|
2131
|
+
__publicField(this, "cubeBindGroup", null);
|
|
2132
|
+
this.device = device;
|
|
2133
|
+
this.format = format;
|
|
2134
|
+
this.depthFormat = depthFormat;
|
|
2135
|
+
this.shaderModule = device.createShaderModule({ code: WGSL });
|
|
2136
|
+
this.bindGroupLayout = device.createBindGroupLayout({
|
|
2137
|
+
entries: [
|
|
2138
|
+
{
|
|
2139
|
+
binding: 0,
|
|
2140
|
+
visibility: GPUShaderStage.VERTEX,
|
|
2141
|
+
buffer: { type: "uniform", minBindingSize: 64 }
|
|
2142
|
+
},
|
|
2143
|
+
{
|
|
2144
|
+
binding: 1,
|
|
2145
|
+
visibility: GPUShaderStage.FRAGMENT,
|
|
2146
|
+
sampler: { type: "filtering" }
|
|
2147
|
+
},
|
|
2148
|
+
{
|
|
2149
|
+
binding: 2,
|
|
2150
|
+
visibility: GPUShaderStage.FRAGMENT,
|
|
2151
|
+
texture: { sampleType: "float", viewDimension: "cube" }
|
|
2152
|
+
}
|
|
2153
|
+
]
|
|
2154
|
+
});
|
|
2155
|
+
this.pipelineLayout = device.createPipelineLayout({
|
|
2156
|
+
bindGroupLayouts: [this.bindGroupLayout]
|
|
2157
|
+
});
|
|
2158
|
+
this.pipeline = device.createRenderPipeline({
|
|
2159
|
+
layout: this.pipelineLayout,
|
|
2160
|
+
vertex: {
|
|
2161
|
+
module: this.shaderModule,
|
|
2162
|
+
entryPoint: "vs"
|
|
2163
|
+
},
|
|
2164
|
+
fragment: {
|
|
2165
|
+
module: this.shaderModule,
|
|
2166
|
+
entryPoint: "fs",
|
|
2167
|
+
targets: [{ format: this.format }]
|
|
2168
|
+
},
|
|
2169
|
+
primitive: {
|
|
2170
|
+
topology: "triangle-list",
|
|
2171
|
+
cullMode: "none"
|
|
2172
|
+
},
|
|
2173
|
+
depthStencil: {
|
|
2174
|
+
format: this.depthFormat,
|
|
2175
|
+
depthWriteEnabled: false,
|
|
2176
|
+
depthCompare: "always"
|
|
2177
|
+
}
|
|
2178
|
+
});
|
|
2179
|
+
this.uniformBuffer = device.createBuffer({
|
|
2180
|
+
size: 64,
|
|
2181
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
2182
|
+
});
|
|
2183
|
+
this.sampler = device.createSampler({
|
|
2184
|
+
magFilter: "linear",
|
|
2185
|
+
minFilter: "linear"
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
get isActive() {
|
|
2189
|
+
return this.cubeTexture !== null && this.cubeBindGroup !== null;
|
|
2190
|
+
}
|
|
2191
|
+
async loadCubemap(faceUrls) {
|
|
2192
|
+
this.clear();
|
|
2193
|
+
const bitmaps = await Promise.all(
|
|
2194
|
+
faceUrls.map(async (url) => {
|
|
2195
|
+
const res = await fetch(url);
|
|
2196
|
+
if (!res.ok) {
|
|
2197
|
+
throw new Error(`SkyboxRenderer: failed to fetch ${url} (${res.status})`);
|
|
2198
|
+
}
|
|
2199
|
+
const blob = await res.blob();
|
|
2200
|
+
return createImageBitmap(blob);
|
|
2201
|
+
})
|
|
2202
|
+
);
|
|
2203
|
+
const width = bitmaps[0].width;
|
|
2204
|
+
const height = bitmaps[0].height;
|
|
2205
|
+
for (let i = 1; i < 6; i++) {
|
|
2206
|
+
if (bitmaps[i].width !== width || bitmaps[i].height !== height) {
|
|
2207
|
+
bitmaps.forEach((b) => b.close());
|
|
2208
|
+
throw new Error("SkyboxRenderer: all cubemap faces must share the same dimensions");
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
const tex = this.device.createTexture({
|
|
2212
|
+
dimension: "2d",
|
|
2213
|
+
size: [width, height, 6],
|
|
2214
|
+
format: "rgba8unorm",
|
|
2215
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
2216
|
+
});
|
|
2217
|
+
for (let layer = 0; layer < 6; layer++) {
|
|
2218
|
+
this.device.queue.copyExternalImageToTexture(
|
|
2219
|
+
{ source: bitmaps[layer] },
|
|
2220
|
+
{ texture: tex, mipLevel: 0, origin: { x: 0, y: 0, z: layer } },
|
|
2221
|
+
{ width, height, depthOrArrayLayers: 1 }
|
|
2222
|
+
);
|
|
2223
|
+
}
|
|
2224
|
+
bitmaps.forEach((b) => b.close());
|
|
2225
|
+
const cubeView = tex.createView({ dimension: "cube" });
|
|
2226
|
+
const bindGroup = this.device.createBindGroup({
|
|
2227
|
+
layout: this.bindGroupLayout,
|
|
2228
|
+
entries: [
|
|
2229
|
+
{ binding: 0, resource: { buffer: this.uniformBuffer } },
|
|
2230
|
+
{ binding: 1, resource: this.sampler },
|
|
2231
|
+
{ binding: 2, resource: cubeView }
|
|
2232
|
+
]
|
|
2233
|
+
});
|
|
2234
|
+
this.cubeTexture = tex;
|
|
2235
|
+
this.cubeBindGroup = bindGroup;
|
|
2236
|
+
}
|
|
2237
|
+
render(pass, viewMatrix, projectionMatrix) {
|
|
2238
|
+
if (!this.isActive || !this.cubeBindGroup) {
|
|
2239
|
+
return;
|
|
2240
|
+
}
|
|
2241
|
+
this.scratchViewNoTrans.set(viewMatrix);
|
|
2242
|
+
this.scratchViewNoTrans[12] = 0;
|
|
2243
|
+
this.scratchViewNoTrans[13] = 0;
|
|
2244
|
+
this.scratchViewNoTrans[14] = 0;
|
|
2245
|
+
SkyboxRenderer.multiplyMat4(this.scratchVp, projectionMatrix, this.scratchViewNoTrans);
|
|
2246
|
+
if (!SkyboxRenderer.invertMat4(this.scratchInv, this.scratchVp)) {
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
this.device.queue.writeBuffer(this.uniformBuffer, 0, this.scratchInv);
|
|
2250
|
+
pass.setPipeline(this.pipeline);
|
|
2251
|
+
pass.setBindGroup(0, this.cubeBindGroup);
|
|
2252
|
+
pass.draw(3);
|
|
2253
|
+
}
|
|
2254
|
+
clear() {
|
|
2255
|
+
if (this.cubeTexture) {
|
|
2256
|
+
this.cubeTexture.destroy();
|
|
2257
|
+
this.cubeTexture = null;
|
|
2258
|
+
}
|
|
2259
|
+
this.cubeBindGroup = null;
|
|
2260
|
+
}
|
|
2261
|
+
destroy() {
|
|
2262
|
+
this.clear();
|
|
2263
|
+
this.uniformBuffer.destroy();
|
|
2264
|
+
}
|
|
2265
|
+
static invertMat4(out, e) {
|
|
2266
|
+
const inv = new Float32Array(16);
|
|
2267
|
+
inv[0] = e[5] * e[10] * e[15] - e[5] * e[11] * e[14] - e[9] * e[6] * e[15] + e[9] * e[7] * e[14] + e[13] * e[6] * e[11] - e[13] * e[7] * e[10];
|
|
2268
|
+
inv[4] = -e[4] * e[10] * e[15] + e[4] * e[11] * e[14] + e[8] * e[6] * e[15] - e[8] * e[7] * e[14] - e[12] * e[6] * e[11] + e[12] * e[7] * e[10];
|
|
2269
|
+
inv[8] = e[4] * e[9] * e[15] - e[4] * e[11] * e[13] - e[8] * e[5] * e[15] + e[8] * e[7] * e[13] + e[12] * e[5] * e[11] - e[12] * e[7] * e[9];
|
|
2270
|
+
inv[12] = -e[4] * e[9] * e[14] + e[4] * e[10] * e[13] + e[8] * e[5] * e[14] - e[8] * e[6] * e[13] - e[12] * e[5] * e[10] + e[12] * e[6] * e[9];
|
|
2271
|
+
inv[1] = -e[1] * e[10] * e[15] + e[1] * e[11] * e[14] + e[9] * e[2] * e[15] - e[9] * e[3] * e[14] - e[13] * e[2] * e[11] + e[13] * e[3] * e[10];
|
|
2272
|
+
inv[5] = e[0] * e[10] * e[15] - e[0] * e[11] * e[14] - e[8] * e[2] * e[15] + e[8] * e[3] * e[14] + e[12] * e[2] * e[11] - e[12] * e[3] * e[10];
|
|
2273
|
+
inv[9] = -e[0] * e[9] * e[15] + e[0] * e[11] * e[13] + e[8] * e[1] * e[15] - e[8] * e[3] * e[13] - e[12] * e[1] * e[11] + e[12] * e[3] * e[9];
|
|
2274
|
+
inv[13] = e[0] * e[9] * e[14] - e[0] * e[10] * e[13] - e[8] * e[1] * e[14] + e[8] * e[2] * e[13] + e[12] * e[1] * e[10] - e[12] * e[2] * e[9];
|
|
2275
|
+
inv[2] = e[1] * e[6] * e[15] - e[1] * e[7] * e[14] - e[5] * e[2] * e[15] + e[5] * e[3] * e[14] + e[13] * e[2] * e[7] - e[13] * e[3] * e[6];
|
|
2276
|
+
inv[6] = -e[0] * e[6] * e[15] + e[0] * e[7] * e[14] + e[4] * e[2] * e[15] - e[4] * e[3] * e[14] - e[12] * e[2] * e[7] + e[12] * e[3] * e[6];
|
|
2277
|
+
inv[10] = e[0] * e[5] * e[15] - e[0] * e[7] * e[13] - e[4] * e[1] * e[15] + e[4] * e[3] * e[13] + e[12] * e[1] * e[7] - e[12] * e[3] * e[5];
|
|
2278
|
+
inv[14] = -e[0] * e[5] * e[14] + e[0] * e[6] * e[13] + e[4] * e[1] * e[14] - e[4] * e[2] * e[13] - e[12] * e[1] * e[6] + e[12] * e[2] * e[5];
|
|
2279
|
+
inv[3] = -e[1] * e[6] * e[11] + e[1] * e[7] * e[10] + e[5] * e[2] * e[11] - e[5] * e[3] * e[10] - e[9] * e[2] * e[7] + e[9] * e[3] * e[6];
|
|
2280
|
+
inv[7] = e[0] * e[6] * e[11] - e[0] * e[7] * e[10] - e[4] * e[2] * e[11] + e[4] * e[3] * e[10] + e[8] * e[2] * e[7] - e[8] * e[3] * e[6];
|
|
2281
|
+
inv[11] = -e[0] * e[5] * e[11] + e[0] * e[7] * e[9] + e[4] * e[1] * e[11] - e[4] * e[3] * e[9] - e[8] * e[1] * e[7] + e[8] * e[3] * e[5];
|
|
2282
|
+
inv[15] = e[0] * e[5] * e[10] - e[0] * e[6] * e[9] - e[4] * e[1] * e[10] + e[4] * e[2] * e[9] + e[8] * e[1] * e[6] - e[8] * e[2] * e[5];
|
|
2283
|
+
const det = e[0] * inv[0] + e[1] * inv[4] + e[2] * inv[8] + e[3] * inv[12];
|
|
2284
|
+
if (Math.abs(det) < 1e-10) {
|
|
2285
|
+
return false;
|
|
2286
|
+
}
|
|
2287
|
+
const invDet = 1 / det;
|
|
2288
|
+
for (let i = 0; i < 16; i++) {
|
|
2289
|
+
out[i] = inv[i] * invDet;
|
|
2290
|
+
}
|
|
2291
|
+
return true;
|
|
2292
|
+
}
|
|
2293
|
+
static multiplyMat4(out, a, b) {
|
|
2294
|
+
for (let c = 0; c < 4; c++) {
|
|
2295
|
+
for (let r = 0; r < 4; r++) {
|
|
2296
|
+
out[c * 4 + r] = a[0 * 4 + r] * b[c * 4 + 0] + a[1 * 4 + r] * b[c * 4 + 1] + a[2 * 4 + r] * b[c * 4 + 2] + a[3 * 4 + r] * b[c * 4 + 3];
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2079
2301
|
class Mesh {
|
|
2080
2302
|
constructor(vertexBuffer, vertexCount, indexBuffer = null, indexCount = 0, boundingBox) {
|
|
2081
2303
|
__publicField(this, "vertexBuffer");
|
|
@@ -18242,6 +18464,7 @@ class App {
|
|
|
18242
18464
|
__publicField(this, "gizmoManager");
|
|
18243
18465
|
__publicField(this, "hotspotManager");
|
|
18244
18466
|
__publicField(this, "sceneAids");
|
|
18467
|
+
__publicField(this, "skyboxRenderer", null);
|
|
18245
18468
|
__publicField(this, "isRunning", false);
|
|
18246
18469
|
__publicField(this, "animationId", 0);
|
|
18247
18470
|
// 是否使用移动端渲染器
|
|
@@ -18681,11 +18904,15 @@ class App {
|
|
|
18681
18904
|
}
|
|
18682
18905
|
}
|
|
18683
18906
|
render() {
|
|
18907
|
+
var _a2;
|
|
18684
18908
|
this.camera.setAspect(this.renderer.getAspectRatio());
|
|
18685
18909
|
this.controls.update();
|
|
18686
18910
|
this.updateAdaptivePerformance();
|
|
18687
18911
|
this.hotspotManager.updateBillboards();
|
|
18688
18912
|
const pass = this.renderer.beginFrame();
|
|
18913
|
+
if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
|
|
18914
|
+
this.skyboxRenderer.render(pass, this.camera.viewMatrix, this.camera.projectionMatrix);
|
|
18915
|
+
}
|
|
18689
18916
|
const gsRenderer = this.sceneManager.getGSRenderer();
|
|
18690
18917
|
if (gsRenderer) {
|
|
18691
18918
|
gsRenderer.render(pass);
|
|
@@ -18845,6 +19072,34 @@ class App {
|
|
|
18845
19072
|
return false;
|
|
18846
19073
|
}
|
|
18847
19074
|
// ============================================
|
|
19075
|
+
// Skybox
|
|
19076
|
+
// ============================================
|
|
19077
|
+
async setSkybox(faceUrls) {
|
|
19078
|
+
if (!this.skyboxRenderer) {
|
|
19079
|
+
this.skyboxRenderer = new SkyboxRenderer(
|
|
19080
|
+
this.renderer.device,
|
|
19081
|
+
this.renderer.format,
|
|
19082
|
+
"depth24plus"
|
|
19083
|
+
);
|
|
19084
|
+
}
|
|
19085
|
+
await this.skyboxRenderer.loadCubemap([
|
|
19086
|
+
faceUrls.posX,
|
|
19087
|
+
faceUrls.negX,
|
|
19088
|
+
faceUrls.posY,
|
|
19089
|
+
faceUrls.negY,
|
|
19090
|
+
faceUrls.posZ,
|
|
19091
|
+
faceUrls.negZ
|
|
19092
|
+
]);
|
|
19093
|
+
}
|
|
19094
|
+
clearSkybox() {
|
|
19095
|
+
var _a2;
|
|
19096
|
+
(_a2 = this.skyboxRenderer) == null ? void 0 : _a2.clear();
|
|
19097
|
+
}
|
|
19098
|
+
isSkyboxActive() {
|
|
19099
|
+
var _a2;
|
|
19100
|
+
return ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) ?? false;
|
|
19101
|
+
}
|
|
19102
|
+
// ============================================
|
|
18848
19103
|
// Gizmo(委托给 GizmoManager)
|
|
18849
19104
|
// ============================================
|
|
18850
19105
|
getTransformGizmo() {
|
|
@@ -19305,6 +19560,7 @@ export {
|
|
|
19305
19560
|
SHMode,
|
|
19306
19561
|
SceneAidsRenderer,
|
|
19307
19562
|
SceneManager,
|
|
19563
|
+
SkyboxRenderer,
|
|
19308
19564
|
SplatBoundingBoxProvider,
|
|
19309
19565
|
SplatEditor,
|
|
19310
19566
|
SplatState,
|