s3m-three 0.4.18 → 0.4.20
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/assets/s3mWorker-DvAUA8NJ.js +1 -0
- package/dist/browser/s3m-three.iife.ext-three.js +619 -304
- package/dist/browser/s3m-three.iife.js +647 -332
- package/dist/core/Draco.d.ts.map +1 -1
- package/dist/core/Draco.js +0 -1
- package/dist/core/Draco.js.map +1 -1
- package/dist/core/GaussianSplat.d.ts +64 -0
- package/dist/core/GaussianSplat.d.ts.map +1 -0
- package/dist/core/GaussianSplat.js +139 -0
- package/dist/core/GaussianSplat.js.map +1 -0
- package/dist/core/S3M1Parser.d.ts +1 -1
- package/dist/core/S3M1Parser.d.ts.map +1 -1
- package/dist/core/S3M1Parser.js +320 -25
- package/dist/core/S3M1Parser.js.map +1 -1
- package/dist/core/S3MBParser.d.ts.map +1 -1
- package/dist/core/S3MBParser.js +13 -0
- package/dist/core/S3MBParser.js.map +1 -1
- package/dist/core/S3MBlockParser.d.ts.map +1 -1
- package/dist/core/S3MBlockParser.js +83 -28
- package/dist/core/S3MBlockParser.js.map +1 -1
- package/dist/core/SplatLod.d.ts +36 -0
- package/dist/core/SplatLod.d.ts.map +1 -0
- package/dist/core/SplatLod.js +54 -0
- package/dist/core/SplatLod.js.map +1 -0
- package/dist/core/SplatProjection.d.ts +75 -0
- package/dist/core/SplatProjection.d.ts.map +1 -0
- package/dist/core/SplatProjection.js +162 -0
- package/dist/core/SplatProjection.js.map +1 -0
- package/dist/core/SplatSort.d.ts +26 -0
- package/dist/core/SplatSort.d.ts.map +1 -0
- package/dist/core/SplatSort.js +61 -0
- package/dist/core/SplatSort.js.map +1 -0
- package/dist/core/TexCoordZ.d.ts +94 -0
- package/dist/core/TexCoordZ.d.ts.map +1 -0
- package/dist/core/TexCoordZ.js +125 -0
- package/dist/core/TexCoordZ.js.map +1 -0
- package/dist/core/TextureDecode.d.ts +19 -0
- package/dist/core/TextureDecode.d.ts.map +1 -1
- package/dist/core/TextureDecode.js +53 -11
- package/dist/core/TextureDecode.js.map +1 -1
- package/dist/core/TileGeometry.d.ts +39 -0
- package/dist/core/TileGeometry.d.ts.map +1 -1
- package/dist/core/TileGeometry.js +133 -14
- package/dist/core/TileGeometry.js.map +1 -1
- package/dist/core/degradations.d.ts +37 -0
- package/dist/core/degradations.d.ts.map +1 -0
- package/dist/core/degradations.js +32 -0
- package/dist/core/degradations.js.map +1 -0
- package/dist/core/types.d.ts +36 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/render/DatasetManager.d.ts +11 -0
- package/dist/render/DatasetManager.d.ts.map +1 -1
- package/dist/render/DatasetManager.js +2 -0
- package/dist/render/DatasetManager.js.map +1 -1
- package/dist/render/FeatureStyleManager.d.ts.map +1 -1
- package/dist/render/FeatureStyleManager.js +7 -5
- package/dist/render/FeatureStyleManager.js.map +1 -1
- package/dist/render/GeometryBuilder.d.ts +31 -0
- package/dist/render/GeometryBuilder.d.ts.map +1 -1
- package/dist/render/GeometryBuilder.js +229 -6
- package/dist/render/GeometryBuilder.js.map +1 -1
- package/dist/render/Picker.d.ts.map +1 -1
- package/dist/render/Picker.js +19 -5
- package/dist/render/Picker.js.map +1 -1
- package/dist/render/S3MViewer.d.ts +106 -379
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +324 -1494
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/SplatMaterial.d.ts +103 -0
- package/dist/render/SplatMaterial.d.ts.map +1 -0
- package/dist/render/SplatMaterial.js +388 -0
- package/dist/render/SplatMaterial.js.map +1 -0
- package/dist/render/SplatSorter.d.ts +14 -0
- package/dist/render/SplatSorter.d.ts.map +1 -0
- package/dist/render/SplatSorter.js +66 -0
- package/dist/render/SplatSorter.js.map +1 -0
- package/dist/render/StyleMaterial.d.ts +48 -0
- package/dist/render/StyleMaterial.d.ts.map +1 -1
- package/dist/render/StyleMaterial.js +292 -69
- package/dist/render/StyleMaterial.js.map +1 -1
- package/dist/render/TextureFactory.d.ts +10 -0
- package/dist/render/TextureFactory.d.ts.map +1 -1
- package/dist/render/TextureFactory.js +35 -5
- package/dist/render/TextureFactory.js.map +1 -1
- package/dist/render/lightingPreset.d.ts +53 -0
- package/dist/render/lightingPreset.d.ts.map +1 -0
- package/dist/render/lightingPreset.js +36 -0
- package/dist/render/lightingPreset.js.map +1 -0
- package/dist/render/materialAlpha.d.ts +51 -0
- package/dist/render/materialAlpha.d.ts.map +1 -0
- package/dist/render/materialAlpha.js +68 -0
- package/dist/render/materialAlpha.js.map +1 -0
- package/dist/render/viewer/EdgeDecorator.d.ts +206 -0
- package/dist/render/viewer/EdgeDecorator.d.ts.map +1 -0
- package/dist/render/viewer/EdgeDecorator.js +628 -0
- package/dist/render/viewer/EdgeDecorator.js.map +1 -0
- package/dist/render/viewer/HeightIndex.d.ts +36 -0
- package/dist/render/viewer/HeightIndex.d.ts.map +1 -0
- package/dist/render/viewer/HeightIndex.js +98 -0
- package/dist/render/viewer/HeightIndex.js.map +1 -0
- package/dist/render/viewer/LightRig.d.ts +88 -0
- package/dist/render/viewer/LightRig.d.ts.map +1 -0
- package/dist/render/viewer/LightRig.js +229 -0
- package/dist/render/viewer/LightRig.js.map +1 -0
- package/dist/render/viewer/PickService.d.ts +109 -0
- package/dist/render/viewer/PickService.d.ts.map +1 -0
- package/dist/render/viewer/PickService.js +591 -0
- package/dist/render/viewer/PickService.js.map +1 -0
- package/dist/render/viewer/SelectionDecorator.d.ts +84 -0
- package/dist/render/viewer/SelectionDecorator.d.ts.map +1 -0
- package/dist/render/viewer/SelectionDecorator.js +339 -0
- package/dist/render/viewer/SelectionDecorator.js.map +1 -0
- package/dist/render/viewer/SplatLayer.d.ts +26 -0
- package/dist/render/viewer/SplatLayer.d.ts.map +1 -0
- package/dist/render/viewer/SplatLayer.js +44 -0
- package/dist/render/viewer/SplatLayer.js.map +1 -0
- package/dist/render/viewer/types.d.ts +250 -0
- package/dist/render/viewer/types.d.ts.map +1 -0
- package/dist/render/viewer/types.js +3 -0
- package/dist/render/viewer/types.js.map +1 -0
- package/dist/tileset/S3MTileset.d.ts +42 -1
- package/dist/tileset/S3MTileset.d.ts.map +1 -1
- package/dist/tileset/S3MTileset.js +52 -2
- package/dist/tileset/S3MTileset.js.map +1 -1
- package/dist/vendor/browser-node-stub.js +10 -0
- package/dist/worker/s3mWorker.js +1166 -979
- package/dist/worker/s3mWorker.js.map +1 -1
- package/docs/API.md +55 -1
- package/docs/FORMAT-NOTES.md +362 -0
- package/package.json +1 -1
- package/src/core/Draco.ts +1 -2
- package/src/core/GaussianSplat.ts +175 -0
- package/src/core/S3M1Parser.ts +330 -24
- package/src/core/S3MBParser.ts +18 -0
- package/src/core/S3MBlockParser.ts +83 -27
- package/src/core/SplatLod.ts +83 -0
- package/src/core/SplatProjection.ts +231 -0
- package/src/core/SplatSort.ts +92 -0
- package/src/core/TexCoordZ.ts +160 -0
- package/src/core/TextureDecode.ts +63 -11
- package/src/core/TileGeometry.ts +151 -14
- package/src/core/degradations.ts +74 -0
- package/src/core/types.ts +32 -0
- package/src/index.ts +8 -1
- package/src/render/DatasetManager.ts +10 -0
- package/src/render/FeatureStyleManager.ts +8 -6
- package/src/render/GeometryBuilder.ts +271 -7
- package/src/render/Picker.ts +21 -5
- package/src/render/S3MViewer.ts +358 -1727
- package/src/render/SplatMaterial.ts +433 -0
- package/src/render/SplatSorter.ts +66 -0
- package/src/render/StyleMaterial.ts +339 -69
- package/src/render/TextureFactory.ts +39 -5
- package/src/render/lightingPreset.ts +76 -0
- package/src/render/materialAlpha.ts +75 -0
- package/src/render/viewer/EdgeDecorator.ts +722 -0
- package/src/render/viewer/HeightIndex.ts +94 -0
- package/src/render/viewer/LightRig.ts +267 -0
- package/src/render/viewer/PickService.ts +651 -0
- package/src/render/viewer/SelectionDecorator.ts +377 -0
- package/src/render/viewer/SplatLayer.ts +44 -0
- package/src/render/viewer/types.ts +258 -0
- package/src/tileset/S3MTileset.ts +78 -2
- package/src/vendor/browser-node-stub.js +10 -0
- package/dist/browser/assets/s3mWorker-BjPOUgjg.js +0 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/** 3σ 覆盖 99.7% 的能量,与 3DGS 论文的裁剪口径一致 */
|
|
2
|
+
export const SPLAT_SIGMA = 3.0;
|
|
3
|
+
/** 抗锯齿低通的标准差(像素),3DGS 论文取 0.3 */
|
|
4
|
+
export const SPLAT_LOW_PASS_PIXELS = 0.3;
|
|
5
|
+
/**
|
|
6
|
+
* 半轴的最小像素长度(≈ 官方 lambda2 下限 0.1px² 对应的 sqrt(2*0.1))。
|
|
7
|
+
* 只防完全退化,绝不是「抬成可见尺寸」—— 后者是彩色噪点的来源。
|
|
8
|
+
*/
|
|
9
|
+
export const SPLAT_MIN_AXIS_PIXELS = 0.45;
|
|
10
|
+
/** 两根轴都短于这个像素数就整片丢弃(官方:dot(cov, cov) < 4.0 两轴同时成立) */
|
|
11
|
+
export const SPLAT_CULL_PIXELS = 2.0;
|
|
12
|
+
/**
|
|
13
|
+
* 半轴的像素上限。EWA 在中心贴近相机平面时会数值爆炸(实测近距离 max 4.2e6 px):
|
|
14
|
+
* 一个 quad 跨满整屏、只跟视锥相交出一个角,看上去就是锐角三角面和放射状拉丝。
|
|
15
|
+
* 1024px 只砍这些异常投影,正常建筑(放大到贴脸看也就几百 px)碰不到。
|
|
16
|
+
*/
|
|
17
|
+
export const SPLAT_MAX_AXIS_PIXELS = 1024;
|
|
18
|
+
/**
|
|
19
|
+
* 返回四边形在 ndc 里的两根半轴;相机后方(w<=0)返回 null。
|
|
20
|
+
* 调用方用 `clip.xy += (position.x*A + position.y*B) * clip.w` 出顶点。
|
|
21
|
+
*/
|
|
22
|
+
export function splatScreenAxes(o) {
|
|
23
|
+
const p = o.projection.elements; // 列主序
|
|
24
|
+
const cx = o.center[0], cy = o.center[1], cz = o.center[2];
|
|
25
|
+
const clipX = p[0] * cx + p[4] * cy + p[8] * cz + p[12];
|
|
26
|
+
const clipY = p[1] * cx + p[5] * cy + p[9] * cz + p[13];
|
|
27
|
+
const w = p[3] * cx + p[7] * cy + p[11] * cz + p[15];
|
|
28
|
+
if (!(w > 1e-6))
|
|
29
|
+
return null;
|
|
30
|
+
// M = W · R · diag(s),行向量取出后 Σ = M Mᵀ 只需要 6 个点积
|
|
31
|
+
const m = o.modelView.elements;
|
|
32
|
+
const [qx, qy, qz, qw] = [o.quat[0], o.quat[1], o.quat[2], o.quat[3]];
|
|
33
|
+
const xx = qx * qx, yy = qy * qy, zz = qz * qz;
|
|
34
|
+
const xy = qx * qy, xz = qx * qz, yz = qy * qz;
|
|
35
|
+
const wx = qw * qx, wy = qw * qy, wz = qw * qz;
|
|
36
|
+
// R 的列(列主序):R[col][row]
|
|
37
|
+
const r00 = 1 - 2 * (yy + zz), r01 = 2 * (xy - wz), r02 = 2 * (xz + wy);
|
|
38
|
+
const r10 = 2 * (xy + wz), r11 = 1 - 2 * (xx + zz), r12 = 2 * (yz - wx);
|
|
39
|
+
const r20 = 2 * (xz - wy), r21 = 2 * (yz + wx), r22 = 1 - 2 * (xx + yy);
|
|
40
|
+
const sx = o.scale[0], sy = o.scale[1], sz = o.scale[2];
|
|
41
|
+
// W · R · diag(s):W 的第 i 列乘 R 的第 j 列再乘 s_j —— 直接展开成 M 的列
|
|
42
|
+
// M[col] = W * (R[col] * s_col)
|
|
43
|
+
const m00 = (m[0] * r00 + m[4] * r10 + m[8] * r20) * sx;
|
|
44
|
+
const m10 = (m[1] * r00 + m[5] * r10 + m[9] * r20) * sx;
|
|
45
|
+
const m20 = (m[2] * r00 + m[6] * r10 + m[10] * r20) * sx;
|
|
46
|
+
const m01 = (m[0] * r01 + m[4] * r11 + m[8] * r21) * sy;
|
|
47
|
+
const m11 = (m[1] * r01 + m[5] * r11 + m[9] * r21) * sy;
|
|
48
|
+
const m21 = (m[2] * r01 + m[6] * r11 + m[10] * r21) * sy;
|
|
49
|
+
const m02 = (m[0] * r02 + m[4] * r12 + m[8] * r22) * sz;
|
|
50
|
+
const m12 = (m[1] * r02 + m[5] * r12 + m[9] * r22) * sz;
|
|
51
|
+
const m22 = (m[2] * r02 + m[6] * r12 + m[10] * r22) * sz;
|
|
52
|
+
// Σ 的上三角:行 i · 行 j
|
|
53
|
+
const v00 = m00 * m00 + m01 * m01 + m02 * m02;
|
|
54
|
+
const v01 = m00 * m10 + m01 * m11 + m02 * m12;
|
|
55
|
+
const v02 = m00 * m20 + m01 * m21 + m02 * m22;
|
|
56
|
+
const v11 = m10 * m10 + m11 * m11 + m12 * m12;
|
|
57
|
+
const v12 = m10 * m20 + m11 * m21 + m12 * m22;
|
|
58
|
+
const v22 = m20 * m20 + m21 * m21 + m22 * m22;
|
|
59
|
+
// 雅可比:ndc = clip.xy / w,对视图坐标求偏导
|
|
60
|
+
const w2 = w * w;
|
|
61
|
+
const j00 = (p[0] * w - clipX * p[3]) / w2;
|
|
62
|
+
const j01 = (p[4] * w - clipX * p[7]) / w2;
|
|
63
|
+
const j02 = (p[8] * w - clipX * p[11]) / w2;
|
|
64
|
+
const j10 = (p[1] * w - clipY * p[3]) / w2;
|
|
65
|
+
const j11 = (p[5] * w - clipY * p[7]) / w2;
|
|
66
|
+
const j12 = (p[9] * w - clipY * p[11]) / w2;
|
|
67
|
+
// C = J Σ Jᵀ(2×2 对称)
|
|
68
|
+
const c00 = j00 * (v00 * j00 + v01 * j01 + v02 * j02) +
|
|
69
|
+
j01 * (v01 * j00 + v11 * j01 + v12 * j02) +
|
|
70
|
+
j02 * (v02 * j00 + v12 * j01 + v22 * j02);
|
|
71
|
+
const c01 = j00 * (v00 * j10 + v01 * j11 + v02 * j12) +
|
|
72
|
+
j01 * (v01 * j10 + v11 * j11 + v12 * j12) +
|
|
73
|
+
j02 * (v02 * j10 + v12 * j11 + v22 * j12);
|
|
74
|
+
const c11 = j10 * (v00 * j10 + v01 * j11 + v02 * j12) +
|
|
75
|
+
j11 * (v01 * j10 + v11 * j11 + v12 * j12) +
|
|
76
|
+
j12 * (v02 * j10 + v12 * j11 + v22 * j12);
|
|
77
|
+
// 抗锯齿低通:对角各加一个亚像素方差
|
|
78
|
+
const lpx = (2 * SPLAT_LOW_PASS_PIXELS) / o.viewportWidth;
|
|
79
|
+
const lpy = (2 * SPLAT_LOW_PASS_PIXELS) / o.viewportHeight;
|
|
80
|
+
const d00 = c00 + lpx * lpx;
|
|
81
|
+
const d11 = c11 + lpy * lpy;
|
|
82
|
+
// 2×2 特征分解(解析解,无迭代)
|
|
83
|
+
const mid = 0.5 * (d00 + d11);
|
|
84
|
+
const half = 0.5 * (d00 - d11);
|
|
85
|
+
const disc = Math.sqrt(Math.max(half * half + c01 * c01, 0));
|
|
86
|
+
const l1 = mid + disc;
|
|
87
|
+
const l2 = Math.max(mid - disc, 0);
|
|
88
|
+
let v1x = c01, v1y = l1 - d00;
|
|
89
|
+
const vlen = Math.hypot(v1x, v1y);
|
|
90
|
+
if (vlen > 1e-20) {
|
|
91
|
+
v1x /= vlen;
|
|
92
|
+
v1y /= vlen;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
v1x = 1;
|
|
96
|
+
v1y = 0;
|
|
97
|
+
}
|
|
98
|
+
let r1 = SPLAT_SIGMA * Math.sqrt(Math.max(l1, 0));
|
|
99
|
+
let r2 = SPLAT_SIGMA * Math.sqrt(l2);
|
|
100
|
+
let ax = v1x * r1, ay = v1y * r1;
|
|
101
|
+
let bx = -v1y * r2, by = v1x * r2;
|
|
102
|
+
// 两道像素级处理,数值口径逐字照抄官方顶点着色器:
|
|
103
|
+
//
|
|
104
|
+
// ① 细轴下限。官方 `lambda2 = max(mid - radius, 0.1)`,即方差不低于 0.1px²,
|
|
105
|
+
// 对应半轴 sqrt(2*0.1) ≈ 0.447px。它只防「完全退化」,**不会**把一根
|
|
106
|
+
// 本来只有 1mm 的薄轴放大到肉眼可见 —— 放大才是噪点的来源。
|
|
107
|
+
// ② 亚像素剔除。官方 `if (dot(cov.xy,cov.xy) < 4.0 && dot(cov.zw,cov.zw) < 4.0)
|
|
108
|
+
// discard`:两根轴都短于 2px 的高斯直接不画。泼溅数据被过度细化时,
|
|
109
|
+
// 一个像素上会压着几十个亚像素高斯,逐个抬成 1px 硬点就是满屏彩色马赛克;
|
|
110
|
+
// 丢掉它们,粗层的大高斯自然接管,画面才干净。
|
|
111
|
+
const px = o.viewportWidth / 2;
|
|
112
|
+
const py = o.viewportHeight / 2;
|
|
113
|
+
// ③ 上限封顶(先于下限)。中心贴近相机平面时雅可比爆炸,半轴能到几百万像素。
|
|
114
|
+
// 等比缩小两根轴,长宽比保持不变 —— 各向异性形状不能被压圆。
|
|
115
|
+
// 不做这一步的表现是:一个 quad 跨满屏、与视锥只相交出一个角,
|
|
116
|
+
// 画面上就是散落的锐角三角面和放射状拉丝。
|
|
117
|
+
if (o.maxPixels && o.maxPixels > 0) {
|
|
118
|
+
const la0 = Math.hypot(ax * px, ay * py);
|
|
119
|
+
const lb0 = Math.hypot(bx * px, by * py);
|
|
120
|
+
const biggest = Math.max(la0, lb0);
|
|
121
|
+
if (biggest > o.maxPixels) {
|
|
122
|
+
const k = o.maxPixels / biggest;
|
|
123
|
+
ax *= k;
|
|
124
|
+
ay *= k;
|
|
125
|
+
bx *= k;
|
|
126
|
+
by *= k;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const floorPx = SPLAT_MIN_AXIS_PIXELS;
|
|
130
|
+
const la = Math.hypot(ax * px, ay * py);
|
|
131
|
+
const lb = Math.hypot(bx * px, by * py);
|
|
132
|
+
if (la < floorPx) {
|
|
133
|
+
if (la > 1e-20) {
|
|
134
|
+
const k = floorPx / la;
|
|
135
|
+
ax *= k;
|
|
136
|
+
ay *= k;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
ax = (2 * floorPx) / o.viewportWidth;
|
|
140
|
+
ay = 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (lb < floorPx) {
|
|
144
|
+
if (lb > 1e-20) {
|
|
145
|
+
const k = floorPx / lb;
|
|
146
|
+
bx *= k;
|
|
147
|
+
by *= k;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
bx = 0;
|
|
151
|
+
by = (2 * floorPx) / o.viewportHeight;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (o.cullPixels > 0) {
|
|
155
|
+
const ca = Math.hypot(ax * px, ay * py);
|
|
156
|
+
const cb = Math.hypot(bx * px, by * py);
|
|
157
|
+
if (ca < o.cullPixels && cb < o.cullPixels)
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
return { ax, ay, bx, by };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=SplatProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplatProjection.js","sourceRoot":"","sources":["../../src/core/SplatProjection.ts"],"names":[],"mappings":"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GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,CA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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 高斯泼溅的 back-to-front 排序(纯数学,可单测)
|
|
3
|
+
*
|
|
4
|
+
* alpha 混合是顺序相关的:先画近的再画远的,远的颜色会盖到近的上头,
|
|
5
|
+
* 画面就是一片随视角乱闪的彩色噪点。3DGS 必须按视深从远到近画。
|
|
6
|
+
*
|
|
7
|
+
* 排序键是**视图空间 z**(相机前方为负),升序 = 远的先画。
|
|
8
|
+
* view 矩阵由调用方给(通常是 camera.matrixWorldInverse × mesh.matrixWorld),
|
|
9
|
+
* 本模块不关心相机朝向约定,只取矩阵第三行做点积。
|
|
10
|
+
*
|
|
11
|
+
* ## 为什么是基数排序
|
|
12
|
+
*
|
|
13
|
+
* 这里是**每帧**都要跑的路径(相机一动就重排),原来的
|
|
14
|
+
* `TypedArray.sort((a, b) => keys[a] - keys[b])` 有两个代价:
|
|
15
|
+
* - 比较函数是 JS 调用,10 万点实测 38 ms/帧;
|
|
16
|
+
* - 每次调用都 `new Float32Array(count)` + `new Uint32Array(count)`,每帧分配 800 KB。
|
|
17
|
+
*
|
|
18
|
+
* 换成 4 遍 8 位 LSD 基数排序后实测 3 ms,且缓冲全部复用。没选桶排序是因为
|
|
19
|
+
* 深度分布会很不均匀(正对相机的墙面,几万个点的视深几乎相同),桶内再排会退化。
|
|
20
|
+
*
|
|
21
|
+
* 排序键先转成「无符号可比」的 32 位整数(IEEE754 的标准技巧),
|
|
22
|
+
* 这样无符号整数比较的大小顺序与 float 完全一致,基数排序才成立。
|
|
23
|
+
*/
|
|
24
|
+
import type * as THREE from 'three';
|
|
25
|
+
export declare function splatDepthOrder(positions: Float32Array, count: number, view: THREE.Matrix4, out?: Uint32Array): Uint32Array;
|
|
26
|
+
//# sourceMappingURL=SplatSort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplatSort.d.ts","sourceRoot":"","sources":["../../src/core/SplatSort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAkBpC,wBAAgB,eAAe,CAC7B,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,KAAK,CAAC,OAAO,EACnB,GAAG,CAAC,EAAE,WAAW,GAChB,WAAW,CA6Cb"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** 模块级 scratch:只增不减。排序是同步的,同一时刻只有一个在跑 */
|
|
2
|
+
let _keys = new Uint32Array(0);
|
|
3
|
+
let _scratch = new Uint32Array(0);
|
|
4
|
+
const _counts = new Uint32Array(256);
|
|
5
|
+
/** float → 无符号可比的 32 位键(正数翻符号位,负数按位取反) */
|
|
6
|
+
const _f32 = new Float32Array(1);
|
|
7
|
+
const _u32 = new Uint32Array(_f32.buffer);
|
|
8
|
+
function sortableBits(k) {
|
|
9
|
+
_f32[0] = k;
|
|
10
|
+
const u = _u32[0];
|
|
11
|
+
// 负数的 IEEE754 表示是「符号位 1 + 绝对值」,直接按无符号比会把 -1 排到 0 后面
|
|
12
|
+
return u & 0x80000000 ? ~u >>> 0 : (u | 0x80000000) >>> 0;
|
|
13
|
+
}
|
|
14
|
+
export function splatDepthOrder(positions, count, view, out) {
|
|
15
|
+
const idx = out && out.length >= count ? out : new Uint32Array(count);
|
|
16
|
+
if (count <= 1) {
|
|
17
|
+
if (count === 1)
|
|
18
|
+
idx[0] = 0;
|
|
19
|
+
return idx;
|
|
20
|
+
}
|
|
21
|
+
if (_keys.length < count)
|
|
22
|
+
_keys = new Uint32Array(count);
|
|
23
|
+
if (_scratch.length < count)
|
|
24
|
+
_scratch = new Uint32Array(count);
|
|
25
|
+
const keys = _keys;
|
|
26
|
+
const scratch = _scratch;
|
|
27
|
+
const e = view.elements;
|
|
28
|
+
const r0 = e[2], r1 = e[6], r2 = e[10], r3 = e[14];
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
keys[i] = sortableBits(r0 * positions[i * 3] + r1 * positions[i * 3 + 1] + r2 * positions[i * 3 + 2] + r3);
|
|
31
|
+
idx[i] = i;
|
|
32
|
+
}
|
|
33
|
+
// 4 遍 × 8 位。偶数遍 → 结果一定回到 idx,不用再拷一次
|
|
34
|
+
let src = idx;
|
|
35
|
+
let dst = scratch;
|
|
36
|
+
for (let pass = 0; pass < 4; pass++) {
|
|
37
|
+
const shift = pass * 8;
|
|
38
|
+
_counts.fill(0);
|
|
39
|
+
for (let i = 0; i < count; i++)
|
|
40
|
+
_counts[(keys[src[i]] >>> shift) & 0xff]++;
|
|
41
|
+
// 前缀和 → 每个桶的起始写位置
|
|
42
|
+
let sum = 0;
|
|
43
|
+
for (let b = 0; b < 256; b++) {
|
|
44
|
+
const c = _counts[b];
|
|
45
|
+
_counts[b] = sum;
|
|
46
|
+
sum += c;
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < count; i++) {
|
|
49
|
+
const v = src[i];
|
|
50
|
+
dst[_counts[(keys[v] >>> shift) & 0xff]++] = v;
|
|
51
|
+
}
|
|
52
|
+
const t = src;
|
|
53
|
+
src = dst;
|
|
54
|
+
dst = t;
|
|
55
|
+
}
|
|
56
|
+
// 4 遍之后 src 就是 idx(起始 src=idx,偶数次交换后回到 idx);防御性兜一下
|
|
57
|
+
if (src !== idx)
|
|
58
|
+
idx.set(src);
|
|
59
|
+
return idx;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=SplatSort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplatSort.js","sourceRoot":"","sources":["../../src/core/SplatSort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S3M 的 uv 第三分量(顶点属性 `custom0`,官方叫 `aTextureCoordMatrix`)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么需要它:官方引擎对普通(非 S3MBLOCK)S3M 瓦片并不是「有纹理就整张平铺」。
|
|
5
|
+
* 每个顶点在 uv 之外还带一个 z,iClient3D 在**顶点着色器**里拿它解出一个纹理矩阵:
|
|
6
|
+
*
|
|
7
|
+
* `getTextureMatrixFromZValue( floor(z), xTran, yTran, scale )`
|
|
8
|
+
* bit[0:7] → yTran (图集列号)
|
|
9
|
+
* bit[8:15] → xTran (图集行号)
|
|
10
|
+
* bit[16:19] → level (scale = 1 / 2^level,即图集是 2^level × 2^level 格)
|
|
11
|
+
* 三档哨兵(官方 bundle getTextureColor / getUV 实测):
|
|
12
|
+
* z < -99900 → `return vec4(1.0)` 纯白不采样(平涂顶点色面,值 -99999)
|
|
13
|
+
* z < -9000 → 「uv 原样平铺整图」:calculateTexCoord 里 `out = inTexCoord.xy`
|
|
14
|
+
* (不 fract 不缩放),普通 texture2D(自动 mip)采样
|
|
15
|
+
* 其余 → 图集子区域公式
|
|
16
|
+
*
|
|
17
|
+
* 片元侧是 `calculateMipLevel` + `calculateTexCoord`:
|
|
18
|
+
*
|
|
19
|
+
* fTile = scale * texWidth // 一格在图里的像素宽
|
|
20
|
+
* mip = clamp( 0.5*log2(d), 0, log2(fTile) - 1.62 )
|
|
21
|
+
* f = clamp( fract(uv), 2^mip/fTile, 1 - 2^mip/fTile ) // 越糊越往格子中心收缩
|
|
22
|
+
* out = ( f + T ) * scale
|
|
23
|
+
*
|
|
24
|
+
* 实测 SuperMap Online 的 `3D-BIMbuilding-2`(OSGB 转 S3M,全部 7 个根瓦片):
|
|
25
|
+
* z ∈ { -99999, 0, 65536, 65537, 65792, 65793, 262144, 327680 }
|
|
26
|
+
* uv 是米制世界坐标(1 单位 ≈ 1 m),每米一个纹理周期。
|
|
27
|
+
*
|
|
28
|
+
* 本文件是这段数学的**唯一可执行版本**:着色器里是它的 GLSL 直译
|
|
29
|
+
* (见 render/StyleMaterial.ts 的 VERT_TEXCOORD_Z / s3mTexCoordZUnit),
|
|
30
|
+
* 单测 tests/unit/texcoord-z-math.test.ts 钉住两边必须一致。
|
|
31
|
+
*/
|
|
32
|
+
/** 官方哨兵:`inTexCoord.z < -9000` 走「uv 原样平铺」分支(getTexColorForS3M / calculateTexCoord) */
|
|
33
|
+
export declare const TEX_COORD_Z_DISABLED_BELOW = -9000;
|
|
34
|
+
/**
|
|
35
|
+
* 官方白色哨兵:`texCoordZ < -99900` 时 getTextureColor 直接 `return vec4(1.0)`,
|
|
36
|
+
* **完全不采样纹理**(数据里是 -99999)。最终颜色 = 白 × 材质 diffuse × 顶点色,
|
|
37
|
+
* 即「平涂顶点色面」—— BIM 场景的地面标线 / 色块就是这类(SMID 3464:灰色地面 +
|
|
38
|
+
* 黄色标线 + 暗红区域,全靠顶点色)。
|
|
39
|
+
*
|
|
40
|
+
* 注意与 -9000 平铺哨兵的区分:-99999 一旦按平铺处理,uv(-85..85 这类米制值)
|
|
41
|
+
* 会把整张纹理平铺上百次,表现为「uv 整图」——这正是三档语义漏掉白色档的教训。
|
|
42
|
+
*/
|
|
43
|
+
export declare const TEX_COORD_Z_WHITE_BELOW = -99900;
|
|
44
|
+
/** 官方 calculateMipLevel 里那个上限收缩量 */
|
|
45
|
+
export declare const MIP_LIMIT_BIAS = 1.62;
|
|
46
|
+
/** 该顶点是否走「uv 原样平铺」分支。没有这条属性的数据 z 取 0,返回 false,行为不变。 */
|
|
47
|
+
export declare function isTexCoordDisabled(z: number): boolean;
|
|
48
|
+
/** 该顶点是否走「纯白、不采样」分支(z < -99900,实测值 -99999)。优先级高于平铺。 */
|
|
49
|
+
export declare function isTexCoordWhite(z: number): boolean;
|
|
50
|
+
/** 解码结果。`disabled` 为真时其余字段无意义(着色器里对应 scale = -1;`white` 时 scale = -2) */
|
|
51
|
+
export interface TexMatrix {
|
|
52
|
+
disabled: boolean;
|
|
53
|
+
/** z < -99900:纯白不采样(见 TEX_COORD_Z_WHITE_BELOW) */
|
|
54
|
+
white: boolean;
|
|
55
|
+
/** 一格占整张纹理的比例,1/2^level */
|
|
56
|
+
scale: number;
|
|
57
|
+
/** 图集列号 */
|
|
58
|
+
xTran: number;
|
|
59
|
+
/** 图集行号 */
|
|
60
|
+
yTran: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 官方 `getTextureMatrixFromZValue` 的逐行移植。
|
|
64
|
+
*
|
|
65
|
+
* 注意 `nZ <= 0` 时官方直接 return,**不改**外部初值 —— 也就是单位变换
|
|
66
|
+
* `scale=1, T=(0,0)`,等价于整张纹理按 uv 平铺。
|
|
67
|
+
*
|
|
68
|
+
* 着色器侧的档位编码:scale = -2 → 白;-1 → 平铺;>0 → 图集公式。
|
|
69
|
+
*/
|
|
70
|
+
export declare function decodeTexMatrix(z: number): TexMatrix;
|
|
71
|
+
/** 官方 `vTexMatrix.w = log2( uTexture0Width * vTexMatrix.z )` */
|
|
72
|
+
export declare function texMaxMip(texWidth: number, scale: number): number;
|
|
73
|
+
/**
|
|
74
|
+
* 官方 `calculateMipLevel` 的逐行移植。
|
|
75
|
+
*
|
|
76
|
+
* 四个导数参数是 `dFdx(u) / dvDx / duDy / dFdy(v)`(uv 单位每像素),
|
|
77
|
+
* 内部乘 `fTile = scale*texWidth` 换成纹素单位 —— 与官方
|
|
78
|
+
* `dFdx( inTexCoord * vecTile )` 完全一致。
|
|
79
|
+
*
|
|
80
|
+
* ★ 必须用**未 fract 的 uv** 求导:先 fract 再求导会在平铺接缝处炸出一个
|
|
81
|
+
* 巨大导数,硬件会把整块面采成最糊的 mip,表现为每条接缝一条暗带。
|
|
82
|
+
*/
|
|
83
|
+
export declare function texMipLevel(duDx: number, dvDx: number, duDy: number, dvDy: number, fTile: number, maxMip: number): number;
|
|
84
|
+
/**
|
|
85
|
+
* 官方 `calculateTexCoord` 的逐行移植:fract → 按 mip 内缩 → 平移 + 缩放。
|
|
86
|
+
*
|
|
87
|
+
* `mip` 必须已经过 `texMipLevel` 的上限裁剪(≤ maxMip - 1.62),
|
|
88
|
+
* 否则 `2^mip/fTile > 0.5` 时 clamp 的上下界会翻转,官方同样会出问题。
|
|
89
|
+
*/
|
|
90
|
+
export declare function sampleTexCoord(m: TexMatrix, u: number, v: number, texWidth: number, mip: number): {
|
|
91
|
+
u: number;
|
|
92
|
+
v: number;
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=TexCoordZ.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TexCoordZ.d.ts","sourceRoot":"","sources":["../../src/core/TexCoordZ.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,SAAS,CAAC;AAE9C,oCAAoC;AACpC,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC,uDAAuD;AACvD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,KAAK,EAAE,OAAO,CAAC;IACf,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAqBpD;AAED,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjE;AAID;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CAYR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,SAAS,EACZ,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,GACV;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM1B"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S3M 的 uv 第三分量(顶点属性 `custom0`,官方叫 `aTextureCoordMatrix`)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么需要它:官方引擎对普通(非 S3MBLOCK)S3M 瓦片并不是「有纹理就整张平铺」。
|
|
5
|
+
* 每个顶点在 uv 之外还带一个 z,iClient3D 在**顶点着色器**里拿它解出一个纹理矩阵:
|
|
6
|
+
*
|
|
7
|
+
* `getTextureMatrixFromZValue( floor(z), xTran, yTran, scale )`
|
|
8
|
+
* bit[0:7] → yTran (图集列号)
|
|
9
|
+
* bit[8:15] → xTran (图集行号)
|
|
10
|
+
* bit[16:19] → level (scale = 1 / 2^level,即图集是 2^level × 2^level 格)
|
|
11
|
+
* 三档哨兵(官方 bundle getTextureColor / getUV 实测):
|
|
12
|
+
* z < -99900 → `return vec4(1.0)` 纯白不采样(平涂顶点色面,值 -99999)
|
|
13
|
+
* z < -9000 → 「uv 原样平铺整图」:calculateTexCoord 里 `out = inTexCoord.xy`
|
|
14
|
+
* (不 fract 不缩放),普通 texture2D(自动 mip)采样
|
|
15
|
+
* 其余 → 图集子区域公式
|
|
16
|
+
*
|
|
17
|
+
* 片元侧是 `calculateMipLevel` + `calculateTexCoord`:
|
|
18
|
+
*
|
|
19
|
+
* fTile = scale * texWidth // 一格在图里的像素宽
|
|
20
|
+
* mip = clamp( 0.5*log2(d), 0, log2(fTile) - 1.62 )
|
|
21
|
+
* f = clamp( fract(uv), 2^mip/fTile, 1 - 2^mip/fTile ) // 越糊越往格子中心收缩
|
|
22
|
+
* out = ( f + T ) * scale
|
|
23
|
+
*
|
|
24
|
+
* 实测 SuperMap Online 的 `3D-BIMbuilding-2`(OSGB 转 S3M,全部 7 个根瓦片):
|
|
25
|
+
* z ∈ { -99999, 0, 65536, 65537, 65792, 65793, 262144, 327680 }
|
|
26
|
+
* uv 是米制世界坐标(1 单位 ≈ 1 m),每米一个纹理周期。
|
|
27
|
+
*
|
|
28
|
+
* 本文件是这段数学的**唯一可执行版本**:着色器里是它的 GLSL 直译
|
|
29
|
+
* (见 render/StyleMaterial.ts 的 VERT_TEXCOORD_Z / s3mTexCoordZUnit),
|
|
30
|
+
* 单测 tests/unit/texcoord-z-math.test.ts 钉住两边必须一致。
|
|
31
|
+
*/
|
|
32
|
+
/** 官方哨兵:`inTexCoord.z < -9000` 走「uv 原样平铺」分支(getTexColorForS3M / calculateTexCoord) */
|
|
33
|
+
export const TEX_COORD_Z_DISABLED_BELOW = -9000;
|
|
34
|
+
/**
|
|
35
|
+
* 官方白色哨兵:`texCoordZ < -99900` 时 getTextureColor 直接 `return vec4(1.0)`,
|
|
36
|
+
* **完全不采样纹理**(数据里是 -99999)。最终颜色 = 白 × 材质 diffuse × 顶点色,
|
|
37
|
+
* 即「平涂顶点色面」—— BIM 场景的地面标线 / 色块就是这类(SMID 3464:灰色地面 +
|
|
38
|
+
* 黄色标线 + 暗红区域,全靠顶点色)。
|
|
39
|
+
*
|
|
40
|
+
* 注意与 -9000 平铺哨兵的区分:-99999 一旦按平铺处理,uv(-85..85 这类米制值)
|
|
41
|
+
* 会把整张纹理平铺上百次,表现为「uv 整图」——这正是三档语义漏掉白色档的教训。
|
|
42
|
+
*/
|
|
43
|
+
export const TEX_COORD_Z_WHITE_BELOW = -99900;
|
|
44
|
+
/** 官方 calculateMipLevel 里那个上限收缩量 */
|
|
45
|
+
export const MIP_LIMIT_BIAS = 1.62;
|
|
46
|
+
/** 该顶点是否走「uv 原样平铺」分支。没有这条属性的数据 z 取 0,返回 false,行为不变。 */
|
|
47
|
+
export function isTexCoordDisabled(z) {
|
|
48
|
+
return z < TEX_COORD_Z_DISABLED_BELOW;
|
|
49
|
+
}
|
|
50
|
+
/** 该顶点是否走「纯白、不采样」分支(z < -99900,实测值 -99999)。优先级高于平铺。 */
|
|
51
|
+
export function isTexCoordWhite(z) {
|
|
52
|
+
return z < TEX_COORD_Z_WHITE_BELOW;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 官方 `getTextureMatrixFromZValue` 的逐行移植。
|
|
56
|
+
*
|
|
57
|
+
* 注意 `nZ <= 0` 时官方直接 return,**不改**外部初值 —— 也就是单位变换
|
|
58
|
+
* `scale=1, T=(0,0)`,等价于整张纹理按 uv 平铺。
|
|
59
|
+
*
|
|
60
|
+
* 着色器侧的档位编码:scale = -2 → 白;-1 → 平铺;>0 → 图集公式。
|
|
61
|
+
*/
|
|
62
|
+
export function decodeTexMatrix(z) {
|
|
63
|
+
if (isTexCoordWhite(z)) {
|
|
64
|
+
return { disabled: true, white: true, scale: -2, xTran: 0, yTran: 0 };
|
|
65
|
+
}
|
|
66
|
+
if (isTexCoordDisabled(z)) {
|
|
67
|
+
return { disabled: true, white: false, scale: -1, xTran: 0, yTran: 0 };
|
|
68
|
+
}
|
|
69
|
+
const nz = Math.floor(z);
|
|
70
|
+
if (nz <= 0) {
|
|
71
|
+
return { disabled: false, white: false, scale: 1, xTran: 0, yTran: 0 };
|
|
72
|
+
}
|
|
73
|
+
const nDel8 = Math.floor(nz / 256);
|
|
74
|
+
const nDel16 = Math.floor(nDel8 / 256);
|
|
75
|
+
const nDel20 = Math.floor(nDel16 / 16);
|
|
76
|
+
return {
|
|
77
|
+
disabled: false,
|
|
78
|
+
white: false,
|
|
79
|
+
xTran: nDel8 - nDel16 * 256,
|
|
80
|
+
yTran: nz - nDel8 * 256,
|
|
81
|
+
scale: 1 / Math.pow(2, nDel16 - nDel20 * 16),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** 官方 `vTexMatrix.w = log2( uTexture0Width * vTexMatrix.z )` */
|
|
85
|
+
export function texMaxMip(texWidth, scale) {
|
|
86
|
+
return Math.log2(texWidth * scale);
|
|
87
|
+
}
|
|
88
|
+
const clamp = (v, lo, hi) => Math.min(Math.max(v, lo), hi);
|
|
89
|
+
/**
|
|
90
|
+
* 官方 `calculateMipLevel` 的逐行移植。
|
|
91
|
+
*
|
|
92
|
+
* 四个导数参数是 `dFdx(u) / dvDx / duDy / dFdy(v)`(uv 单位每像素),
|
|
93
|
+
* 内部乘 `fTile = scale*texWidth` 换成纹素单位 —— 与官方
|
|
94
|
+
* `dFdx( inTexCoord * vecTile )` 完全一致。
|
|
95
|
+
*
|
|
96
|
+
* ★ 必须用**未 fract 的 uv** 求导:先 fract 再求导会在平铺接缝处炸出一个
|
|
97
|
+
* 巨大导数,硬件会把整块面采成最糊的 mip,表现为每条接缝一条暗带。
|
|
98
|
+
*/
|
|
99
|
+
export function texMipLevel(duDx, dvDx, duDy, dvDy, fTile, maxMip) {
|
|
100
|
+
const xU = duDx * fTile;
|
|
101
|
+
const xV = dvDx * fTile;
|
|
102
|
+
const yU = duDy * fTile;
|
|
103
|
+
const yV = dvDy * fTile;
|
|
104
|
+
const dotX = xU * xU + xV * xV;
|
|
105
|
+
const dotY = yU * yU + yV * yV;
|
|
106
|
+
const dMax = Math.max(dotX, dotY);
|
|
107
|
+
const dMin = Math.min(dotX, dotY);
|
|
108
|
+
const off = clamp((dMax - dMin) / Math.max(dMax + dMin, 1e-8), 0, 1);
|
|
109
|
+
const d = dMax * (1 - off) + dMin * off;
|
|
110
|
+
return clamp(0.5 * Math.log2(Math.max(d, 1e-8)), 0, maxMip - MIP_LIMIT_BIAS);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 官方 `calculateTexCoord` 的逐行移植:fract → 按 mip 内缩 → 平移 + 缩放。
|
|
114
|
+
*
|
|
115
|
+
* `mip` 必须已经过 `texMipLevel` 的上限裁剪(≤ maxMip - 1.62),
|
|
116
|
+
* 否则 `2^mip/fTile > 0.5` 时 clamp 的上下界会翻转,官方同样会出问题。
|
|
117
|
+
*/
|
|
118
|
+
export function sampleTexCoord(m, u, v, texWidth, mip) {
|
|
119
|
+
const fTile = Math.max(m.scale * texWidth, 1);
|
|
120
|
+
const inner = Math.pow(2, mip) / fTile;
|
|
121
|
+
const fu = clamp(u - Math.floor(u), inner, 1 - inner);
|
|
122
|
+
const fv = clamp(v - Math.floor(v), inner, 1 - inner);
|
|
123
|
+
return { u: (fu + m.xTran) * m.scale, v: (fv + m.yTran) * m.scale };
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=TexCoordZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TexCoordZ.js","sourceRoot":"","sources":["../../src/core/TexCoordZ.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,16 @@ export interface DecodedTextureData {
|
|
|
16
16
|
*/
|
|
17
17
|
blocks?: Uint8Array;
|
|
18
18
|
blockFormat?: 'dxt1' | 'dxt5';
|
|
19
|
+
/**
|
|
20
|
+
* 数据自带的 DXT 内联 mip 链(S3M 纹理的 data 常是 level0 + 完整链,`tex.level`
|
|
21
|
+
* 记录层数)。官方 iClient3D 把整条链逐层上传,远处采样高层级平均成纯色。
|
|
22
|
+
* 与 blocks 同时存在;渲染层用它构造多层 CompressedTexture。
|
|
23
|
+
*/
|
|
24
|
+
mipmaps?: {
|
|
25
|
+
data: Uint8Array;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
}[];
|
|
19
29
|
/** CRN 转码失败时的原始错误(渲染层负责打 warn) */
|
|
20
30
|
error?: string;
|
|
21
31
|
}
|
|
@@ -43,6 +53,15 @@ export interface DecodeOptions {
|
|
|
43
53
|
* 压缩直传前必须用这个函数把关,不匹配就回退 RGBA 解码。
|
|
44
54
|
*/
|
|
45
55
|
export declare function expectedDxtByteLength(width: number, height: number, format: 'dxt1' | 'dxt5'): number;
|
|
56
|
+
/**
|
|
57
|
+
* 切 DXT 内联 mip 链:`data` = level0 + 逐层减半直到 1×1,每层 ceil(w/4)*ceil(h/4)*blockBytes。
|
|
58
|
+
* 切不出与总字节数严丝合缝的链(不是链 / 格式对不上)返回 null,调用方回退。
|
|
59
|
+
*/
|
|
60
|
+
export declare function sliceDxtMipChain(data: Uint8Array, width: number, height: number, blockBytes: number): {
|
|
61
|
+
data: Uint8Array;
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
}[] | null;
|
|
46
65
|
/** 主线程 / Worker 共用的解码入口。不抛错:失败与不支持都体现在返回值里 */
|
|
47
66
|
export declare function decodeTextureData(tex: S3MTexture, options?: DecodeOptions): Promise<DecodedTextureData>;
|
|
48
67
|
//# sourceMappingURL=TextureDecode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextureDecode.d.ts","sourceRoot":"","sources":["../../src/core/TextureDecode.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,qEAAqE;IACrE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIpG;AAED,8CAA8C;AAC9C,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAK7B"}
|
|
1
|
+
{"version":3,"file":"TextureDecode.d.ts","sourceRoot":"","sources":["../../src/core/TextureDecode.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,qEAAqE;IACrE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIpG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,IAAI,CAgB9D;AAED,8CAA8C;AAC9C,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAK7B"}
|
|
@@ -137,6 +137,30 @@ export function expectedDxtByteLength(width, height, format) {
|
|
|
137
137
|
const bh = (height + 3) >> 2;
|
|
138
138
|
return bw * bh * (format === 'dxt1' ? 8 : 16);
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* 切 DXT 内联 mip 链:`data` = level0 + 逐层减半直到 1×1,每层 ceil(w/4)*ceil(h/4)*blockBytes。
|
|
142
|
+
* 切不出与总字节数严丝合缝的链(不是链 / 格式对不上)返回 null,调用方回退。
|
|
143
|
+
*/
|
|
144
|
+
export function sliceDxtMipChain(data, width, height, blockBytes) {
|
|
145
|
+
const levels = [];
|
|
146
|
+
let w = width;
|
|
147
|
+
let h = height;
|
|
148
|
+
let off = 0;
|
|
149
|
+
for (;;) {
|
|
150
|
+
const bytes = Math.ceil(w / 4) * Math.ceil(h / 4) * blockBytes;
|
|
151
|
+
if (off + bytes > data.byteLength)
|
|
152
|
+
return null;
|
|
153
|
+
levels.push({ data: data.subarray(off, off + bytes), width: w, height: h });
|
|
154
|
+
off += bytes;
|
|
155
|
+
if (w === 1 && h === 1)
|
|
156
|
+
break;
|
|
157
|
+
w = Math.max(1, w >> 1);
|
|
158
|
+
h = Math.max(1, h >> 1);
|
|
159
|
+
}
|
|
160
|
+
if (off !== data.byteLength)
|
|
161
|
+
return null;
|
|
162
|
+
return levels;
|
|
163
|
+
}
|
|
140
164
|
/** 主线程 / Worker 共用的解码入口。不抛错:失败与不支持都体现在返回值里 */
|
|
141
165
|
export async function decodeTextureData(tex, options = {}) {
|
|
142
166
|
// 尺寸收口放在这一层:raw 里各分支(DXT / CRN / raw / WebP)有多个 return,
|
|
@@ -210,17 +234,35 @@ async function decodeTextureDataRaw(tex, options = {}) {
|
|
|
210
234
|
if (kind === 'dxt1' || kind === 'dxt3' || kind === 'dxt4' || kind === 'dxt5') {
|
|
211
235
|
const pf = dxtPixelFormatOf(kind);
|
|
212
236
|
// dxt3/dxt4 少见,不进直传白名单;块长与 4×4 对齐公式不符的也回退解码
|
|
213
|
-
if (canCompress && (kind === 'dxt1' || kind === 'dxt5')
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
237
|
+
if (canCompress && (kind === 'dxt1' || kind === 'dxt5')) {
|
|
238
|
+
const level0Bytes = expectedDxtByteLength(tex.width, tex.height, kind);
|
|
239
|
+
if (tex.data.byteLength === level0Bytes && compressible(tex.data, tex.width, tex.height, kind)) {
|
|
240
|
+
return {
|
|
241
|
+
kind: `${kind}(c)`,
|
|
242
|
+
width: tex.width,
|
|
243
|
+
height: tex.height,
|
|
244
|
+
rgba: null,
|
|
245
|
+
bitmap: null,
|
|
246
|
+
hasAlpha: kind === 'dxt5',
|
|
247
|
+
blocks: tex.data,
|
|
248
|
+
blockFormat: kind,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// 带内联 mip 链:整条切出来逐层上传(官方同款)。切不齐(字节不吻合)再回退解码
|
|
252
|
+
const chain = sliceDxtMipChain(tex.data, tex.width, tex.height, kind === 'dxt1' ? 8 : 16);
|
|
253
|
+
if (chain && chain.length > 1) {
|
|
254
|
+
return {
|
|
255
|
+
kind: `${kind}(chain)`,
|
|
256
|
+
width: tex.width,
|
|
257
|
+
height: tex.height,
|
|
258
|
+
rgba: null,
|
|
259
|
+
bitmap: null,
|
|
260
|
+
hasAlpha: kind === 'dxt5',
|
|
261
|
+
blocks: tex.data,
|
|
262
|
+
blockFormat: kind,
|
|
263
|
+
mipmaps: chain,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
224
266
|
}
|
|
225
267
|
const decoded = decodeDXT({ ...tex, pixelFormat: pf });
|
|
226
268
|
return { kind, width: tex.width, height: tex.height, rgba: decoded.rgba, bitmap: null, hasAlpha: decoded.hasAlpha };
|