@d5techs/3dgs-lib 1.4.54 → 1.4.56
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 +64 -10
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +64 -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,46 @@ 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 (always computed for uniform control flow) ---
|
|
2246
|
+
// Ray from camera (0, camY, 0) in direction d hits plane y=0 at t
|
|
2247
|
+
let dyClamped = min(d.y, -0.0001);
|
|
2248
|
+
let t = -camY / dyClamped;
|
|
2249
|
+
let hitX = t * d.x;
|
|
2250
|
+
let hitZ = t * d.z;
|
|
2251
|
+
let hitDist = sqrt(hitX * hitX + hitZ * hitZ);
|
|
2252
|
+
|
|
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));
|
|
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: 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;
|
|
2273
|
+
let c = mix(skyColor, groundColor, finalBlend);
|
|
2274
|
+
|
|
2275
|
+
// Reinhard tone mapping + gamma
|
|
2235
2276
|
let mapped = c / (c + vec3(1.));
|
|
2236
2277
|
let gamma = pow(mapped, vec3(1./2.2));
|
|
2237
2278
|
return vec4(gamma, 1.);
|
|
@@ -2242,7 +2283,7 @@ class SkyboxRenderer {
|
|
|
2242
2283
|
__publicField(this, "device");
|
|
2243
2284
|
__publicField(this, "uniformBuffer");
|
|
2244
2285
|
__publicField(this, "sampler");
|
|
2245
|
-
__publicField(this, "uniformData", new Float32Array(
|
|
2286
|
+
__publicField(this, "uniformData", new Float32Array(16));
|
|
2246
2287
|
__publicField(this, "cubePipeline");
|
|
2247
2288
|
__publicField(this, "cubeBindGroupLayout");
|
|
2248
2289
|
__publicField(this, "equirectPipeline");
|
|
@@ -2251,6 +2292,8 @@ class SkyboxRenderer {
|
|
|
2251
2292
|
__publicField(this, "bindGroup", null);
|
|
2252
2293
|
__publicField(this, "frameReady", false);
|
|
2253
2294
|
__publicField(this, "mode", "none");
|
|
2295
|
+
/** Ground projection sphere radius (world units). Larger = ground extends further, flatter. */
|
|
2296
|
+
__publicField(this, "groundRadius", 500);
|
|
2254
2297
|
this.device = device;
|
|
2255
2298
|
const depthStencil = {
|
|
2256
2299
|
format: depthFormat,
|
|
@@ -2259,7 +2302,7 @@ class SkyboxRenderer {
|
|
|
2259
2302
|
};
|
|
2260
2303
|
this.cubeBindGroupLayout = device.createBindGroupLayout({
|
|
2261
2304
|
entries: [
|
|
2262
|
-
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } },
|
|
2305
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
2263
2306
|
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
2264
2307
|
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "cube" } }
|
|
2265
2308
|
]
|
|
@@ -2273,7 +2316,7 @@ class SkyboxRenderer {
|
|
|
2273
2316
|
});
|
|
2274
2317
|
this.equirectBindGroupLayout = device.createBindGroupLayout({
|
|
2275
2318
|
entries: [
|
|
2276
|
-
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } },
|
|
2319
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
2277
2320
|
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
|
|
2278
2321
|
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "2d" } }
|
|
2279
2322
|
]
|
|
@@ -2286,7 +2329,7 @@ class SkyboxRenderer {
|
|
|
2286
2329
|
depthStencil
|
|
2287
2330
|
});
|
|
2288
2331
|
this.uniformBuffer = device.createBuffer({
|
|
2289
|
-
size:
|
|
2332
|
+
size: 64,
|
|
2290
2333
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
2291
2334
|
});
|
|
2292
2335
|
this.sampler = device.createSampler({ magFilter: "linear", minFilter: "linear" });
|
|
@@ -2369,7 +2412,7 @@ class SkyboxRenderer {
|
|
|
2369
2412
|
this.mode = "equirect";
|
|
2370
2413
|
}
|
|
2371
2414
|
// ---- common ----
|
|
2372
|
-
prepareFrame(viewMatrix, projectionMatrix) {
|
|
2415
|
+
prepareFrame(viewMatrix, projectionMatrix, cameraPosition) {
|
|
2373
2416
|
if (!this.isActive) {
|
|
2374
2417
|
this.frameReady = false;
|
|
2375
2418
|
return;
|
|
@@ -2387,6 +2430,10 @@ class SkyboxRenderer {
|
|
|
2387
2430
|
ud[9] = viewMatrix[9];
|
|
2388
2431
|
ud[10] = viewMatrix[10];
|
|
2389
2432
|
ud[11] = 0;
|
|
2433
|
+
ud[12] = cameraPosition ? cameraPosition[1] : 0;
|
|
2434
|
+
ud[13] = this.groundRadius;
|
|
2435
|
+
ud[14] = 0;
|
|
2436
|
+
ud[15] = 0;
|
|
2390
2437
|
this.device.queue.writeBuffer(this.uniformBuffer, 0, ud);
|
|
2391
2438
|
this.frameReady = true;
|
|
2392
2439
|
}
|
|
@@ -19023,9 +19070,11 @@ class App {
|
|
|
19023
19070
|
this.updateAdaptivePerformance();
|
|
19024
19071
|
this.hotspotManager.updateBillboards();
|
|
19025
19072
|
if ((_a2 = this.skyboxRenderer) == null ? void 0 : _a2.isActive) {
|
|
19073
|
+
const cam = this.camera.position;
|
|
19026
19074
|
this.skyboxRenderer.prepareFrame(
|
|
19027
19075
|
this.camera.viewMatrix,
|
|
19028
|
-
this.camera.projectionMatrix
|
|
19076
|
+
this.camera.projectionMatrix,
|
|
19077
|
+
[cam[0], cam[1], cam[2]]
|
|
19029
19078
|
);
|
|
19030
19079
|
}
|
|
19031
19080
|
const pass = this.renderer.beginFrame();
|
|
@@ -19220,6 +19269,11 @@ class App {
|
|
|
19220
19269
|
}
|
|
19221
19270
|
await this.skyboxRenderer.loadEquirectangular(url);
|
|
19222
19271
|
}
|
|
19272
|
+
setHdrGroundRadius(radius) {
|
|
19273
|
+
if (this.skyboxRenderer) {
|
|
19274
|
+
this.skyboxRenderer.groundRadius = radius;
|
|
19275
|
+
}
|
|
19276
|
+
}
|
|
19223
19277
|
clearSkybox() {
|
|
19224
19278
|
var _a2;
|
|
19225
19279
|
(_a2 = this.skyboxRenderer) == null ? void 0 : _a2.clear();
|