s3m-three 0.4.15 → 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 +118 -24
- package/dist/browser/s3m-three.iife.js +118 -24
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/render/EdgeLines.d.ts +14 -2
- package/dist/render/EdgeLines.d.ts.map +1 -1
- package/dist/render/EdgeLines.js +45 -8
- package/dist/render/EdgeLines.js.map +1 -1
- package/dist/render/GpuEdgePass.d.ts +58 -0
- package/dist/render/GpuEdgePass.d.ts.map +1 -0
- package/dist/render/GpuEdgePass.js +207 -0
- package/dist/render/GpuEdgePass.js.map +1 -0
- package/dist/render/S3MViewer.d.ts +66 -14
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +327 -87
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/StyleMaterial.d.ts +98 -7
- package/dist/render/StyleMaterial.d.ts.map +1 -1
- package/dist/render/StyleMaterial.js +107 -9
- 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 +77 -27
- package/package.json +1 -1
- package/src/core/types.ts +8 -0
- package/src/index.ts +4 -0
- package/src/render/EdgeLines.ts +50 -8
- package/src/render/GpuEdgePass.ts +236 -0
- package/src/render/S3MViewer.ts +352 -84
- package/src/render/StyleMaterial.ts +193 -11
- package/src/tileset/S3MTileset.ts +15 -1
|
@@ -61,6 +61,75 @@ export const SELECT_MODE_LABELS: Record<SelectMode, string> = {
|
|
|
61
61
|
[SELECT_MODE.GLOW_ONLY]: '仅描边发光 (Glow)',
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
/* ------------------------------------------------------------------ 棱线画法 */
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 全局棱线的画法。
|
|
68
|
+
*
|
|
69
|
+
* - `'line'` CPU 折边线:焊合 → 折边判定 → 屏幕空间等宽四边形(默认口径)
|
|
70
|
+
* - `'offset'` 同上,但整段沿「边法线」往外推 `edgeOffset` 米。贴在面上的线会被
|
|
71
|
+
* 面的明暗吃掉,推出去一点才看得清,代价是要多带一条 aNormal 属性
|
|
72
|
+
* - `'hull'` 背面外扩轮廓:把整块几何沿法线鼓一圈、只画背面,得到「白模 + 卡通
|
|
73
|
+
* 描边」的观感。不建任何折边几何,成本就是多画一遍网格
|
|
74
|
+
* - `'gpu'` 纯片元描边:在主材质里用屏幕导数找「法线突变」的像素,直接混成棱线色。
|
|
75
|
+
* 零几何、零额外 pass,代价是线宽约 1 个设备像素,且描不出几何外轮廓
|
|
76
|
+
*/
|
|
77
|
+
export type EdgeStyle = 'line' | 'offset' | 'hull' | 'gpu';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* `style.edges` 的取值。
|
|
81
|
+
*
|
|
82
|
+
* boolean 是旧口径(`true` = `'line'`),字符串 / 数组用来选画法,数组可叠加,
|
|
83
|
+
* 例如 `['line', 'hull']` = 折边线 + 外扩轮廓同时上。
|
|
84
|
+
* 注意 `'offset'` 隐含折边线:外推是折边线的修饰,不是另一种线。
|
|
85
|
+
*/
|
|
86
|
+
export type EdgesOption = boolean | EdgeStyle | EdgeStyle[];
|
|
87
|
+
|
|
88
|
+
/** 归一化后的棱线开关 */
|
|
89
|
+
export interface EdgeModes {
|
|
90
|
+
/** 整体开关:任一画法命中就是 true */
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
/** 是否建 CPU 折边线 */
|
|
93
|
+
line: boolean;
|
|
94
|
+
/** 折边线是否沿边法线外推 */
|
|
95
|
+
offset: boolean;
|
|
96
|
+
/** 是否挂背面外扩轮廓 */
|
|
97
|
+
hull: boolean;
|
|
98
|
+
/** 是否在材质里做片元级描边(零几何) */
|
|
99
|
+
gpu: boolean;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const EDGE_MODE_OFF: EdgeModes = { enabled: false, line: false, offset: false, hull: false, gpu: false };
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 把 `EdgesOption` 归一成四个开关。
|
|
106
|
+
*
|
|
107
|
+
* 未知值(宿主 JS 里传错字符串 / 脏数组)一律当关,不抛错也不误开——样式这种东西
|
|
108
|
+
* 出错时最该做的是「保持不动」,而不是把整个图层带崩。
|
|
109
|
+
*/
|
|
110
|
+
export function resolveEdgeModes(value: EdgesOption | null | undefined): EdgeModes {
|
|
111
|
+
if (value == null || value === false) return { ...EDGE_MODE_OFF };
|
|
112
|
+
if (value === true) return { ...EDGE_MODE_OFF, enabled: true, line: true };
|
|
113
|
+
|
|
114
|
+
const list = Array.isArray(value) ? value : [value];
|
|
115
|
+
const modes: EdgeModes = { ...EDGE_MODE_OFF };
|
|
116
|
+
for (const item of list) {
|
|
117
|
+
if (item === 'line') modes.line = true;
|
|
118
|
+
else if (item === 'offset') {
|
|
119
|
+
modes.line = true;
|
|
120
|
+
modes.offset = true;
|
|
121
|
+
} else if (item === 'hull') modes.hull = true;
|
|
122
|
+
else if (item === 'gpu') modes.gpu = true;
|
|
123
|
+
}
|
|
124
|
+
modes.enabled = modes.line || modes.hull || modes.gpu;
|
|
125
|
+
return modes;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** 两套开关是否等价(只比较有效位,用来判断要不要重建装饰) */
|
|
129
|
+
export function sameEdgeModes(a: EdgeModes, b: EdgeModes): boolean {
|
|
130
|
+
return a.line === b.line && a.offset === b.offset && a.hull === b.hull && a.gpu === b.gpu;
|
|
131
|
+
}
|
|
132
|
+
|
|
64
133
|
/* ------------------------------------------------------------------ 样式配置 */
|
|
65
134
|
|
|
66
135
|
/** 图层整体样式(宿主无关,S3MViewer 与 s3m-maplibre 的 S3MLayer 共用) */
|
|
@@ -105,14 +174,31 @@ export interface S3MStyle {
|
|
|
105
174
|
outlineWidth?: number;
|
|
106
175
|
/** 选中棱线的粗细(像素,默认 3,仅 outlineStyle: 'edges' 生效,缩放时保持恒定) */
|
|
107
176
|
outlineWidthPx?: number;
|
|
108
|
-
/**
|
|
109
|
-
|
|
177
|
+
/**
|
|
178
|
+
* 是否显示几何棱线。
|
|
179
|
+
*
|
|
180
|
+
* 取值是 `boolean | EdgeStyle | EdgeStyle[]`:`true` 等价于 `'line'`(旧口径),
|
|
181
|
+
* `'hull'` 走背面外扩轮廓,`'offset'` 是折边线 + 法线外推,数组可叠加。
|
|
182
|
+
* 见 `resolveEdgeModes`。
|
|
183
|
+
*/
|
|
184
|
+
edges: EdgesOption;
|
|
110
185
|
/** 全局棱线粗细(像素,默认 1.2) */
|
|
111
186
|
edgeWidth?: number;
|
|
112
187
|
edgeColor: string;
|
|
113
188
|
edgeOpacity?: number;
|
|
114
189
|
/** 棱线临界角(度):相邻面法线夹角超过该值才描边,过滤掉浅坡与曲面细分。默认 55° */
|
|
115
190
|
edgeThreshold?: number;
|
|
191
|
+
/** 折边线沿边法线外推的距离(米,默认 0.15,仅 edges 含 'offset' 生效) */
|
|
192
|
+
edgeOffset?: number;
|
|
193
|
+
/** 背面外扩轮廓的厚度(米,默认 0.9,仅 edges 含 'hull' 生效) */
|
|
194
|
+
edgeHullWidth?: number;
|
|
195
|
+
/**
|
|
196
|
+
* 忽略数据自带的棱线包(primitiveType 13),一律 CPU 现算。默认 false。
|
|
197
|
+
*
|
|
198
|
+
* 数据自带的棱线是 `LineBasicMaterial`,线宽恒 1px,`edgeWidth` / 外扩 / 单体跟随
|
|
199
|
+
* 全都吃不上。想让这些能力对所有数据统一生效就打开它,代价是 CPU 要现算折边。
|
|
200
|
+
*/
|
|
201
|
+
forceCpuEdges?: boolean;
|
|
116
202
|
roofThreshold?: number;
|
|
117
203
|
/** 是否与模型原色贴图叠加混合(0 = 纯色覆盖,1 = 叠乘原色贴图) */
|
|
118
204
|
texMix?: number;
|
|
@@ -161,6 +247,9 @@ export const DEFAULT_STYLE: S3MStyle = {
|
|
|
161
247
|
edgeColor: '#334155',
|
|
162
248
|
edgeOpacity: 0.6,
|
|
163
249
|
edgeThreshold: 55,
|
|
250
|
+
edgeOffset: 0.15,
|
|
251
|
+
edgeHullWidth: 0.9,
|
|
252
|
+
forceCpuEdges: false,
|
|
164
253
|
roofThreshold: 0.65,
|
|
165
254
|
texMix: 0,
|
|
166
255
|
ambientGain: 0,
|
|
@@ -286,6 +375,12 @@ export function createSharedUniforms(): StyleUniforms {
|
|
|
286
375
|
* (压暗 → 换模式 → 亮回来),比硬切自然得多。
|
|
287
376
|
*/
|
|
288
377
|
uFade: { value: 1 },
|
|
378
|
+
/**
|
|
379
|
+
* 平面 / 平滑着色开关:0 = 平滑(插值法线),1 = 平面(屏幕导数法线)。
|
|
380
|
+
* 走 uniform 而不是 three 的 `flatShading` define,所以切换 shading 不会触发
|
|
381
|
+
* 着色器重编译(旧实现靠 prewarm 把卡顿藏起来,现在连卡顿都没有)。
|
|
382
|
+
*/
|
|
383
|
+
uFlatShading: { value: 1 },
|
|
289
384
|
};
|
|
290
385
|
}
|
|
291
386
|
const VERT_PARS = /* glsl */ `
|
|
@@ -322,6 +417,8 @@ const VERT_PARS = /* glsl */ `
|
|
|
322
417
|
varying float vWorldZ;
|
|
323
418
|
varying vec3 vWorldNormal;
|
|
324
419
|
varying vec3 vWorldPos;
|
|
420
|
+
// 视图空间位置:平面着色用它算屏幕导数法线,符号与 three 的 vViewPosition 一致
|
|
421
|
+
varying vec3 vS3MViewPos;
|
|
325
422
|
|
|
326
423
|
// 跨 chunk 共享的顶点姿态变量(在 beginnormal_vertex 建立,begin_vertex / worldpos 使用)
|
|
327
424
|
vec3 s3mCustomOffset;
|
|
@@ -487,6 +584,9 @@ const VERT_WORLD = /* glsl */ `
|
|
|
487
584
|
mat3 s3mNormMat = mat3( modelMatrix );
|
|
488
585
|
#endif
|
|
489
586
|
vWorldNormal = normalize( s3mNormMat * ( s3mRot * normal ) );
|
|
587
|
+
// 视图空间位置直接拷 three 的 vViewPosition(此处已在 project_vertex 之后,
|
|
588
|
+
// 含实例化 / 形变的最终值):平面着色的导数法线与 FLAT_SHADED 分支逐点一致
|
|
589
|
+
vS3MViewPos = vViewPosition;
|
|
490
590
|
`;
|
|
491
591
|
|
|
492
592
|
const FRAG_PARS = /* glsl */ `
|
|
@@ -595,6 +695,8 @@ const FRAG_PARS = /* glsl */ `
|
|
|
595
695
|
varying float vWorldZ;
|
|
596
696
|
varying vec3 vWorldNormal;
|
|
597
697
|
varying vec3 vWorldPos;
|
|
698
|
+
varying vec3 vS3MViewPos;
|
|
699
|
+
uniform float uFlatShading;
|
|
598
700
|
|
|
599
701
|
vec4 s3mSampleBatchRow0( sampler2D texA, sampler2D texB, vec2 uv, float mixVal ) {
|
|
600
702
|
vec4 vA = texture2D( texA, uv );
|
|
@@ -796,6 +898,12 @@ export interface StyledMaterialOptions {
|
|
|
796
898
|
transparent?: boolean;
|
|
797
899
|
opacity?: number;
|
|
798
900
|
roughness?: number;
|
|
901
|
+
/**
|
|
902
|
+
* @deprecated 旧版用 three 的 `flatShading` define 表达,切换必重编译;现在
|
|
903
|
+
* shading 走共享 uniform `uFlatShading`(见 `createSharedUniforms`),运行期
|
|
904
|
+
* 二选一。此参数仅作为 uniform 的**初始值**被兼容(false = smooth),
|
|
905
|
+
* 运行期切换请走 viewer 的 `setStyle({ shading })`。
|
|
906
|
+
*/
|
|
799
907
|
flatShading?: boolean;
|
|
800
908
|
/** >0 时开启 alphaTest:镂空贴图(S3MBLOCK 图集)的透明片元直接丢弃,避免渲染成黑面 */
|
|
801
909
|
alphaTest?: number;
|
|
@@ -809,6 +917,27 @@ export interface StyledMaterialOptions {
|
|
|
809
917
|
* 创建一个带样式的 PBR 材质。
|
|
810
918
|
* 每个 Mesh 独享一个材质实例,但 uniform 对象是全局共享的。
|
|
811
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
|
+
|
|
812
941
|
export function createStyledMaterial(opts: StyledMaterialOptions): StyledMaterial {
|
|
813
942
|
const uniforms = opts.uniforms;
|
|
814
943
|
// 两种光照模型共用的参数。注入的 chunk 只动 diffuseColor / normal / transformed,
|
|
@@ -820,9 +949,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
820
949
|
transparent: !!opts.transparent,
|
|
821
950
|
opacity: opts.opacity ?? 1,
|
|
822
951
|
depthWrite: opts.transparent ? false : true,
|
|
823
|
-
// 白模 / OSGB
|
|
824
|
-
//
|
|
825
|
-
|
|
952
|
+
// 白模 / OSGB 的法线多是共享顶点平均出来的,平滑插值会让墙面出现斑驳。
|
|
953
|
+
// 平面 / 平滑不再走 three 的 flatShading define(那是编译期变体,切换必重编译),
|
|
954
|
+
// 改由共享 uniform uFlatShading 在片元里二选一:材质恒为平滑,program 因此稳定。
|
|
955
|
+
flatShading: false,
|
|
826
956
|
// 顶点色、贴图全部在自定义 chunk 里处理,不让 three 插手
|
|
827
957
|
vertexColors: false,
|
|
828
958
|
alphaTest: opts.alphaTest ?? 0,
|
|
@@ -841,6 +971,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
841
971
|
const uSelBatch = { value: -1 };
|
|
842
972
|
// 没有单体化信息的几何(batchId = -1)只能整块选中
|
|
843
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 };
|
|
844
978
|
const uBatchTex = { value: DUMMY_BATCH_TEX };
|
|
845
979
|
const uBatchTex2 = { value: DUMMY_BATCH_TEX };
|
|
846
980
|
const uBatchTexWidth = { value: 1.0 };
|
|
@@ -861,6 +995,7 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
861
995
|
Object.assign(shader.uniforms, uniforms, {
|
|
862
996
|
uSelBatch,
|
|
863
997
|
uSelWhole,
|
|
998
|
+
uFlatShading,
|
|
864
999
|
uBatchTex,
|
|
865
1000
|
uBatchTex2,
|
|
866
1001
|
uBatchTexWidth,
|
|
@@ -898,6 +1033,12 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
898
1033
|
} else if (secMap) {
|
|
899
1034
|
shader.fragmentShader = shader.fragmentShader.replace('#include <map_fragment>', `#include <map_fragment>\n${FRAG_BAKE}`);
|
|
900
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
|
+
);
|
|
901
1042
|
};
|
|
902
1043
|
|
|
903
1044
|
// 不同材质共用同一段注入代码,必须让 three 认为它们的 program 可复用;
|
|
@@ -920,6 +1061,10 @@ export function createStyledMaterial(opts: StyledMaterialOptions): StyledMateria
|
|
|
920
1061
|
mat.userData.uBatchTexWidth = uBatchTexWidth;
|
|
921
1062
|
mat.userData.uBatchTexActive = uBatchTexActive;
|
|
922
1063
|
mat.userData.uTileFade = uTileFade;
|
|
1064
|
+
// 平面 / 平滑着色开关:S3MViewer._applyShading 翻它,不触发重编译
|
|
1065
|
+
mat.userData.uFlatShading = uFlatShading;
|
|
1066
|
+
// 记录创建参数:materialQuality 运行时切换时按原参数重建材质(换类不换外观)
|
|
1067
|
+
mat.userData.s3mOpts = opts;
|
|
923
1068
|
mat.userData.isStyled = true;
|
|
924
1069
|
return mat;
|
|
925
1070
|
}
|
|
@@ -1029,18 +1174,34 @@ const OUTLINE_VERT = /* glsl */ `
|
|
|
1029
1174
|
|
|
1030
1175
|
const OUTLINE_FRAG = /* glsl */ `
|
|
1031
1176
|
uniform vec3 uColor;
|
|
1177
|
+
uniform float uOpacity;
|
|
1032
1178
|
varying float vSel;
|
|
1033
1179
|
void main() {
|
|
1034
1180
|
if ( vSel < 0.5 ) discard;
|
|
1035
|
-
|
|
1181
|
+
if ( uOpacity <= 0.003 ) discard;
|
|
1182
|
+
gl_FragColor = vec4( uColor, uOpacity );
|
|
1036
1183
|
}
|
|
1037
1184
|
`;
|
|
1038
1185
|
|
|
1186
|
+
/**
|
|
1187
|
+
* 外扩轮廓的「外观」uniform。
|
|
1188
|
+
*
|
|
1189
|
+
* 与棱线一样,全局外扩是逐网格一份材质(要各绑各的单体状态纹理),但颜色 / 厚度 /
|
|
1190
|
+
* 不透明度必须全局统一 —— 所以这些 `{ value }` 对象由调用方持有并共享给每一份材质,
|
|
1191
|
+
* 改一次全场景生效。
|
|
1192
|
+
*/
|
|
1193
|
+
export interface OutlineStyleUniforms {
|
|
1194
|
+
uColor: { value: THREE.Color };
|
|
1195
|
+
uWidth: { value: number };
|
|
1196
|
+
uOpacity: { value: number };
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1039
1199
|
export interface OutlineMaterial extends THREE.ShaderMaterial {
|
|
1040
1200
|
uniforms: {
|
|
1041
1201
|
uSelBatch: { value: number };
|
|
1042
1202
|
uSelWhole: { value: number };
|
|
1043
1203
|
uWidth: { value: number };
|
|
1204
|
+
uOpacity: { value: number };
|
|
1044
1205
|
uElevation: { value: number };
|
|
1045
1206
|
uBatchTex: { value: THREE.Texture };
|
|
1046
1207
|
uBatchTex2: { value: THREE.Texture };
|
|
@@ -1055,13 +1216,34 @@ export interface OutlineMaterial extends THREE.ShaderMaterial {
|
|
|
1055
1216
|
};
|
|
1056
1217
|
}
|
|
1057
1218
|
|
|
1058
|
-
/**
|
|
1059
|
-
|
|
1219
|
+
/**
|
|
1220
|
+
* 描边材质(背面外扩法)。
|
|
1221
|
+
*
|
|
1222
|
+
* 选中侧与全局棱线共用这一份实现,差别只在 uniform:
|
|
1223
|
+
* - 选中:`uSelBatch` = 选中单体的 batchId,只扩那一栋,不透明
|
|
1224
|
+
* - 全局:`uSelWhole` = 1,整块几何都扩,走 `edgeOpacity` 混合
|
|
1225
|
+
*
|
|
1226
|
+
* @param styleUniforms 传入时**直接复用这些 `{ value }` 对象**,让逐网格材质共享外观
|
|
1227
|
+
* @param transparent 全局外扩要能吃 `edgeOpacity`,选中侧保持不透明(默认 false)
|
|
1228
|
+
*/
|
|
1229
|
+
export function createOutlineMaterial(
|
|
1230
|
+
shared: StyleUniforms,
|
|
1231
|
+
initialWidth = 0.9,
|
|
1232
|
+
styleUniforms?: OutlineStyleUniforms,
|
|
1233
|
+
transparent = false
|
|
1234
|
+
): OutlineMaterial {
|
|
1235
|
+
const style: OutlineStyleUniforms = styleUniforms ?? {
|
|
1236
|
+
uColor: { value: shared.uSelColor.value.clone() },
|
|
1237
|
+
uWidth: { value: initialWidth },
|
|
1238
|
+
uOpacity: { value: 1 },
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1060
1241
|
const mat = new THREE.ShaderMaterial({
|
|
1061
1242
|
uniforms: {
|
|
1062
1243
|
uSelBatch: { value: -1 },
|
|
1063
1244
|
uSelWhole: { value: 0 },
|
|
1064
|
-
uWidth:
|
|
1245
|
+
uWidth: style.uWidth,
|
|
1246
|
+
uOpacity: style.uOpacity,
|
|
1065
1247
|
uElevation: { value: 0 },
|
|
1066
1248
|
uBatchTex: { value: DUMMY_BATCH_TEX },
|
|
1067
1249
|
uBatchTex2: { value: DUMMY_BATCH_TEX },
|
|
@@ -1072,13 +1254,13 @@ export function createOutlineMaterial(shared: StyleUniforms, initialWidth = 0.9)
|
|
|
1072
1254
|
uPathCount: shared.uPathCount ?? { value: 1 },
|
|
1073
1255
|
uPathTexActive: shared.uPathTexActive ?? { value: 0 },
|
|
1074
1256
|
uPathTime: shared.uPathTime ?? { value: 0 },
|
|
1075
|
-
uColor:
|
|
1257
|
+
uColor: style.uColor,
|
|
1076
1258
|
},
|
|
1077
1259
|
vertexShader: OUTLINE_VERT,
|
|
1078
1260
|
fragmentShader: OUTLINE_FRAG,
|
|
1079
1261
|
side: THREE.BackSide,
|
|
1080
1262
|
depthWrite: false,
|
|
1081
|
-
transparent
|
|
1263
|
+
transparent,
|
|
1082
1264
|
// 描边要压在建筑后面一点,避免和本体 z-fighting
|
|
1083
1265
|
polygonOffset: true,
|
|
1084
1266
|
polygonOffsetFactor: 1,
|
|
@@ -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;
|