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