s3m-three 0.4.16 → 0.4.17
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/browser/s3m-three.iife.ext-three.js +33 -15
- package/dist/browser/s3m-three.iife.js +33 -15
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/render/S3MViewer.d.ts +18 -8
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +88 -38
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/StyleMaterial.d.ts +6 -4
- package/dist/render/StyleMaterial.d.ts.map +1 -1
- package/dist/render/StyleMaterial.js +48 -3
- package/dist/render/StyleMaterial.js.map +1 -1
- package/dist/tileset/S3MTileset.d.ts.map +1 -1
- package/dist/tileset/S3MTileset.js +15 -1
- package/dist/tileset/S3MTileset.js.map +1 -1
- package/docs/API.md +40 -22
- package/package.json +1 -1
- package/src/core/types.ts +8 -0
- package/src/render/S3MViewer.ts +90 -35
- package/src/render/StyleMaterial.ts +59 -3
- package/src/tileset/S3MTileset.ts +15 -1
package/src/render/S3MViewer.ts
CHANGED
|
@@ -24,7 +24,7 @@ import * as THREE from 'three';
|
|
|
24
24
|
import { S3MTileset, usableGeoBounds } from '../tileset/S3MTileset.js';
|
|
25
25
|
import type { BuildTileFn, TileNode } from '../tileset/S3MTileset.js';
|
|
26
26
|
import { setMaxAnisotropy, setCompressedTexturesSupported, setTextureOffThreadDecode, setMaxTextureSize as setTextureSizeCap } from './TextureFactory.js';
|
|
27
|
-
import { setMaterialQuality } from './StyleMaterial.js';
|
|
27
|
+
import { getMaterialQuality, setMaterialQuality } from './StyleMaterial.js';
|
|
28
28
|
import { decodeTextureWithWorker } from '../worker/S3MWorkerClient.js';
|
|
29
29
|
import {
|
|
30
30
|
STYLE,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
SELECT_MODE,
|
|
33
33
|
DEFAULT_STYLE,
|
|
34
34
|
createSharedUniforms,
|
|
35
|
+
createStyledMaterial,
|
|
35
36
|
createOutlineMaterial,
|
|
36
37
|
resolveEdgeModes,
|
|
37
38
|
sameEdgeModes,
|
|
@@ -40,11 +41,13 @@ import type {
|
|
|
40
41
|
OutlineMaterial,
|
|
41
42
|
OutlineStyleUniforms,
|
|
42
43
|
StyledMaterial,
|
|
44
|
+
StyledMaterialOptions,
|
|
43
45
|
StyleMode,
|
|
44
46
|
SelectMode,
|
|
45
47
|
S3MStyle,
|
|
46
48
|
EdgeModes,
|
|
47
49
|
EdgesOption,
|
|
50
|
+
MaterialQuality,
|
|
48
51
|
} from './StyleMaterial.js';
|
|
49
52
|
import { applyPointCloudStyle, isOwnedPointCloudMaterial } from './PointCloudMaterial.js';
|
|
50
53
|
import { Picker } from './Picker.js';
|
|
@@ -1864,8 +1867,11 @@ export class S3MViewer {
|
|
|
1864
1867
|
mat.transparent = o < 0.999;
|
|
1865
1868
|
const keepDepth = this.style.depthWrite !== false;
|
|
1866
1869
|
mat.depthWrite = mat.transparent ? keepDepth : (this.style.depthWrite !== false);
|
|
1867
|
-
mat.flatShading
|
|
1868
|
-
|
|
1870
|
+
// shading 走共享 uniform(uFlatShading),不写 mat.flatShading / needsUpdate——
|
|
1871
|
+
// transparent / depthWrite 也不是 program 决定项,整套样式继承零重编译
|
|
1872
|
+
if (mat.userData.uFlatShading) {
|
|
1873
|
+
mat.userData.uFlatShading.value = this.style.shading !== 'smooth' ? 1 : 0;
|
|
1874
|
+
}
|
|
1869
1875
|
this._featureStyleManager.applyOverridesToMesh(mesh);
|
|
1870
1876
|
this._startTileFade(mesh, mat);
|
|
1871
1877
|
}
|
|
@@ -2369,26 +2375,74 @@ export class S3MViewer {
|
|
|
2369
2375
|
|
|
2370
2376
|
/** 平面/平滑着色:FLAT_SHADED 是编译期宏,改它必须重编译 */
|
|
2371
2377
|
private _applyShading(): void {
|
|
2372
|
-
|
|
2378
|
+
// shading 现在是共享 uniform(uFlatShading)驱动的运行期分支,不再是
|
|
2379
|
+
// flatShading define:翻一个 float 就完成切换,零重编译、零卡顿。
|
|
2380
|
+
const target = this.style.shading !== 'smooth' ? 1 : 0;
|
|
2373
2381
|
for (const p of this._pickables.values()) {
|
|
2374
2382
|
const m = styledMaterialOf(p.mesh);
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2383
|
+
const u = m?.userData.uFlatShading;
|
|
2384
|
+
if (!u || u.value === target) continue;
|
|
2385
|
+
u.value = target;
|
|
2378
2386
|
}
|
|
2379
2387
|
this._requestRepaint();
|
|
2380
2388
|
}
|
|
2381
2389
|
|
|
2382
2390
|
/**
|
|
2383
|
-
*
|
|
2391
|
+
* 运行时切换材质质感(`'pbr'` | `'lambert'`)。
|
|
2384
2392
|
*
|
|
2385
|
-
*
|
|
2386
|
-
*
|
|
2387
|
-
*
|
|
2393
|
+
* 档位是模块级设置(影响之后新建的材质);已加载瓦片的材质在这里**原位重建**:
|
|
2394
|
+
* 不重拉瓦片、不重建几何,按创建时记录的参数(`userData.s3mOpts`)换一个
|
|
2395
|
+
* 新材质实例,并保留逐材质状态(选中编号、瓦片淡入、批量状态纹理)。
|
|
2396
|
+
* 切换后 program 需要重新编译一次(lambert / pbr 是不同着色器),这是唯一开销。
|
|
2397
|
+
*/
|
|
2398
|
+
setMaterialQuality(q: MaterialQuality): void {
|
|
2399
|
+
setMaterialQuality(q);
|
|
2400
|
+
this._rebuildStyledMaterials();
|
|
2401
|
+
this._requestRepaint();
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
/** 当前材质质感档位 */
|
|
2405
|
+
get materialQuality(): MaterialQuality {
|
|
2406
|
+
return getMaterialQuality();
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
/** 按创建参数原位重建所有 styled 材质(materialQuality 切换用) */
|
|
2410
|
+
private _rebuildStyledMaterials(): void {
|
|
2411
|
+
// 逐材质 own uniform 的状态要在重建时搬过去,否则选中高亮 / 瓦片淡入会闪没
|
|
2412
|
+
const PRESERVED = [
|
|
2413
|
+
'uSelBatch',
|
|
2414
|
+
'uSelWhole',
|
|
2415
|
+
'uBatchTex',
|
|
2416
|
+
'uBatchTex2',
|
|
2417
|
+
'uBatchTexWidth',
|
|
2418
|
+
'uBatchTexActive',
|
|
2419
|
+
'uTileFade',
|
|
2420
|
+
] as const;
|
|
2421
|
+
for (const p of this._pickables.values()) {
|
|
2422
|
+
const mesh = p.mesh;
|
|
2423
|
+
const raw = mesh.material;
|
|
2424
|
+
if (Array.isArray(raw)) continue; // styled 材质恒为单材质;数组材质(点云等)不归这里管
|
|
2425
|
+
const old = raw as StyledMaterial | undefined;
|
|
2426
|
+
if (!old?.userData?.isStyled || !old.userData?.s3mOpts) continue;
|
|
2427
|
+
const opts = old.userData.s3mOpts as StyledMaterialOptions;
|
|
2428
|
+
const fresh = createStyledMaterial({ ...opts, uniforms: this.uniforms });
|
|
2429
|
+
for (const key of PRESERVED) {
|
|
2430
|
+
const src = old.userData[key] as { value: unknown } | undefined;
|
|
2431
|
+
const dst = fresh.userData[key] as { value: unknown } | undefined;
|
|
2432
|
+
if (src && dst) dst.value = src.value;
|
|
2433
|
+
}
|
|
2434
|
+
mesh.material = fresh;
|
|
2435
|
+
old.dispose();
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
/**
|
|
2440
|
+
* 预热着色 program,避免首帧同步编译。
|
|
2388
2441
|
*
|
|
2389
|
-
*
|
|
2390
|
-
*
|
|
2391
|
-
*
|
|
2442
|
+
* shading 改为 `uFlatShading` 共享 uniform 驱动后(见 `_applyShading`),
|
|
2443
|
+
* flat / smooth 共用同一个 program,不再存在「另一种变体」,也不需要
|
|
2444
|
+
* 「翻变体 → 编译 → 翻回来」的那套流程与 `_prewarming` 跳帧。这里只把当前
|
|
2445
|
+
* 唯一的 program 编一次(优先 `compileAsync`,KHR_parallel_shader_compile)。
|
|
2392
2446
|
*/
|
|
2393
2447
|
async prewarmShading(): Promise<void> {
|
|
2394
2448
|
if (this._shadingPrewarmed || this._prewarming) return;
|
|
@@ -2397,23 +2451,17 @@ export class S3MViewer {
|
|
|
2397
2451
|
const camera = this.camera;
|
|
2398
2452
|
if (!r || !scene || !camera) return;
|
|
2399
2453
|
|
|
2400
|
-
|
|
2401
|
-
|
|
2454
|
+
// 场上还没有材质就没必要预热:program 会在首个材质出现时编译
|
|
2455
|
+
let hasMaterial = false;
|
|
2402
2456
|
for (const p of this._pickables.values()) {
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2457
|
+
if (styledMaterialOf(p.mesh)) {
|
|
2458
|
+
hasMaterial = true;
|
|
2459
|
+
break;
|
|
2460
|
+
}
|
|
2407
2461
|
}
|
|
2408
|
-
if (
|
|
2462
|
+
if (!hasMaterial) return;
|
|
2409
2463
|
|
|
2410
2464
|
this._shadingPrewarmed = true;
|
|
2411
|
-
this._prewarming = true;
|
|
2412
|
-
// 当前是 smooth(flatShading = false)就预热 flat,反之预热 smooth
|
|
2413
|
-
const target = this.style.shading === 'smooth';
|
|
2414
|
-
const saved = mats.map((m) => m.flatShading);
|
|
2415
|
-
for (const m of mats) m.flatShading = target;
|
|
2416
|
-
|
|
2417
2465
|
try {
|
|
2418
2466
|
const anyR = r as unknown as {
|
|
2419
2467
|
compileAsync?: (s: THREE.Object3D, c: THREE.Camera) => Promise<unknown>;
|
|
@@ -2421,15 +2469,9 @@ export class S3MViewer {
|
|
|
2421
2469
|
if (typeof anyR.compileAsync === 'function') await anyR.compileAsync(scene, camera);
|
|
2422
2470
|
else r.compile(scene, camera);
|
|
2423
2471
|
} catch {
|
|
2424
|
-
//
|
|
2425
|
-
} finally {
|
|
2426
|
-
for (let i = 0; i < mats.length; i++) {
|
|
2427
|
-
mats[i].flatShading = saved[i];
|
|
2428
|
-
mats[i].needsUpdate = true;
|
|
2429
|
-
}
|
|
2430
|
-
this._prewarming = false;
|
|
2431
|
-
this._requestRepaint();
|
|
2472
|
+
// 预热失败不影响主流程:最坏情况退回「首次渲染时编译一次」
|
|
2432
2473
|
}
|
|
2474
|
+
this._requestRepaint();
|
|
2433
2475
|
}
|
|
2434
2476
|
|
|
2435
2477
|
/**
|
|
@@ -3989,6 +4031,10 @@ export class S3MViewer {
|
|
|
3989
4031
|
vertices: 0,
|
|
3990
4032
|
triangles: 0,
|
|
3991
4033
|
datasets: this.datasets.size,
|
|
4034
|
+
drawCalls: 0,
|
|
4035
|
+
programs: 0,
|
|
4036
|
+
textures: 0,
|
|
4037
|
+
geometries: 0,
|
|
3992
4038
|
};
|
|
3993
4039
|
for (const entry of this.datasets.values()) {
|
|
3994
4040
|
const s = entry.tileset?.stats;
|
|
@@ -4000,6 +4046,15 @@ export class S3MViewer {
|
|
|
4000
4046
|
total.vertices += s.vertices;
|
|
4001
4047
|
total.triangles += s.triangles;
|
|
4002
4048
|
}
|
|
4049
|
+
// GPU 侧预算观测:draw call / program / 显存驻留。没有渲染器(未 mount /
|
|
4050
|
+
// 纯解析场景)时保持 0,不抛错。
|
|
4051
|
+
const info = this.renderer?.info;
|
|
4052
|
+
if (info) {
|
|
4053
|
+
total.drawCalls = info.render.calls;
|
|
4054
|
+
total.programs = info.programs?.length ?? 0;
|
|
4055
|
+
total.textures = info.memory.textures;
|
|
4056
|
+
total.geometries = info.memory.geometries;
|
|
4057
|
+
}
|
|
4003
4058
|
return total;
|
|
4004
4059
|
}
|
|
4005
4060
|
|
|
@@ -375,6 +375,12 @@ export function createSharedUniforms(): StyleUniforms {
|
|
|
375
375
|
* (压暗 → 换模式 → 亮回来),比硬切自然得多。
|
|
376
376
|
*/
|
|
377
377
|
uFade: { value: 1 },
|
|
378
|
+
/**
|
|
379
|
+
* 平面 / 平滑着色开关:0 = 平滑(插值法线),1 = 平面(屏幕导数法线)。
|
|
380
|
+
* 走 uniform 而不是 three 的 `flatShading` define,所以切换 shading 不会触发
|
|
381
|
+
* 着色器重编译(旧实现靠 prewarm 把卡顿藏起来,现在连卡顿都没有)。
|
|
382
|
+
*/
|
|
383
|
+
uFlatShading: { value: 1 },
|
|
378
384
|
};
|
|
379
385
|
}
|
|
380
386
|
const VERT_PARS = /* glsl */ `
|
|
@@ -411,6 +417,8 @@ const VERT_PARS = /* glsl */ `
|
|
|
411
417
|
varying float vWorldZ;
|
|
412
418
|
varying vec3 vWorldNormal;
|
|
413
419
|
varying vec3 vWorldPos;
|
|
420
|
+
// 视图空间位置:平面着色用它算屏幕导数法线,符号与 three 的 vViewPosition 一致
|
|
421
|
+
varying vec3 vS3MViewPos;
|
|
414
422
|
|
|
415
423
|
// 跨 chunk 共享的顶点姿态变量(在 beginnormal_vertex 建立,begin_vertex / worldpos 使用)
|
|
416
424
|
vec3 s3mCustomOffset;
|
|
@@ -576,6 +584,9 @@ const VERT_WORLD = /* glsl */ `
|
|
|
576
584
|
mat3 s3mNormMat = mat3( modelMatrix );
|
|
577
585
|
#endif
|
|
578
586
|
vWorldNormal = normalize( s3mNormMat * ( s3mRot * normal ) );
|
|
587
|
+
// 视图空间位置直接拷 three 的 vViewPosition(此处已在 project_vertex 之后,
|
|
588
|
+
// 含实例化 / 形变的最终值):平面着色的导数法线与 FLAT_SHADED 分支逐点一致
|
|
589
|
+
vS3MViewPos = vViewPosition;
|
|
579
590
|
`;
|
|
580
591
|
|
|
581
592
|
const FRAG_PARS = /* glsl */ `
|
|
@@ -684,6 +695,8 @@ const FRAG_PARS = /* glsl */ `
|
|
|
684
695
|
varying float vWorldZ;
|
|
685
696
|
varying vec3 vWorldNormal;
|
|
686
697
|
varying vec3 vWorldPos;
|
|
698
|
+
varying vec3 vS3MViewPos;
|
|
699
|
+
uniform float uFlatShading;
|
|
687
700
|
|
|
688
701
|
vec4 s3mSampleBatchRow0( sampler2D texA, sampler2D texB, vec2 uv, float mixVal ) {
|
|
689
702
|
vec4 vA = texture2D( texA, uv );
|
|
@@ -885,6 +898,12 @@ export interface StyledMaterialOptions {
|
|
|
885
898
|
transparent?: boolean;
|
|
886
899
|
opacity?: number;
|
|
887
900
|
roughness?: number;
|
|
901
|
+
/**
|
|
902
|
+
* @deprecated 旧版用 three 的 `flatShading` define 表达,切换必重编译;现在
|
|
903
|
+
* shading 走共享 uniform `uFlatShading`(见 `createSharedUniforms`),运行期
|
|
904
|
+
* 二选一。此参数仅作为 uniform 的**初始值**被兼容(false = smooth),
|
|
905
|
+
* 运行期切换请走 viewer 的 `setStyle({ shading })`。
|
|
906
|
+
*/
|
|
888
907
|
flatShading?: boolean;
|
|
889
908
|
/** >0 时开启 alphaTest:镂空贴图(S3MBLOCK 图集)的透明片元直接丢弃,避免渲染成黑面 */
|
|
890
909
|
alphaTest?: number;
|
|
@@ -898,6 +917,27 @@ export interface StyledMaterialOptions {
|
|
|
898
917
|
* 创建一个带样式的 PBR 材质。
|
|
899
918
|
* 每个 Mesh 独享一个材质实例,但 uniform 对象是全局共享的。
|
|
900
919
|
*/
|
|
920
|
+
/**
|
|
921
|
+
* 片元法线覆盖:平面着色时用屏幕导数算真实几何法线。
|
|
922
|
+
*
|
|
923
|
+
* 注入在 `<normal_fragment_begin>` 之后——此时 three 已按平滑路径算好 `normal`
|
|
924
|
+
* (来自插值 vNormal);uFlatShading > 0.5 时用视图空间位置的导数叉积覆盖它,
|
|
925
|
+
* 数学上与 three 的 FLAT_SHADED 分支逐点一致(vS3MViewPos 符号对齐 vViewPosition)。
|
|
926
|
+
* 因为是运行期分支而非编译期 define,切 shading 不再触发重编译。
|
|
927
|
+
*/
|
|
928
|
+
const FRAG_NORMAL = /* glsl */ `
|
|
929
|
+
if ( uFlatShading > 0.5 ) {
|
|
930
|
+
vec3 s3mFlatN = normalize( cross( dFdx( vS3MViewPos ), dFdy( vS3MViewPos ) ) );
|
|
931
|
+
#ifdef USE_DOUBLE_SIDED
|
|
932
|
+
s3mFlatN = s3mFlatN * ( float( gl_FrontFacing ) * 2.0 - 1.0 );
|
|
933
|
+
#endif
|
|
934
|
+
#ifdef USE_FLIP_SIDED
|
|
935
|
+
s3mFlatN = - s3mFlatN;
|
|
936
|
+
#endif
|
|
937
|
+
normal = s3mFlatN;
|
|
938
|
+
}
|
|
939
|
+
`;
|
|
940
|
+
|
|
901
941
|
export function createStyledMaterial(opts: StyledMaterialOptions): StyledMaterial {
|
|
902
942
|
const uniforms = opts.uniforms;
|
|
903
943
|
// 两种光照模型共用的参数。注入的 chunk 只动 diffuseColor / normal / transformed,
|
|
@@ -909,9 +949,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
909
949
|
transparent: !!opts.transparent,
|
|
910
950
|
opacity: opts.opacity ?? 1,
|
|
911
951
|
depthWrite: opts.transparent ? false : true,
|
|
912
|
-
// 白模 / OSGB
|
|
913
|
-
//
|
|
914
|
-
|
|
952
|
+
// 白模 / OSGB 的法线多是共享顶点平均出来的,平滑插值会让墙面出现斑驳。
|
|
953
|
+
// 平面 / 平滑不再走 three 的 flatShading define(那是编译期变体,切换必重编译),
|
|
954
|
+
// 改由共享 uniform uFlatShading 在片元里二选一:材质恒为平滑,program 因此稳定。
|
|
955
|
+
flatShading: false,
|
|
915
956
|
// 顶点色、贴图全部在自定义 chunk 里处理,不让 three 插手
|
|
916
957
|
vertexColors: false,
|
|
917
958
|
alphaTest: opts.alphaTest ?? 0,
|
|
@@ -930,6 +971,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
930
971
|
const uSelBatch = { value: -1 };
|
|
931
972
|
// 没有单体化信息的几何(batchId = -1)只能整块选中
|
|
932
973
|
const uSelWhole = { value: 0 };
|
|
974
|
+
// shading 开关:跟随共享 uniforms(改一次全场景生效);测试里可能不传
|
|
975
|
+
// uniforms,这里兜底一份独立对象,与旧代码容忍 uniforms === undefined 的口径一致。
|
|
976
|
+
// 兼容旧参数:显式传 flatShading: false(旧语义 = smooth)映射为初始值 0
|
|
977
|
+
const uFlatShading = uniforms?.uFlatShading ?? { value: opts.flatShading === false ? 0 : 1 };
|
|
933
978
|
const uBatchTex = { value: DUMMY_BATCH_TEX };
|
|
934
979
|
const uBatchTex2 = { value: DUMMY_BATCH_TEX };
|
|
935
980
|
const uBatchTexWidth = { value: 1.0 };
|
|
@@ -950,6 +995,7 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
950
995
|
Object.assign(shader.uniforms, uniforms, {
|
|
951
996
|
uSelBatch,
|
|
952
997
|
uSelWhole,
|
|
998
|
+
uFlatShading,
|
|
953
999
|
uBatchTex,
|
|
954
1000
|
uBatchTex2,
|
|
955
1001
|
uBatchTexWidth,
|
|
@@ -987,6 +1033,12 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
987
1033
|
} else if (secMap) {
|
|
988
1034
|
shader.fragmentShader = shader.fragmentShader.replace('#include <map_fragment>', `#include <map_fragment>\n${FRAG_BAKE}`);
|
|
989
1035
|
}
|
|
1036
|
+
|
|
1037
|
+
// 平面 / 平滑着色:运行期分支(见 FRAG_NORMAL),不再依赖 flatShading define
|
|
1038
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
1039
|
+
'#include <normal_fragment_begin>',
|
|
1040
|
+
`#include <normal_fragment_begin>\n${FRAG_NORMAL}`
|
|
1041
|
+
);
|
|
990
1042
|
};
|
|
991
1043
|
|
|
992
1044
|
// 不同材质共用同一段注入代码,必须让 three 认为它们的 program 可复用;
|
|
@@ -1009,6 +1061,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
1009
1061
|
mat.userData.uBatchTexWidth = uBatchTexWidth;
|
|
1010
1062
|
mat.userData.uBatchTexActive = uBatchTexActive;
|
|
1011
1063
|
mat.userData.uTileFade = uTileFade;
|
|
1064
|
+
// 平面 / 平滑着色开关:S3MViewer._applyShading 翻它,不触发重编译
|
|
1065
|
+
mat.userData.uFlatShading = uFlatShading;
|
|
1066
|
+
// 记录创建参数:materialQuality 运行时切换时按原参数重建材质(换类不换外观)
|
|
1067
|
+
mat.userData.s3mOpts = opts;
|
|
1012
1068
|
mat.userData.isStyled = true;
|
|
1013
1069
|
return mat;
|
|
1014
1070
|
}
|
|
@@ -321,7 +321,21 @@ export class S3MTileset {
|
|
|
321
321
|
readonly atlasUpgraded = new Set<string>();
|
|
322
322
|
/** 拿到高清版但判定不通过 → 原因。用于排查「为什么这块还是糊的」 */
|
|
323
323
|
readonly atlasUpgradeSkipped = new Map<string, string>();
|
|
324
|
-
|
|
324
|
+
// drawCalls / programs / textures / geometries 是 viewer 级 GPU 观测,
|
|
325
|
+
// 瓦片侧不产生,恒为 0;聚合时由 S3MViewer.stats 用 renderer.info 覆盖
|
|
326
|
+
readonly stats: Stats = {
|
|
327
|
+
tiles: 0,
|
|
328
|
+
loading: 0,
|
|
329
|
+
failed: 0,
|
|
330
|
+
meshes: 0,
|
|
331
|
+
vertices: 0,
|
|
332
|
+
triangles: 0,
|
|
333
|
+
datasets: 1,
|
|
334
|
+
drawCalls: 0,
|
|
335
|
+
programs: 0,
|
|
336
|
+
textures: 0,
|
|
337
|
+
geometries: 0,
|
|
338
|
+
};
|
|
325
339
|
|
|
326
340
|
maxConcurrent: number;
|
|
327
341
|
maxTiles: number;
|