@d5techs/3dgs-lib 1.4.49 → 1.4.51

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 CHANGED
@@ -2117,12 +2117,6 @@ struct VSOut {
2117
2117
  @location(0) dir: vec3<f32>,
2118
2118
  };
2119
2119
 
2120
- fn rotateX(d: vec3<f32>, angle: f32) -> vec3<f32> {
2121
- let c = cos(angle);
2122
- let s = sin(angle);
2123
- return vec3<f32>(d.x, c * d.y - s * d.z, s * d.y + c * d.z);
2124
- }
2125
-
2126
2120
  @vertex
2127
2121
  fn vs(@builtin(vertex_index) vi: u32) -> VSOut {
2128
2122
  let positions = array<vec2<f32>, 3>(
@@ -2136,22 +2130,38 @@ fn vs(@builtin(vertex_index) vi: u32) -> VSOut {
2136
2130
 
2137
2131
  let eyeDir = vec3<f32>(p.x * u.col0.w, p.y * u.col1.w, -1.0);
2138
2132
 
2139
- var worldDir = vec3<f32>(
2133
+ out.dir = vec3<f32>(
2140
2134
  dot(u.col0.xyz, eyeDir),
2141
2135
  dot(u.col1.xyz, eyeDir),
2142
2136
  dot(u.col2.xyz, eyeDir),
2143
2137
  );
2144
-
2145
- worldDir = rotateX(worldDir, u.extra.x);
2146
-
2147
- out.dir = worldDir;
2148
2138
  return out;
2149
2139
  }
2150
2140
 
2151
2141
  @fragment
2152
2142
  fn fs(input: VSOut) -> @location(0) vec4<f32> {
2153
- let color = textureSample(cubeTexture, cubeSampler, normalize(input.dir));
2154
- return vec4<f32>(color.rgb, 1.0);
2143
+ let dir = normalize(input.dir);
2144
+
2145
+ let camX = u.extra.y;
2146
+ let camY = u.extra.z;
2147
+ let camZ = u.extra.w;
2148
+
2149
+ let doGround = u.extra.x > 0.5 && dir.y < -0.001 && camY > 0.01;
2150
+ let safeDirY = select(dir.y, -0.01, dir.y > -0.001);
2151
+ let t = camY / (-safeDirY);
2152
+ let gx = camX + dir.x * t;
2153
+ let gz = camZ + dir.z * t;
2154
+ let scale = max(camY, 1.0) * 5.0;
2155
+ let groundDir = normalize(vec3<f32>(gx / max(scale, 0.01), -1.0, gz / max(scale, 0.01)));
2156
+
2157
+ let skyColor = textureSample(cubeTexture, cubeSampler, dir);
2158
+ let groundColor = textureSample(cubeTexture, cubeSampler, groundDir);
2159
+
2160
+ let blend = smoothstep(0.0, -0.12, dir.y);
2161
+ let mixed = mix(skyColor.rgb, groundColor.rgb, blend);
2162
+
2163
+ let final_color = select(skyColor.rgb, mixed, doGround);
2164
+ return vec4<f32>(final_color, 1.0);
2155
2165
  }
2156
2166
  `
2157
2167
  );
@@ -2173,7 +2183,7 @@ class SkyboxRenderer {
2173
2183
  entries: [
2174
2184
  {
2175
2185
  binding: 0,
2176
- visibility: GPUShaderStage.VERTEX,
2186
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
2177
2187
  buffer: { type: "uniform" }
2178
2188
  },
2179
2189
  {
@@ -2263,12 +2273,7 @@ class SkyboxRenderer {
2263
2273
  });
2264
2274
  this.cubeTexture = tex;
2265
2275
  }
2266
- /**
2267
- * Write uniforms BEFORE beginFrame().
2268
- * pitchOffset: radians to rotate sampling direction around world X axis,
2269
- * used to align skybox horizon with model ground plane.
2270
- */
2271
- prepareFrame(viewMatrix, projectionMatrix, pitchOffset = 0) {
2276
+ prepareFrame(viewMatrix, projectionMatrix, cameraPosition) {
2272
2277
  if (!this.isActive) {
2273
2278
  this.frameReady = false;
2274
2279
  return;
@@ -2286,10 +2291,17 @@ class SkyboxRenderer {
2286
2291
  ud[9] = viewMatrix[9];
2287
2292
  ud[10] = viewMatrix[10];
2288
2293
  ud[11] = 0;
2289
- ud[12] = pitchOffset;
2290
- ud[13] = 0;
2291
- ud[14] = 0;
2292
- ud[15] = 0;
2294
+ if (this.alignToGround && cameraPosition) {
2295
+ ud[12] = 1;
2296
+ ud[13] = cameraPosition[0];
2297
+ ud[14] = cameraPosition[1];
2298
+ ud[15] = cameraPosition[2];
2299
+ } else {
2300
+ ud[12] = 0;
2301
+ ud[13] = 0;
2302
+ ud[14] = 0;
2303
+ ud[15] = 0;
2304
+ }
2293
2305
  this.device.queue.writeBuffer(this.uniformBuffer, 0, ud);
2294
2306
  this.frameReady = true;
2295
2307
  }
@@ -18924,23 +18936,11 @@ class App {
18924
18936
  this.updateAdaptivePerformance();
18925
18937
  this.hotspotManager.updateBillboards();
18926
18938
  if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
18927
- let pitchOffset = 0;
18928
- if (this.skyboxRenderer.alignToGround) {
18929
- const cam = this.camera.position;
18930
- const mc = this.controls.modelCenter;
18931
- const mr = this.controls.modelRadius;
18932
- if (mr !== Infinity) {
18933
- const dx = cam[0] - mc[0];
18934
- const dz = cam[2] - mc[2];
18935
- const hDist = Math.sqrt(dx * dx + dz * dz);
18936
- const fullAngle = Math.atan2(cam[1], Math.max(hDist, 0.01));
18937
- pitchOffset = Math.max(-0.15, Math.min(0.15, -fullAngle * 0.1));
18938
- }
18939
- }
18939
+ const cam = this.camera.position;
18940
18940
  this.skyboxRenderer.prepareFrame(
18941
18941
  this.camera.viewMatrix,
18942
18942
  this.camera.projectionMatrix,
18943
- pitchOffset
18943
+ [cam[0], cam[1], cam[2]]
18944
18944
  );
18945
18945
  }
18946
18946
  const pass = this.renderer.beginFrame();