@d5techs/3dgs-lib 1.4.71 → 1.4.73

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
@@ -2112,7 +2112,8 @@ struct V { @builtin(position) pos: vec4<f32>, @location(0) dir: vec3<f32> };
2112
2112
  return o;
2113
2113
  }
2114
2114
  @fragment fn fs(i: V) -> @location(0) vec4<f32> {
2115
- return vec4(textureSample(cubeTexture, cubeSampler, normalize(i.dir)).rgb, 1.);
2115
+ let d = normalize(i.dir);
2116
+ return vec4(textureSample(cubeTexture, cubeSampler, vec3(-d.x, d.y, -d.z)).rgb, 1.);
2116
2117
  }`
2117
2118
  );
2118
2119
  class SkyboxRenderer {
@@ -2151,7 +2152,7 @@ class SkyboxRenderer {
2151
2152
  size: 64,
2152
2153
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
2153
2154
  });
2154
- this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear" });
2155
+ this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear", mipmapFilter: "linear" });
2155
2156
  }
2156
2157
  get isActive() {
2157
2158
  return this.active && this.texture !== null && this.bindGroup !== null;
@@ -2173,10 +2174,12 @@ class SkyboxRenderer {
2173
2174
  throw new Error("SkyboxRenderer: all cubemap faces must share the same dimensions");
2174
2175
  }
2175
2176
  }
2177
+ const mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1;
2176
2178
  const tex = this.device.createTexture({
2177
2179
  dimension: "2d",
2178
2180
  size: [width, height, 6],
2179
2181
  format: "rgba8unorm",
2182
+ mipLevelCount,
2180
2183
  usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
2181
2184
  });
2182
2185
  for (let layer = 0; layer < 6; layer++) {
@@ -2187,6 +2190,7 @@ class SkyboxRenderer {
2187
2190
  );
2188
2191
  }
2189
2192
  bitmaps.forEach((b) => b.close());
2193
+ this.generateMipmaps(tex, width, height, 6, mipLevelCount);
2190
2194
  this.bindGroup = this.device.createBindGroup({
2191
2195
  layout: this.cubeBindGroupLayout,
2192
2196
  entries: [
@@ -2225,6 +2229,80 @@ class SkyboxRenderer {
2225
2229
  pass.setBindGroup(0, this.bindGroup);
2226
2230
  pass.draw(3);
2227
2231
  }
2232
+ generateMipmaps(tex, baseWidth, baseHeight, layerCount, mipLevelCount) {
2233
+ if (mipLevelCount <= 1) return;
2234
+ const module = this.device.createShaderModule({
2235
+ code: (
2236
+ /* wgsl */
2237
+ `
2238
+ @group(0) @binding(0) var src: texture_2d<f32>;
2239
+ @group(0) @binding(1) var srcSampler: sampler;
2240
+ struct V { @builtin(position) pos: vec4<f32>, @location(0) uv: vec2<f32> };
2241
+ @vertex fn vs(@builtin(vertex_index) vi: u32) -> V {
2242
+ let ps = array<vec2<f32>,3>(vec2(0.,0.),vec2(2.,0.),vec2(0.,2.));
2243
+ var o: V; let p = ps[vi];
2244
+ o.pos = vec4(p * 2. - 1., 0., 1.);
2245
+ o.uv = vec2(p.x, 1. - p.y);
2246
+ return o;
2247
+ }
2248
+ @fragment fn fs(i: V) -> @location(0) vec4<f32> {
2249
+ return textureSample(src, srcSampler, i.uv);
2250
+ }`
2251
+ )
2252
+ });
2253
+ const bgl = this.device.createBindGroupLayout({
2254
+ entries: [
2255
+ { binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float" } },
2256
+ { binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } }
2257
+ ]
2258
+ });
2259
+ const pipeline = this.device.createRenderPipeline({
2260
+ layout: this.device.createPipelineLayout({ bindGroupLayouts: [bgl] }),
2261
+ vertex: { module, entryPoint: "vs" },
2262
+ fragment: { module, entryPoint: "fs", targets: [{ format: "rgba8unorm" }] },
2263
+ primitive: { topology: "triangle-list" }
2264
+ });
2265
+ const linearSampler = this.device.createSampler({ magFilter: "linear", minFilter: "linear" });
2266
+ const encoder = this.device.createCommandEncoder();
2267
+ for (let level = 1; level < mipLevelCount; level++) {
2268
+ for (let layer = 0; layer < layerCount; layer++) {
2269
+ const srcView = tex.createView({
2270
+ dimension: "2d",
2271
+ baseMipLevel: level - 1,
2272
+ mipLevelCount: 1,
2273
+ baseArrayLayer: layer,
2274
+ arrayLayerCount: 1
2275
+ });
2276
+ const dstView = tex.createView({
2277
+ dimension: "2d",
2278
+ baseMipLevel: level,
2279
+ mipLevelCount: 1,
2280
+ baseArrayLayer: layer,
2281
+ arrayLayerCount: 1
2282
+ });
2283
+ const bg = this.device.createBindGroup({
2284
+ layout: bgl,
2285
+ entries: [
2286
+ { binding: 0, resource: srcView },
2287
+ { binding: 1, resource: linearSampler }
2288
+ ]
2289
+ });
2290
+ const pass = encoder.beginRenderPass({
2291
+ colorAttachments: [{
2292
+ view: dstView,
2293
+ loadOp: "clear",
2294
+ storeOp: "store",
2295
+ clearValue: { r: 0, g: 0, b: 0, a: 1 }
2296
+ }]
2297
+ });
2298
+ pass.setPipeline(pipeline);
2299
+ pass.setBindGroup(0, bg);
2300
+ pass.draw(3);
2301
+ pass.end();
2302
+ }
2303
+ }
2304
+ this.device.queue.submit([encoder.finish()]);
2305
+ }
2228
2306
  clear() {
2229
2307
  if (this.texture) {
2230
2308
  this.texture.destroy();