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