@d5techs/3dgs-lib 1.4.70 → 1.4.72
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 +87 -260
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +87 -260
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/App.d.ts +0 -2
- package/dist/core/SkyboxRenderer.d.ts +3 -7
- package/dist/index.d.ts +0 -2
- package/package.json +1 -1
- package/dist/loaders/HdrLoader.d.ts +0 -6
package/dist/3dgs-lib.cjs
CHANGED
|
@@ -2098,103 +2098,6 @@ class SceneAidsRenderer {
|
|
|
2098
2098
|
this.axesBindGroup = null;
|
|
2099
2099
|
}
|
|
2100
2100
|
}
|
|
2101
|
-
async function loadHdr(url) {
|
|
2102
|
-
const res = await fetch(url);
|
|
2103
|
-
if (!res.ok) throw new Error(`HdrLoader: fetch failed ${url} (${res.status})`);
|
|
2104
|
-
const buf = await res.arrayBuffer();
|
|
2105
|
-
return parseHdr(new Uint8Array(buf));
|
|
2106
|
-
}
|
|
2107
|
-
function parseHdr(bytes) {
|
|
2108
|
-
let pos = 0;
|
|
2109
|
-
const readLine = () => {
|
|
2110
|
-
let line = "";
|
|
2111
|
-
while (pos < bytes.length) {
|
|
2112
|
-
const c = bytes[pos++];
|
|
2113
|
-
if (c === 10) return line;
|
|
2114
|
-
line += String.fromCharCode(c);
|
|
2115
|
-
}
|
|
2116
|
-
return line;
|
|
2117
|
-
};
|
|
2118
|
-
const magic = readLine();
|
|
2119
|
-
if (!magic.startsWith("#?")) throw new Error("HdrLoader: not a Radiance HDR file");
|
|
2120
|
-
while (pos < bytes.length) {
|
|
2121
|
-
const line = readLine();
|
|
2122
|
-
if (line.length === 0) break;
|
|
2123
|
-
}
|
|
2124
|
-
const resLine = readLine();
|
|
2125
|
-
const m = resLine.match(/-Y\s+(\d+)\s+\+X\s+(\d+)/);
|
|
2126
|
-
if (!m) throw new Error("HdrLoader: unsupported resolution format: " + resLine);
|
|
2127
|
-
const height = parseInt(m[1], 10);
|
|
2128
|
-
const width = parseInt(m[2], 10);
|
|
2129
|
-
const rgbe = new Uint8Array(width * height * 4);
|
|
2130
|
-
for (let y = 0; y < height; y++) {
|
|
2131
|
-
const scanline = decodeScanline(bytes, pos, width);
|
|
2132
|
-
pos = scanline.newPos;
|
|
2133
|
-
rgbe.set(scanline.pixels, y * width * 4);
|
|
2134
|
-
}
|
|
2135
|
-
const data = new Float32Array(width * height * 4);
|
|
2136
|
-
for (let i = 0; i < width * height; i++) {
|
|
2137
|
-
const r = rgbe[i * 4];
|
|
2138
|
-
const g = rgbe[i * 4 + 1];
|
|
2139
|
-
const b = rgbe[i * 4 + 2];
|
|
2140
|
-
const e = rgbe[i * 4 + 3];
|
|
2141
|
-
if (e === 0) {
|
|
2142
|
-
data[i * 4] = 0;
|
|
2143
|
-
data[i * 4 + 1] = 0;
|
|
2144
|
-
data[i * 4 + 2] = 0;
|
|
2145
|
-
} else {
|
|
2146
|
-
const scale = Math.pow(2, e - 128 - 8);
|
|
2147
|
-
data[i * 4] = r * scale;
|
|
2148
|
-
data[i * 4 + 1] = g * scale;
|
|
2149
|
-
data[i * 4 + 2] = b * scale;
|
|
2150
|
-
}
|
|
2151
|
-
data[i * 4 + 3] = 1;
|
|
2152
|
-
}
|
|
2153
|
-
return { width, height, data };
|
|
2154
|
-
}
|
|
2155
|
-
function decodeScanline(bytes, pos, width) {
|
|
2156
|
-
const pixels = new Uint8Array(width * 4);
|
|
2157
|
-
if (width < 8 || width > 32767) {
|
|
2158
|
-
for (let i = 0; i < width * 4; i++) pixels[i] = bytes[pos++];
|
|
2159
|
-
return { pixels, newPos: pos };
|
|
2160
|
-
}
|
|
2161
|
-
const b0 = bytes[pos], b1 = bytes[pos + 1], b22 = bytes[pos + 2], b3 = bytes[pos + 3];
|
|
2162
|
-
if (b0 !== 2 || b1 !== 2 || (b22 & 128) !== 0) {
|
|
2163
|
-
for (let i = 0; i < width * 4; i++) pixels[i] = bytes[pos++];
|
|
2164
|
-
return { pixels, newPos: pos };
|
|
2165
|
-
}
|
|
2166
|
-
const lineWidth = b22 << 8 | b3;
|
|
2167
|
-
if (lineWidth !== width) throw new Error("HdrLoader: scanline width mismatch");
|
|
2168
|
-
pos += 4;
|
|
2169
|
-
for (let ch = 0; ch < 4; ch++) {
|
|
2170
|
-
let x = 0;
|
|
2171
|
-
while (x < width) {
|
|
2172
|
-
const code = bytes[pos++];
|
|
2173
|
-
if (code > 128) {
|
|
2174
|
-
const count = code - 128;
|
|
2175
|
-
const val = bytes[pos++];
|
|
2176
|
-
for (let i = 0; i < count; i++) pixels[(x + i) * 4 + ch] = val;
|
|
2177
|
-
x += count;
|
|
2178
|
-
} else {
|
|
2179
|
-
for (let i = 0; i < code; i++) pixels[(x + i) * 4 + ch] = bytes[pos++];
|
|
2180
|
-
x += code;
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
return { pixels, newPos: pos };
|
|
2185
|
-
}
|
|
2186
|
-
const f32Buf = new Float32Array(1);
|
|
2187
|
-
const u32Buf = new Uint32Array(f32Buf.buffer);
|
|
2188
|
-
function float32ToFloat16(val) {
|
|
2189
|
-
f32Buf[0] = val;
|
|
2190
|
-
const f = u32Buf[0];
|
|
2191
|
-
const sign = f >> 16 & 32768;
|
|
2192
|
-
const exp = (f >> 23 & 255) - 127 + 15;
|
|
2193
|
-
const frac = f >> 13 & 1023;
|
|
2194
|
-
if (exp <= 0) return sign;
|
|
2195
|
-
if (exp >= 31) return sign | 31744;
|
|
2196
|
-
return sign | exp << 10 | frac;
|
|
2197
|
-
}
|
|
2198
2101
|
const CUBE_WGSL = (
|
|
2199
2102
|
/* wgsl */
|
|
2200
2103
|
`
|
|
@@ -2211,62 +2114,8 @@ struct V { @builtin(position) pos: vec4<f32>, @location(0) dir: vec3<f32> };
|
|
|
2211
2114
|
return o;
|
|
2212
2115
|
}
|
|
2213
2116
|
@fragment fn fs(i: V) -> @location(0) vec4<f32> {
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
);
|
|
2217
|
-
const EQUIRECT_WGSL = (
|
|
2218
|
-
/* wgsl */
|
|
2219
|
-
`
|
|
2220
|
-
struct Uniforms { col0: vec4<f32>, col1: vec4<f32>, col2: vec4<f32>, cam: vec4<f32> };
|
|
2221
|
-
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
2222
|
-
@group(0) @binding(1) var envSampler: sampler;
|
|
2223
|
-
@group(0) @binding(2) var envTexture: texture_2d<f32>;
|
|
2224
|
-
struct V { @builtin(position) pos: vec4<f32>, @location(0) dir: vec3<f32> };
|
|
2225
|
-
const PI: f32 = 3.14159265358979;
|
|
2226
|
-
|
|
2227
|
-
fn dirToUv(d: vec3<f32>) -> vec2<f32> {
|
|
2228
|
-
return vec2(atan2(d.z, d.x) / (2.*PI) + .5, 1. - (asin(clamp(d.y,-1.,1.)) / PI + .5));
|
|
2229
|
-
}
|
|
2230
|
-
|
|
2231
|
-
@vertex fn vs(@builtin(vertex_index) vi: u32) -> V {
|
|
2232
|
-
let ps = array<vec2<f32>,3>(vec2(-1.,-1.),vec2(3.,-1.),vec2(-1.,3.));
|
|
2233
|
-
var o: V; let p = ps[vi]; o.pos = vec4(p, 0., 1.);
|
|
2234
|
-
let e = vec3(p.x*u.col0.w, p.y*u.col1.w, -1.);
|
|
2235
|
-
o.dir = vec3(dot(u.col0.xyz,e), dot(u.col1.xyz,e), dot(u.col2.xyz,e));
|
|
2236
|
-
return o;
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
|
-
@fragment fn fs(i: V) -> @location(0) vec4<f32> {
|
|
2240
|
-
let d = normalize(i.dir);
|
|
2241
|
-
let cx = u.cam.x;
|
|
2242
|
-
let cy = max(u.cam.y, 0.1); // clamp: camera always above ground
|
|
2243
|
-
let cz = u.cam.z;
|
|
2244
|
-
let captureH = u.cam.w;
|
|
2245
|
-
|
|
2246
|
-
// --- sky: sample HDR with original direction ---
|
|
2247
|
-
let skyUv = dirToUv(d);
|
|
2248
|
-
|
|
2249
|
-
// --- ground: camera-centered, height-independent projection ---
|
|
2250
|
-
let dyClamped = min(d.y, -0.0001);
|
|
2251
|
-
let ratio = d.x / dyClamped;
|
|
2252
|
-
let ratioZ = d.z / dyClamped;
|
|
2253
|
-
|
|
2254
|
-
// K = captureH controls ground spread (smaller = more horizon, larger = more nadir)
|
|
2255
|
-
let groundDir = normalize(vec3(-ratio, -captureH, -ratioZ));
|
|
2256
|
-
let groundUv = dirToUv(groundDir);
|
|
2257
|
-
|
|
2258
|
-
// --- sample both (uniform control flow) ---
|
|
2259
|
-
let skyColor = textureSample(envTexture, envSampler, skyUv).rgb;
|
|
2260
|
-
let groundColor = textureSample(envTexture, envSampler, groundUv).rgb;
|
|
2261
|
-
|
|
2262
|
-
// Sharp blend at horizon — cy is always > 0 so no aboveGround check needed
|
|
2263
|
-
let horizonBlend = smoothstep(0.002, -0.002, d.y);
|
|
2264
|
-
let c = mix(skyColor, groundColor, horizonBlend);
|
|
2265
|
-
|
|
2266
|
-
// Reinhard tone mapping + gamma
|
|
2267
|
-
let mapped = c / (c + vec3(1.));
|
|
2268
|
-
let gamma = pow(mapped, vec3(1./2.2));
|
|
2269
|
-
return vec4(gamma, 1.);
|
|
2117
|
+
let d = normalize(i.dir);
|
|
2118
|
+
return vec4(textureSample(cubeTexture, cubeSampler, vec3(-d.x, d.y, d.z)).rgb, 1.);
|
|
2270
2119
|
}`
|
|
2271
2120
|
);
|
|
2272
2121
|
class SkyboxRenderer {
|
|
@@ -2277,14 +2126,10 @@ class SkyboxRenderer {
|
|
|
2277
2126
|
__publicField(this, "uniformData", new Float32Array(16));
|
|
2278
2127
|
__publicField(this, "cubePipeline");
|
|
2279
2128
|
__publicField(this, "cubeBindGroupLayout");
|
|
2280
|
-
__publicField(this, "equirectPipeline");
|
|
2281
|
-
__publicField(this, "equirectBindGroupLayout");
|
|
2282
2129
|
__publicField(this, "texture", null);
|
|
2283
2130
|
__publicField(this, "bindGroup", null);
|
|
2284
2131
|
__publicField(this, "frameReady", false);
|
|
2285
|
-
__publicField(this, "
|
|
2286
|
-
/** Virtual HDR capture height (world units). Controls ground texture spread. */
|
|
2287
|
-
__publicField(this, "groundRadius", 50);
|
|
2132
|
+
__publicField(this, "active", false);
|
|
2288
2133
|
this.device = device;
|
|
2289
2134
|
const depthStencil = {
|
|
2290
2135
|
format: depthFormat,
|
|
@@ -2305,30 +2150,15 @@ class SkyboxRenderer {
|
|
|
2305
2150
|
primitive: { topology: "triangle-list", cullMode: "none" },
|
|
2306
2151
|
depthStencil
|
|
2307
2152
|
});
|
|
2308
|
-
this.equirectBindGroupLayout = device.createBindGroupLayout({
|
|
2309
|
-
entries: [
|
|
2310
|
-
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
2311
|
-
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
2312
|
-
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "2d" } }
|
|
2313
|
-
]
|
|
2314
|
-
});
|
|
2315
|
-
this.equirectPipeline = device.createRenderPipeline({
|
|
2316
|
-
layout: device.createPipelineLayout({ bindGroupLayouts: [this.equirectBindGroupLayout] }),
|
|
2317
|
-
vertex: { module: device.createShaderModule({ code: EQUIRECT_WGSL }), entryPoint: "vs" },
|
|
2318
|
-
fragment: { module: device.createShaderModule({ code: EQUIRECT_WGSL }), entryPoint: "fs", targets: [{ format }] },
|
|
2319
|
-
primitive: { topology: "triangle-list", cullMode: "none" },
|
|
2320
|
-
depthStencil
|
|
2321
|
-
});
|
|
2322
2153
|
this.uniformBuffer = device.createBuffer({
|
|
2323
2154
|
size: 64,
|
|
2324
2155
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
2325
2156
|
});
|
|
2326
|
-
this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear" });
|
|
2157
|
+
this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear", mipmapFilter: "linear" });
|
|
2327
2158
|
}
|
|
2328
2159
|
get isActive() {
|
|
2329
|
-
return this.
|
|
2160
|
+
return this.active && this.texture !== null && this.bindGroup !== null;
|
|
2330
2161
|
}
|
|
2331
|
-
// ---- cubemap ----
|
|
2332
2162
|
async loadCubemap(faceUrls) {
|
|
2333
2163
|
this.clear();
|
|
2334
2164
|
const bitmaps = await Promise.all(
|
|
@@ -2346,10 +2176,12 @@ class SkyboxRenderer {
|
|
|
2346
2176
|
throw new Error("SkyboxRenderer: all cubemap faces must share the same dimensions");
|
|
2347
2177
|
}
|
|
2348
2178
|
}
|
|
2179
|
+
const mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1;
|
|
2349
2180
|
const tex = this.device.createTexture({
|
|
2350
2181
|
dimension: "2d",
|
|
2351
2182
|
size: [width, height, 6],
|
|
2352
2183
|
format: "rgba8unorm",
|
|
2184
|
+
mipLevelCount,
|
|
2353
2185
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
|
|
2354
2186
|
});
|
|
2355
2187
|
for (let layer = 0; layer < 6; layer++) {
|
|
@@ -2360,6 +2192,7 @@ class SkyboxRenderer {
|
|
|
2360
2192
|
);
|
|
2361
2193
|
}
|
|
2362
2194
|
bitmaps.forEach((b) => b.close());
|
|
2195
|
+
this.generateMipmaps(tex, width, height, 6, mipLevelCount);
|
|
2363
2196
|
this.bindGroup = this.device.createBindGroup({
|
|
2364
2197
|
layout: this.cubeBindGroupLayout,
|
|
2365
2198
|
entries: [
|
|
@@ -2369,41 +2202,9 @@ class SkyboxRenderer {
|
|
|
2369
2202
|
]
|
|
2370
2203
|
});
|
|
2371
2204
|
this.texture = tex;
|
|
2372
|
-
this.
|
|
2373
|
-
}
|
|
2374
|
-
// ---- equirectangular HDR ----
|
|
2375
|
-
async loadEquirectangular(url) {
|
|
2376
|
-
this.clear();
|
|
2377
|
-
const hdr = await loadHdr(url);
|
|
2378
|
-
const pixelCount = hdr.width * hdr.height * 4;
|
|
2379
|
-
const f16 = new Uint16Array(pixelCount);
|
|
2380
|
-
for (let i = 0; i < pixelCount; i++) {
|
|
2381
|
-
f16[i] = float32ToFloat16(hdr.data[i]);
|
|
2382
|
-
}
|
|
2383
|
-
const tex = this.device.createTexture({
|
|
2384
|
-
size: [hdr.width, hdr.height],
|
|
2385
|
-
format: "rgba16float",
|
|
2386
|
-
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
2387
|
-
});
|
|
2388
|
-
this.device.queue.writeTexture(
|
|
2389
|
-
{ texture: tex },
|
|
2390
|
-
f16.buffer,
|
|
2391
|
-
{ bytesPerRow: hdr.width * 8, rowsPerImage: hdr.height },
|
|
2392
|
-
{ width: hdr.width, height: hdr.height }
|
|
2393
|
-
);
|
|
2394
|
-
this.bindGroup = this.device.createBindGroup({
|
|
2395
|
-
layout: this.equirectBindGroupLayout,
|
|
2396
|
-
entries: [
|
|
2397
|
-
{ binding: 0, resource: { buffer: this.uniformBuffer } },
|
|
2398
|
-
{ binding: 1, resource: this.sampler },
|
|
2399
|
-
{ binding: 2, resource: tex.createView() }
|
|
2400
|
-
]
|
|
2401
|
-
});
|
|
2402
|
-
this.texture = tex;
|
|
2403
|
-
this.mode = "equirect";
|
|
2205
|
+
this.active = true;
|
|
2404
2206
|
}
|
|
2405
|
-
|
|
2406
|
-
prepareFrame(viewMatrix, projectionMatrix, cameraPosition) {
|
|
2207
|
+
prepareFrame(viewMatrix, projectionMatrix) {
|
|
2407
2208
|
if (!this.isActive) {
|
|
2408
2209
|
this.frameReady = false;
|
|
2409
2210
|
return;
|
|
@@ -2421,20 +2222,89 @@ class SkyboxRenderer {
|
|
|
2421
2222
|
ud[9] = viewMatrix[9];
|
|
2422
2223
|
ud[10] = viewMatrix[10];
|
|
2423
2224
|
ud[11] = 0;
|
|
2424
|
-
ud[12] = cameraPosition ? cameraPosition[0] : 0;
|
|
2425
|
-
ud[13] = cameraPosition ? cameraPosition[1] : 0;
|
|
2426
|
-
ud[14] = cameraPosition ? cameraPosition[2] : 0;
|
|
2427
|
-
ud[15] = this.groundRadius;
|
|
2428
2225
|
this.device.queue.writeBuffer(this.uniformBuffer, 0, ud);
|
|
2429
2226
|
this.frameReady = true;
|
|
2430
2227
|
}
|
|
2431
2228
|
draw(pass) {
|
|
2432
2229
|
if (!this.frameReady || !this.bindGroup) return;
|
|
2433
|
-
|
|
2434
|
-
pass.setPipeline(pipeline);
|
|
2230
|
+
pass.setPipeline(this.cubePipeline);
|
|
2435
2231
|
pass.setBindGroup(0, this.bindGroup);
|
|
2436
2232
|
pass.draw(3);
|
|
2437
2233
|
}
|
|
2234
|
+
generateMipmaps(tex, baseWidth, baseHeight, layerCount, mipLevelCount) {
|
|
2235
|
+
if (mipLevelCount <= 1) return;
|
|
2236
|
+
const module2 = this.device.createShaderModule({
|
|
2237
|
+
code: (
|
|
2238
|
+
/* wgsl */
|
|
2239
|
+
`
|
|
2240
|
+
@group(0) @binding(0) var src: texture_2d<f32>;
|
|
2241
|
+
@group(0) @binding(1) var srcSampler: sampler;
|
|
2242
|
+
struct V { @builtin(position) pos: vec4<f32>, @location(0) uv: vec2<f32> };
|
|
2243
|
+
@vertex fn vs(@builtin(vertex_index) vi: u32) -> V {
|
|
2244
|
+
let ps = array<vec2<f32>,3>(vec2(0.,0.),vec2(2.,0.),vec2(0.,2.));
|
|
2245
|
+
var o: V; let p = ps[vi];
|
|
2246
|
+
o.pos = vec4(p * 2. - 1., 0., 1.);
|
|
2247
|
+
o.uv = vec2(p.x, 1. - p.y);
|
|
2248
|
+
return o;
|
|
2249
|
+
}
|
|
2250
|
+
@fragment fn fs(i: V) -> @location(0) vec4<f32> {
|
|
2251
|
+
return textureSample(src, srcSampler, i.uv);
|
|
2252
|
+
}`
|
|
2253
|
+
)
|
|
2254
|
+
});
|
|
2255
|
+
const bgl = this.device.createBindGroupLayout({
|
|
2256
|
+
entries: [
|
|
2257
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float" } },
|
|
2258
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } }
|
|
2259
|
+
]
|
|
2260
|
+
});
|
|
2261
|
+
const pipeline = this.device.createRenderPipeline({
|
|
2262
|
+
layout: this.device.createPipelineLayout({ bindGroupLayouts: [bgl] }),
|
|
2263
|
+
vertex: { module: module2, entryPoint: "vs" },
|
|
2264
|
+
fragment: { module: module2, entryPoint: "fs", targets: [{ format: "rgba8unorm" }] },
|
|
2265
|
+
primitive: { topology: "triangle-list" }
|
|
2266
|
+
});
|
|
2267
|
+
const linearSampler = this.device.createSampler({ magFilter: "linear", minFilter: "linear" });
|
|
2268
|
+
const encoder = this.device.createCommandEncoder();
|
|
2269
|
+
for (let level = 1; level < mipLevelCount; level++) {
|
|
2270
|
+
for (let layer = 0; layer < layerCount; layer++) {
|
|
2271
|
+
const srcView = tex.createView({
|
|
2272
|
+
dimension: "2d",
|
|
2273
|
+
baseMipLevel: level - 1,
|
|
2274
|
+
mipLevelCount: 1,
|
|
2275
|
+
baseArrayLayer: layer,
|
|
2276
|
+
arrayLayerCount: 1
|
|
2277
|
+
});
|
|
2278
|
+
const dstView = tex.createView({
|
|
2279
|
+
dimension: "2d",
|
|
2280
|
+
baseMipLevel: level,
|
|
2281
|
+
mipLevelCount: 1,
|
|
2282
|
+
baseArrayLayer: layer,
|
|
2283
|
+
arrayLayerCount: 1
|
|
2284
|
+
});
|
|
2285
|
+
const bg = this.device.createBindGroup({
|
|
2286
|
+
layout: bgl,
|
|
2287
|
+
entries: [
|
|
2288
|
+
{ binding: 0, resource: srcView },
|
|
2289
|
+
{ binding: 1, resource: linearSampler }
|
|
2290
|
+
]
|
|
2291
|
+
});
|
|
2292
|
+
const pass = encoder.beginRenderPass({
|
|
2293
|
+
colorAttachments: [{
|
|
2294
|
+
view: dstView,
|
|
2295
|
+
loadOp: "clear",
|
|
2296
|
+
storeOp: "store",
|
|
2297
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 }
|
|
2298
|
+
}]
|
|
2299
|
+
});
|
|
2300
|
+
pass.setPipeline(pipeline);
|
|
2301
|
+
pass.setBindGroup(0, bg);
|
|
2302
|
+
pass.draw(3);
|
|
2303
|
+
pass.end();
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
this.device.queue.submit([encoder.finish()]);
|
|
2307
|
+
}
|
|
2438
2308
|
clear() {
|
|
2439
2309
|
if (this.texture) {
|
|
2440
2310
|
this.texture.destroy();
|
|
@@ -2442,7 +2312,7 @@ class SkyboxRenderer {
|
|
|
2442
2312
|
}
|
|
2443
2313
|
this.bindGroup = null;
|
|
2444
2314
|
this.frameReady = false;
|
|
2445
|
-
this.
|
|
2315
|
+
this.active = false;
|
|
2446
2316
|
}
|
|
2447
2317
|
destroy() {
|
|
2448
2318
|
this.clear();
|
|
@@ -19061,36 +18931,9 @@ class App {
|
|
|
19061
18931
|
this.updateAdaptivePerformance();
|
|
19062
18932
|
this.hotspotManager.updateBillboards();
|
|
19063
18933
|
if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
|
|
19064
|
-
const cam = this.camera.position;
|
|
19065
|
-
let groundLevel = 0;
|
|
19066
|
-
const gsRendererForGround = this.sceneManager.getGSRenderer();
|
|
19067
|
-
const bbox = (gsRendererForGround == null ? void 0 : gsRendererForGround.getBoundingBox()) ?? null;
|
|
19068
|
-
if (bbox) {
|
|
19069
|
-
const m = gsRendererForGround.getModelMatrix();
|
|
19070
|
-
groundLevel = m[5] * bbox.min[1] + m[13];
|
|
19071
|
-
}
|
|
19072
|
-
if (!this._hdrDebugLogged) {
|
|
19073
|
-
this._hdrDebugLogged = true;
|
|
19074
|
-
console.log(
|
|
19075
|
-
"[HDR Ground Debug]",
|
|
19076
|
-
"hasGsRenderer:",
|
|
19077
|
-
!!gsRendererForGround,
|
|
19078
|
-
"hasBbox:",
|
|
19079
|
-
!!bbox,
|
|
19080
|
-
"bbox:",
|
|
19081
|
-
bbox ? { min: [...bbox.min], max: [...bbox.max], center: [...bbox.center] } : null,
|
|
19082
|
-
"groundLevel:",
|
|
19083
|
-
groundLevel,
|
|
19084
|
-
"cam:",
|
|
19085
|
-
[cam[0].toFixed(2), cam[1].toFixed(2), cam[2].toFixed(2)]
|
|
19086
|
-
);
|
|
19087
|
-
}
|
|
19088
|
-
const camH = cam[1] - groundLevel;
|
|
19089
|
-
this.skyboxRenderer.groundRadius = 0.3;
|
|
19090
18934
|
this.skyboxRenderer.prepareFrame(
|
|
19091
18935
|
this.camera.viewMatrix,
|
|
19092
|
-
this.camera.projectionMatrix
|
|
19093
|
-
[cam[0], camH, cam[2]]
|
|
18936
|
+
this.camera.projectionMatrix
|
|
19094
18937
|
);
|
|
19095
18938
|
}
|
|
19096
18939
|
const pass = this.renderer.beginFrame();
|
|
@@ -19275,21 +19118,6 @@ class App {
|
|
|
19275
19118
|
faceUrls.negZ
|
|
19276
19119
|
]);
|
|
19277
19120
|
}
|
|
19278
|
-
async setHdrBackground(url) {
|
|
19279
|
-
if (!this.skyboxRenderer) {
|
|
19280
|
-
this.skyboxRenderer = new SkyboxRenderer(
|
|
19281
|
-
this.renderer.device,
|
|
19282
|
-
this.renderer.format,
|
|
19283
|
-
"depth24plus"
|
|
19284
|
-
);
|
|
19285
|
-
}
|
|
19286
|
-
await this.skyboxRenderer.loadEquirectangular(url);
|
|
19287
|
-
}
|
|
19288
|
-
setHdrGroundRadius(radius) {
|
|
19289
|
-
if (this.skyboxRenderer) {
|
|
19290
|
-
this.skyboxRenderer.groundRadius = radius;
|
|
19291
|
-
}
|
|
19292
|
-
}
|
|
19293
19121
|
clearSkybox() {
|
|
19294
19122
|
var _a2;
|
|
19295
19123
|
(_a2 = this.skyboxRenderer) == null ? void 0 : _a2.clear();
|
|
@@ -19781,7 +19609,6 @@ exports.exportEditedPLY = exportEditedPLY;
|
|
|
19781
19609
|
exports.getRecommendedDPR = getRecommendedDPR;
|
|
19782
19610
|
exports.isMobileDevice = isMobileDevice;
|
|
19783
19611
|
exports.isWebGPUSupported = isWebGPUSupported;
|
|
19784
|
-
exports.loadHdr = loadHdr;
|
|
19785
19612
|
exports.loadPLY = loadPLY;
|
|
19786
19613
|
exports.loadPLYMobile = loadPLYMobile;
|
|
19787
19614
|
exports.loadSOG = loadSOG;
|