@d5techs/3dgs-lib 1.4.56 → 1.4.58

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
@@ -2236,40 +2236,36 @@ fn dirToUv(d: vec3<f32>) -> vec2<f32> {
2236
2236
 
2237
2237
  @fragment fn fs(i: V) -> @location(0) vec4<f32> {
2238
2238
  let d = normalize(i.dir);
2239
- let camY = u.extra.x;
2240
- let sphereR = u.extra.y;
2239
+ let camH = u.extra.x;
2240
+ let projR = u.extra.y;
2241
2241
 
2242
- // --- sky UV (always computed) ---
2242
+ // --- sky UV (always computed for uniform control flow) ---
2243
2243
  let skyUv = dirToUv(d);
2244
2244
 
2245
- // --- ground projection (always computed for uniform control flow) ---
2246
- // Ray from camera (0, camY, 0) in direction d hits plane y=0 at t
2245
+ // --- flat ground projection ---
2246
+ // Ray from camera at height camH above ground, direction d,
2247
+ // hits ground plane at t = -camH / d.y
2247
2248
  let dyClamped = min(d.y, -0.0001);
2248
- let t = -camY / dyClamped;
2249
+ let t = -camH / dyClamped;
2249
2250
  let hitX = t * d.x;
2250
2251
  let hitZ = t * d.z;
2251
2252
  let hitDist = sqrt(hitX * hitX + hitZ * hitZ);
2252
2253
 
2253
- // Project the ground hit point back onto a sphere of radius R
2254
- // centered at the camera projection on y=0 (i.e. center = origin).
2255
- // For points beyond R, fade to horizon sampling.
2256
- let ratio = min(hitDist, sphereR) / max(hitDist, 0.001);
2257
- let pX = hitX * ratio;
2258
- let pZ = hitZ * ratio;
2259
- let pY = -sqrt(max(sphereR * sphereR - pX * pX - pZ * pZ, 0.0));
2260
- let groundDir = normalize(vec3(pX, pY, pZ));
2254
+ // Reconstruct a sampling direction as if looking from HDR capture
2255
+ // height (1.7m) straight down at the hit point FLAT ground
2256
+ let captureH = 1.7;
2257
+ let groundDir = normalize(vec3(hitX, -captureH, hitZ));
2261
2258
  let groundUv = dirToUv(groundDir);
2262
2259
 
2263
- // --- sample both (unconditional = uniform control flow) ---
2260
+ // --- sample both unconditionally (uniform control flow) ---
2264
2261
  let skyColor = textureSample(envTexture, envSampler, skyUv).rgb;
2265
2262
  let groundColor = textureSample(envTexture, envSampler, groundUv).rgb;
2266
2263
 
2267
2264
  // Blend: smooth transition near horizon
2268
- // step(0.01, camY) disables ground projection when camera is at/below ground
2269
- let groundFactor = smoothstep(0.01, -0.15, d.y) * step(0.01, camY);
2270
- // Fade out ground color at the sphere edge to avoid hard seam
2271
- let edgeFade = 1.0 - smoothstep(sphereR * 0.7, sphereR * 0.99, hitDist);
2272
- let finalBlend = groundFactor * edgeFade;
2265
+ let horizonBlend = smoothstep(0.0, -0.12, d.y);
2266
+ let aboveGround = step(0.01, camH);
2267
+ let edgeFade = 1.0 - smoothstep(projR * 0.6, projR, hitDist);
2268
+ let finalBlend = horizonBlend * aboveGround * edgeFade;
2273
2269
  let c = mix(skyColor, groundColor, finalBlend);
2274
2270
 
2275
2271
  // Reinhard tone mapping + gamma
@@ -2412,7 +2408,7 @@ class SkyboxRenderer {
2412
2408
  this.mode = "equirect";
2413
2409
  }
2414
2410
  // ---- common ----
2415
- prepareFrame(viewMatrix, projectionMatrix, cameraPosition) {
2411
+ prepareFrame(viewMatrix, projectionMatrix, cameraPosition, groundY) {
2416
2412
  if (!this.isActive) {
2417
2413
  this.frameReady = false;
2418
2414
  return;
@@ -2430,7 +2426,9 @@ class SkyboxRenderer {
2430
2426
  ud[9] = viewMatrix[9];
2431
2427
  ud[10] = viewMatrix[10];
2432
2428
  ud[11] = 0;
2433
- ud[12] = cameraPosition ? cameraPosition[1] : 0;
2429
+ const camWorldY = cameraPosition ? cameraPosition[1] : 0;
2430
+ const gndY = groundY ?? 0;
2431
+ ud[12] = camWorldY - gndY;
2434
2432
  ud[13] = this.groundRadius;
2435
2433
  ud[14] = 0;
2436
2434
  ud[15] = 0;
@@ -19071,10 +19069,20 @@ class App {
19071
19069
  this.hotspotManager.updateBillboards();
19072
19070
  if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
19073
19071
  const cam = this.camera.position;
19072
+ let groundY = 0;
19073
+ const gsRenderer2 = this.sceneManager.getGSRenderer();
19074
+ if (gsRenderer2) {
19075
+ const bbox = gsRenderer2.getBoundingBox();
19076
+ if (bbox) {
19077
+ const m = gsRenderer2.getModelMatrix();
19078
+ groundY = m[5] * bbox.min[1] + m[13];
19079
+ }
19080
+ }
19074
19081
  this.skyboxRenderer.prepareFrame(
19075
19082
  this.camera.viewMatrix,
19076
19083
  this.camera.projectionMatrix,
19077
- [cam[0], cam[1], cam[2]]
19084
+ [cam[0], cam[1], cam[2]],
19085
+ groundY
19078
19086
  );
19079
19087
  }
19080
19088
  const pass = this.renderer.beginFrame();