@d5techs/3dgs-lib 1.4.38 → 1.4.40

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