@d5techs/3dgs-lib 1.4.41 → 1.4.43

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.js CHANGED
@@ -622,7 +622,7 @@ const _OrbitControls = class _OrbitControls {
622
622
  __publicField(this, "minPhi", 0.01);
623
623
  __publicField(this, "maxPhi", Math.PI - 0.01);
624
624
  // 灵敏度
625
- __publicField(this, "rotateSpeed", 5e-3);
625
+ __publicField(this, "rotateSpeed", 3e-3);
626
626
  __publicField(this, "zoomSpeed", 1e-3);
627
627
  __publicField(this, "panSpeed", 5e-3);
628
628
  // 移动端触摸灵敏度
@@ -2080,10 +2080,12 @@ const WGSL = (
2080
2080
  /* wgsl */
2081
2081
  `
2082
2082
  struct Uniforms {
2083
- invViewProjNoTrans: mat4x4<f32>,
2083
+ col0: vec4<f32>,
2084
+ col1: vec4<f32>,
2085
+ col2: vec4<f32>,
2084
2086
  };
2085
2087
 
2086
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
2088
+ @group(0) @binding(0) var<uniform> u: Uniforms;
2087
2089
  @group(0) @binding(1) var cubeSampler: sampler;
2088
2090
  @group(0) @binding(2) var cubeTexture: texture_cube<f32>;
2089
2091
 
@@ -2102,8 +2104,16 @@ fn vs(@builtin(vertex_index) vi: u32) -> VSOut {
2102
2104
  var out: VSOut;
2103
2105
  let p = positions[vi];
2104
2106
  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
+
2108
+ // col0.w = 1/proj[0] (aspect*tan(fov/2)), col1.w = 1/proj[5] (tan(fov/2))
2109
+ let eyeDir = vec3<f32>(p.x * u.col0.w, p.y * u.col1.w, -1.0);
2110
+
2111
+ // col0..2.xyz = rows of inverse view rotation (= transpose of view rotation)
2112
+ out.dir = vec3<f32>(
2113
+ dot(u.col0.xyz, eyeDir),
2114
+ dot(u.col1.xyz, eyeDir),
2115
+ dot(u.col2.xyz, eyeDir),
2116
+ );
2107
2117
  return out;
2108
2118
  }
2109
2119
 
@@ -2117,75 +2127,35 @@ fn fs(input: VSOut) -> @location(0) vec4<f32> {
2117
2127
  class SkyboxRenderer {
2118
2128
  constructor(device, format, depthFormat) {
2119
2129
  __publicField(this, "device");
2120
- __publicField(this, "format");
2121
- __publicField(this, "depthFormat");
2122
- __publicField(this, "shaderModule");
2123
- __publicField(this, "bindGroupLayout");
2124
- __publicField(this, "pipelineLayout");
2125
2130
  __publicField(this, "pipeline");
2126
2131
  __publicField(this, "uniformBuffer");
2127
2132
  __publicField(this, "sampler");
2128
- __publicField(this, "scratchViewNoTrans", new Float32Array(16));
2129
- __publicField(this, "scratchVp", new Float32Array(16));
2130
- __publicField(this, "scratchInv", new Float32Array(16));
2133
+ __publicField(this, "bindGroupLayout");
2134
+ __publicField(this, "uniformData", new Float32Array(12));
2131
2135
  __publicField(this, "cubeTexture", null);
2132
2136
  __publicField(this, "cubeBindGroup", null);
2133
- __publicField(this, "uniformDirty", false);
2137
+ __publicField(this, "frameReady", false);
2134
2138
  this.device = device;
2135
- this.format = format;
2136
- this.depthFormat = depthFormat;
2137
- this.shaderModule = device.createShaderModule({ code: WGSL });
2139
+ const shaderModule = device.createShaderModule({ code: WGSL });
2138
2140
  this.bindGroupLayout = device.createBindGroupLayout({
2139
2141
  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
- }
2142
+ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } },
2143
+ { binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
2144
+ { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "cube" } }
2155
2145
  ]
2156
2146
  });
2157
- this.pipelineLayout = device.createPipelineLayout({
2158
- bindGroupLayouts: [this.bindGroupLayout]
2159
- });
2160
2147
  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
- }
2148
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.bindGroupLayout] }),
2149
+ vertex: { module: shaderModule, entryPoint: "vs" },
2150
+ fragment: { module: shaderModule, entryPoint: "fs", targets: [{ format }] },
2151
+ primitive: { topology: "triangle-list", cullMode: "none" },
2152
+ depthStencil: { format: depthFormat, depthWriteEnabled: false, depthCompare: "always" }
2180
2153
  });
2181
2154
  this.uniformBuffer = device.createBuffer({
2182
- size: 64,
2155
+ size: 48,
2183
2156
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
2184
2157
  });
2185
- this.sampler = device.createSampler({
2186
- magFilter: "linear",
2187
- minFilter: "linear"
2188
- });
2158
+ this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear" });
2189
2159
  }
2190
2160
  get isActive() {
2191
2161
  return this.cubeTexture !== null && this.cubeBindGroup !== null;
@@ -2195,11 +2165,8 @@ class SkyboxRenderer {
2195
2165
  const bitmaps = await Promise.all(
2196
2166
  faceUrls.map(async (url) => {
2197
2167
  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);
2168
+ if (!res.ok) throw new Error(`SkyboxRenderer: failed to fetch ${url} (${res.status})`);
2169
+ return createImageBitmap(await res.blob());
2203
2170
  })
2204
2171
  );
2205
2172
  const width = bitmaps[0].width;
@@ -2224,40 +2191,43 @@ class SkyboxRenderer {
2224
2191
  );
2225
2192
  }
2226
2193
  bitmaps.forEach((b) => b.close());
2227
- const cubeView = tex.createView({ dimension: "cube" });
2228
- const bindGroup = this.device.createBindGroup({
2194
+ this.cubeBindGroup = this.device.createBindGroup({
2229
2195
  layout: this.bindGroupLayout,
2230
2196
  entries: [
2231
2197
  { binding: 0, resource: { buffer: this.uniformBuffer } },
2232
2198
  { binding: 1, resource: this.sampler },
2233
- { binding: 2, resource: cubeView }
2199
+ { binding: 2, resource: tex.createView({ dimension: "cube" }) }
2234
2200
  ]
2235
2201
  });
2236
2202
  this.cubeTexture = tex;
2237
- this.cubeBindGroup = bindGroup;
2238
2203
  }
2239
2204
  /**
2240
- * Must be called BEFORE beginFrame() to write uniform data outside the render pass.
2205
+ * Write uniforms BEFORE beginFrame(). No matrix inversion needed
2206
+ * we extract the view rotation transpose and inverse projection scalars directly.
2241
2207
  */
2242
2208
  prepareFrame(viewMatrix, projectionMatrix) {
2243
- if (!this.isActive) return;
2244
- this.scratchViewNoTrans.set(viewMatrix);
2245
- this.scratchViewNoTrans[12] = 0;
2246
- this.scratchViewNoTrans[13] = 0;
2247
- this.scratchViewNoTrans[14] = 0;
2248
- SkyboxRenderer.multiplyMat4(this.scratchVp, projectionMatrix, this.scratchViewNoTrans);
2249
- if (!SkyboxRenderer.invertMat4(this.scratchInv, this.scratchVp)) {
2250
- this.uniformDirty = false;
2209
+ if (!this.isActive) {
2210
+ this.frameReady = false;
2251
2211
  return;
2252
2212
  }
2253
- this.device.queue.writeBuffer(this.uniformBuffer, 0, this.scratchInv);
2254
- this.uniformDirty = true;
2213
+ const ud = this.uniformData;
2214
+ ud[0] = viewMatrix[0];
2215
+ ud[1] = viewMatrix[1];
2216
+ ud[2] = viewMatrix[2];
2217
+ ud[3] = 1 / projectionMatrix[0];
2218
+ ud[4] = viewMatrix[4];
2219
+ ud[5] = viewMatrix[5];
2220
+ ud[6] = viewMatrix[6];
2221
+ ud[7] = 1 / projectionMatrix[5];
2222
+ ud[8] = viewMatrix[8];
2223
+ ud[9] = viewMatrix[9];
2224
+ ud[10] = viewMatrix[10];
2225
+ ud[11] = 0;
2226
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, ud);
2227
+ this.frameReady = true;
2255
2228
  }
2256
- /**
2257
- * Draw the skybox into the given render pass. Call prepareFrame() first.
2258
- */
2259
2229
  draw(pass) {
2260
- if (!this.uniformDirty || !this.cubeBindGroup) return;
2230
+ if (!this.frameReady || !this.cubeBindGroup) return;
2261
2231
  pass.setPipeline(this.pipeline);
2262
2232
  pass.setBindGroup(0, this.cubeBindGroup);
2263
2233
  pass.draw(3);
@@ -2268,47 +2238,12 @@ class SkyboxRenderer {
2268
2238
  this.cubeTexture = null;
2269
2239
  }
2270
2240
  this.cubeBindGroup = null;
2271
- this.uniformDirty = false;
2241
+ this.frameReady = false;
2272
2242
  }
2273
2243
  destroy() {
2274
2244
  this.clear();
2275
2245
  this.uniformBuffer.destroy();
2276
2246
  }
2277
- static invertMat4(out, e) {
2278
- const inv = new Float32Array(16);
2279
- 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];
2280
- 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];
2281
- 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];
2282
- 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];
2283
- 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];
2284
- 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];
2285
- 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];
2286
- 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];
2287
- 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];
2288
- 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];
2289
- 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];
2290
- 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];
2291
- 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];
2292
- 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];
2293
- 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];
2294
- 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];
2295
- const det = e[0] * inv[0] + e[1] * inv[4] + e[2] * inv[8] + e[3] * inv[12];
2296
- if (Math.abs(det) < 1e-10) {
2297
- return false;
2298
- }
2299
- const invDet = 1 / det;
2300
- for (let i = 0; i < 16; i++) {
2301
- out[i] = inv[i] * invDet;
2302
- }
2303
- return true;
2304
- }
2305
- static multiplyMat4(out, a, b) {
2306
- for (let c = 0; c < 4; c++) {
2307
- for (let r = 0; r < 4; r++) {
2308
- 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];
2309
- }
2310
- }
2311
- }
2312
2247
  }
2313
2248
  class Mesh {
2314
2249
  constructor(vertexBuffer, vertexCount, indexBuffer = null, indexCount = 0, boundingBox) {