@d5techs/3dgs-lib 1.4.54 → 1.4.55
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 +62 -10
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +62 -10
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/App.d.ts +1 -0
- package/dist/core/SkyboxRenderer.d.ts +3 -1
- package/package.json +1 -1
package/dist/3dgs-lib.js
CHANGED
|
@@ -2196,7 +2196,7 @@ function float32ToFloat16(val) {
|
|
|
2196
2196
|
const CUBE_WGSL = (
|
|
2197
2197
|
/* wgsl */
|
|
2198
2198
|
`
|
|
2199
|
-
struct Uniforms { col0: vec4<f32>, col1: vec4<f32>, col2: vec4<f32> };
|
|
2199
|
+
struct Uniforms { col0: vec4<f32>, col1: vec4<f32>, col2: vec4<f32>, extra: vec4<f32> };
|
|
2200
2200
|
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
2201
2201
|
@group(0) @binding(1) var cubeSampler: sampler;
|
|
2202
2202
|
@group(0) @binding(2) var cubeTexture: texture_cube<f32>;
|
|
@@ -2215,12 +2215,17 @@ struct V { @builtin(position) pos: vec4<f32>, @location(0) dir: vec3<f32> };
|
|
|
2215
2215
|
const EQUIRECT_WGSL = (
|
|
2216
2216
|
/* wgsl */
|
|
2217
2217
|
`
|
|
2218
|
-
struct Uniforms { col0: vec4<f32>, col1: vec4<f32>, col2: vec4<f32> };
|
|
2218
|
+
struct Uniforms { col0: vec4<f32>, col1: vec4<f32>, col2: vec4<f32>, extra: vec4<f32> };
|
|
2219
2219
|
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
2220
2220
|
@group(0) @binding(1) var envSampler: sampler;
|
|
2221
2221
|
@group(0) @binding(2) var envTexture: texture_2d<f32>;
|
|
2222
2222
|
struct V { @builtin(position) pos: vec4<f32>, @location(0) dir: vec3<f32> };
|
|
2223
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
|
+
|
|
2224
2229
|
@vertex fn vs(@builtin(vertex_index) vi: u32) -> V {
|
|
2225
2230
|
let ps = array<vec2<f32>,3>(vec2(-1.,-1.),vec2(3.,-1.),vec2(-1.,3.));
|
|
2226
2231
|
var o: V; let p = ps[vi]; o.pos = vec4(p, 0., 1.);
|
|
@@ -2228,10 +2233,44 @@ const PI: f32 = 3.14159265358979;
|
|
|
2228
2233
|
o.dir = vec3(dot(u.col0.xyz,e), dot(u.col1.xyz,e), dot(u.col2.xyz,e));
|
|
2229
2234
|
return o;
|
|
2230
2235
|
}
|
|
2236
|
+
|
|
2231
2237
|
@fragment fn fs(i: V) -> @location(0) vec4<f32> {
|
|
2232
2238
|
let d = normalize(i.dir);
|
|
2233
|
-
let
|
|
2234
|
-
let
|
|
2239
|
+
let camY = u.extra.x;
|
|
2240
|
+
let sphereR = u.extra.y;
|
|
2241
|
+
|
|
2242
|
+
// --- sky UV (always computed) ---
|
|
2243
|
+
let skyUv = dirToUv(d);
|
|
2244
|
+
|
|
2245
|
+
// --- ground projection UV (always computed to satisfy uniform control flow) ---
|
|
2246
|
+
// ray-plane intersection: camera at height camY, plane y=0
|
|
2247
|
+
let dySafe = select(d.y, -0.0001, d.y > -0.0001);
|
|
2248
|
+
let t = -camY / dySafe;
|
|
2249
|
+
let hitX = t * d.x;
|
|
2250
|
+
let hitZ = t * d.z;
|
|
2251
|
+
let hitDist2 = hitX * hitX + hitZ * hitZ;
|
|
2252
|
+
let R2 = sphereR * sphereR;
|
|
2253
|
+
// clamp hit to sphere radius to avoid extreme stretching at edges
|
|
2254
|
+
let needClamp = hitDist2 > R2;
|
|
2255
|
+
let clampScale = select(1.0, sphereR / sqrt(max(hitDist2, 0.0001)), needClamp);
|
|
2256
|
+
let pX = hitX * clampScale;
|
|
2257
|
+
let pZ = hitZ * clampScale;
|
|
2258
|
+
// project back onto sphere: y = -sqrt(R^2 - x^2 - z^2)
|
|
2259
|
+
let projY = -sqrt(max(R2 - pX * pX - pZ * pZ, 0.0));
|
|
2260
|
+
let groundDir = normalize(vec3(pX, projY, pZ));
|
|
2261
|
+
let groundUv = dirToUv(groundDir);
|
|
2262
|
+
|
|
2263
|
+
// --- sample both (unconditional = uniform control flow) ---
|
|
2264
|
+
let skyColor = textureSample(envTexture, envSampler, skyUv).rgb;
|
|
2265
|
+
let groundColor = textureSample(envTexture, envSampler, groundUv).rgb;
|
|
2266
|
+
|
|
2267
|
+
// blend near horizon for smooth transition
|
|
2268
|
+
let blend = smoothstep(0.0, -0.08, d.y);
|
|
2269
|
+
let mixed = mix(skyColor, groundColor, blend);
|
|
2270
|
+
let useGround = d.y < 0.0 && camY > 0.01;
|
|
2271
|
+
let c = select(skyColor, mixed, useGround);
|
|
2272
|
+
|
|
2273
|
+
// Reinhard tone mapping + gamma
|
|
2235
2274
|
let mapped = c / (c + vec3(1.));
|
|
2236
2275
|
let gamma = pow(mapped, vec3(1./2.2));
|
|
2237
2276
|
return vec4(gamma, 1.);
|
|
@@ -2242,7 +2281,7 @@ class SkyboxRenderer {
|
|
|
2242
2281
|
__publicField(this, "device");
|
|
2243
2282
|
__publicField(this, "uniformBuffer");
|
|
2244
2283
|
__publicField(this, "sampler");
|
|
2245
|
-
__publicField(this, "uniformData", new Float32Array(
|
|
2284
|
+
__publicField(this, "uniformData", new Float32Array(16));
|
|
2246
2285
|
__publicField(this, "cubePipeline");
|
|
2247
2286
|
__publicField(this, "cubeBindGroupLayout");
|
|
2248
2287
|
__publicField(this, "equirectPipeline");
|
|
@@ -2251,6 +2290,8 @@ class SkyboxRenderer {
|
|
|
2251
2290
|
__publicField(this, "bindGroup", null);
|
|
2252
2291
|
__publicField(this, "frameReady", false);
|
|
2253
2292
|
__publicField(this, "mode", "none");
|
|
2293
|
+
/** Ground projection sphere radius (world units). Larger = ground extends further. */
|
|
2294
|
+
__publicField(this, "groundRadius", 32);
|
|
2254
2295
|
this.device = device;
|
|
2255
2296
|
const depthStencil = {
|
|
2256
2297
|
format: depthFormat,
|
|
@@ -2259,7 +2300,7 @@ class SkyboxRenderer {
|
|
|
2259
2300
|
};
|
|
2260
2301
|
this.cubeBindGroupLayout = device.createBindGroupLayout({
|
|
2261
2302
|
entries: [
|
|
2262
|
-
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } },
|
|
2303
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
2263
2304
|
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
2264
2305
|
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "cube" } }
|
|
2265
2306
|
]
|
|
@@ -2273,7 +2314,7 @@ class SkyboxRenderer {
|
|
|
2273
2314
|
});
|
|
2274
2315
|
this.equirectBindGroupLayout = device.createBindGroupLayout({
|
|
2275
2316
|
entries: [
|
|
2276
|
-
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } },
|
|
2317
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
2277
2318
|
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
2278
2319
|
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "2d" } }
|
|
2279
2320
|
]
|
|
@@ -2286,7 +2327,7 @@ class SkyboxRenderer {
|
|
|
2286
2327
|
depthStencil
|
|
2287
2328
|
});
|
|
2288
2329
|
this.uniformBuffer = device.createBuffer({
|
|
2289
|
-
size:
|
|
2330
|
+
size: 64,
|
|
2290
2331
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
2291
2332
|
});
|
|
2292
2333
|
this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear" });
|
|
@@ -2369,7 +2410,7 @@ class SkyboxRenderer {
|
|
|
2369
2410
|
this.mode = "equirect";
|
|
2370
2411
|
}
|
|
2371
2412
|
// ---- common ----
|
|
2372
|
-
prepareFrame(viewMatrix, projectionMatrix) {
|
|
2413
|
+
prepareFrame(viewMatrix, projectionMatrix, cameraPosition) {
|
|
2373
2414
|
if (!this.isActive) {
|
|
2374
2415
|
this.frameReady = false;
|
|
2375
2416
|
return;
|
|
@@ -2387,6 +2428,10 @@ class SkyboxRenderer {
|
|
|
2387
2428
|
ud[9] = viewMatrix[9];
|
|
2388
2429
|
ud[10] = viewMatrix[10];
|
|
2389
2430
|
ud[11] = 0;
|
|
2431
|
+
ud[12] = cameraPosition ? cameraPosition[1] : 0;
|
|
2432
|
+
ud[13] = this.groundRadius;
|
|
2433
|
+
ud[14] = 0;
|
|
2434
|
+
ud[15] = 0;
|
|
2390
2435
|
this.device.queue.writeBuffer(this.uniformBuffer, 0, ud);
|
|
2391
2436
|
this.frameReady = true;
|
|
2392
2437
|
}
|
|
@@ -19023,9 +19068,11 @@ class App {
|
|
|
19023
19068
|
this.updateAdaptivePerformance();
|
|
19024
19069
|
this.hotspotManager.updateBillboards();
|
|
19025
19070
|
if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
|
|
19071
|
+
const cam = this.camera.position;
|
|
19026
19072
|
this.skyboxRenderer.prepareFrame(
|
|
19027
19073
|
this.camera.viewMatrix,
|
|
19028
|
-
this.camera.projectionMatrix
|
|
19074
|
+
this.camera.projectionMatrix,
|
|
19075
|
+
[cam[0], cam[1], cam[2]]
|
|
19029
19076
|
);
|
|
19030
19077
|
}
|
|
19031
19078
|
const pass = this.renderer.beginFrame();
|
|
@@ -19220,6 +19267,11 @@ class App {
|
|
|
19220
19267
|
}
|
|
19221
19268
|
await this.skyboxRenderer.loadEquirectangular(url);
|
|
19222
19269
|
}
|
|
19270
|
+
setHdrGroundRadius(radius) {
|
|
19271
|
+
if (this.skyboxRenderer) {
|
|
19272
|
+
this.skyboxRenderer.groundRadius = radius;
|
|
19273
|
+
}
|
|
19274
|
+
}
|
|
19223
19275
|
clearSkybox() {
|
|
19224
19276
|
var _a2;
|
|
19225
19277
|
(_a2 = this.skyboxRenderer) == null ? void 0 : _a2.clear();
|