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