@spatialwalk/avatarkit 1.0.0-beta.77 → 1.0.0-beta.78
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/CHANGELOG.md +14 -0
- package/dist/{StreamingAudioPlayer-BtOgYxcz.js → StreamingAudioPlayer-BNj8LpDw.js} +9 -79
- package/dist/avatar_core_wasm-e68766db.wasm +0 -0
- package/dist/core/AvatarController.d.ts +0 -1
- package/dist/core/AvatarManager.d.ts +12 -3
- package/dist/core/AvatarView.d.ts +33 -0
- package/dist/{index-CTh2onXJ.js → index-DEJMvfST.js} +581 -2764
- package/dist/index.js +1 -1
- package/dist/internal/constants.d.ts +102 -0
- package/dist/internal/index.d.ts +7 -0
- package/dist/renderer/webgpu/webgpuRenderer.d.ts +0 -57
- package/dist/utils/animation-interpolation.d.ts +3 -1
- package/dist/wasm/avatarCoreAdapter.d.ts +0 -49
- package/dist/wasm/avatarCoreMemory.d.ts +0 -13
- package/package.json +13 -14
- package/dist/renderer/webgpu/flameGPUBuffers.d.ts +0 -137
- package/dist/renderer/webgpu/flamePipeline.d.ts +0 -71
- package/dist/renderer/webgpu/gpuRadixSort.d.ts +0 -47
- package/dist/renderer/webgpu/transformPipeline.d.ts +0 -97
package/dist/index.js
CHANGED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar SDK 内部共享常量
|
|
3
|
+
* 跨平台统一配置,确保行为一致
|
|
4
|
+
*
|
|
5
|
+
* 对应:
|
|
6
|
+
* - Android: AvatarPlayer.kt 中的 companion object
|
|
7
|
+
* - iOS: (待实现)
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
/** 帧间隔 (毫秒) */
|
|
12
|
+
export declare const FLAME_FRAME_INTERVAL_MS: number;
|
|
13
|
+
/** 开始过渡时长 (秒): idle -> speaking */
|
|
14
|
+
export declare const START_TRANSITION_DURATION_S = 0.2;
|
|
15
|
+
/** 结束过渡时长 (秒): speaking -> idle */
|
|
16
|
+
export declare const END_TRANSITION_DURATION_S = 1.6;
|
|
17
|
+
/** 开始过渡时长 (毫秒) */
|
|
18
|
+
export declare const START_TRANSITION_DURATION_MS: number;
|
|
19
|
+
/** 结束过渡时长 (毫秒) */
|
|
20
|
+
export declare const END_TRANSITION_DURATION_MS: number;
|
|
21
|
+
/** 默认音频采样率 (Hz) */
|
|
22
|
+
export declare const AUDIO_SAMPLE_RATE = 16000;
|
|
23
|
+
/** 音频声道数 (mono) */
|
|
24
|
+
export declare const AUDIO_CHANNELS = 1;
|
|
25
|
+
/** 每样本字节数 (16bit PCM) */
|
|
26
|
+
export declare const AUDIO_BYTES_PER_SAMPLE = 2;
|
|
27
|
+
/** 每秒音频字节数 */
|
|
28
|
+
export declare const AUDIO_BYTES_PER_SECOND: number;
|
|
29
|
+
/**
|
|
30
|
+
* 各部位插值曲线控制点
|
|
31
|
+
* 格式: [x1, y1, x2, y2] 对应 cubic-bezier(x1, y1, x2, y2)
|
|
32
|
+
*
|
|
33
|
+
* 与 Android FlameFrameData.kt 中的 BEZIER_CURVES 完全一致
|
|
34
|
+
*/
|
|
35
|
+
export declare const BEZIER_CURVES: {
|
|
36
|
+
/** 下颌: 快速启动,平滑停止 */
|
|
37
|
+
readonly jaw: readonly [0.2, 0.8, 0.3, 1];
|
|
38
|
+
/** 表情: 平滑 S 曲线 */
|
|
39
|
+
readonly expression: readonly [0.4, 0, 0.2, 1];
|
|
40
|
+
/** 眼部: 柔和 S 曲线 */
|
|
41
|
+
readonly eye: readonly [0.3, 0, 0.1, 1];
|
|
42
|
+
/** 颈部: 慢启动,惯性停止 */
|
|
43
|
+
readonly neck: readonly [0.1, 0.2, 0.2, 1];
|
|
44
|
+
/** 全局: 标准 ease-in-out */
|
|
45
|
+
readonly global: readonly [0.42, 0, 0.58, 1];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* 各部位时间缩放因子
|
|
49
|
+
* 控制各部位完成过渡所需的相对时间
|
|
50
|
+
*
|
|
51
|
+
* 与 Android FlameFrameData.kt 中的 TIME_SCALE 完全一致
|
|
52
|
+
*/
|
|
53
|
+
export declare const TIME_SCALE: {
|
|
54
|
+
/** 下颌: 40% 时间完成 (1/2.5) */
|
|
55
|
+
readonly jaw: 2.5;
|
|
56
|
+
/** 表情: 62.5% 时间完成 (1/1.6) */
|
|
57
|
+
readonly expression: 1.6;
|
|
58
|
+
/** 眼部: 77% 时间完成 (1/1.3) */
|
|
59
|
+
readonly eye: 1.3;
|
|
60
|
+
/** 颈部: 100% 时间完成 */
|
|
61
|
+
readonly neck: 1;
|
|
62
|
+
/** 全局: 100% 时间完成 */
|
|
63
|
+
readonly global: 1;
|
|
64
|
+
};
|
|
65
|
+
export type BezierCurveKey = keyof typeof BEZIER_CURVES;
|
|
66
|
+
export type TimeScaleKey = keyof typeof TIME_SCALE;
|
|
67
|
+
export declare const AvatarConstants: {
|
|
68
|
+
readonly FLAME_FRAME_RATE: 25;
|
|
69
|
+
readonly FLAME_FRAME_INTERVAL_MS: number;
|
|
70
|
+
readonly START_TRANSITION_DURATION_S: 0.2;
|
|
71
|
+
readonly END_TRANSITION_DURATION_S: 1.6;
|
|
72
|
+
readonly START_TRANSITION_DURATION_MS: number;
|
|
73
|
+
readonly END_TRANSITION_DURATION_MS: number;
|
|
74
|
+
readonly AUDIO_SAMPLE_RATE: 16000;
|
|
75
|
+
readonly AUDIO_CHANNELS: 1;
|
|
76
|
+
readonly AUDIO_BYTES_PER_SAMPLE: 2;
|
|
77
|
+
readonly AUDIO_BYTES_PER_SECOND: number;
|
|
78
|
+
readonly BEZIER_CURVES: {
|
|
79
|
+
/** 下颌: 快速启动,平滑停止 */
|
|
80
|
+
readonly jaw: readonly [0.2, 0.8, 0.3, 1];
|
|
81
|
+
/** 表情: 平滑 S 曲线 */
|
|
82
|
+
readonly expression: readonly [0.4, 0, 0.2, 1];
|
|
83
|
+
/** 眼部: 柔和 S 曲线 */
|
|
84
|
+
readonly eye: readonly [0.3, 0, 0.1, 1];
|
|
85
|
+
/** 颈部: 慢启动,惯性停止 */
|
|
86
|
+
readonly neck: readonly [0.1, 0.2, 0.2, 1];
|
|
87
|
+
/** 全局: 标准 ease-in-out */
|
|
88
|
+
readonly global: readonly [0.42, 0, 0.58, 1];
|
|
89
|
+
};
|
|
90
|
+
readonly TIME_SCALE: {
|
|
91
|
+
/** 下颌: 40% 时间完成 (1/2.5) */
|
|
92
|
+
readonly jaw: 2.5;
|
|
93
|
+
/** 表情: 62.5% 时间完成 (1/1.6) */
|
|
94
|
+
readonly expression: 1.6;
|
|
95
|
+
/** 眼部: 77% 时间完成 (1/1.3) */
|
|
96
|
+
readonly eye: 1.3;
|
|
97
|
+
/** 颈部: 100% 时间完成 */
|
|
98
|
+
readonly neck: 1;
|
|
99
|
+
/** 全局: 100% 时间完成 */
|
|
100
|
+
readonly global: 1;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { I3DGSRenderer, Transform } from '../renderer';
|
|
2
|
-
import { FLAMETemplateData, FLAMEFrameParams, ActiveShapeParams } from './flameGPUBuffers';
|
|
3
2
|
export declare class WebGPURenderer implements I3DGSRenderer {
|
|
4
3
|
private canvas;
|
|
5
4
|
private backgroundColor;
|
|
@@ -14,13 +13,6 @@ export declare class WebGPURenderer implements I3DGSRenderer {
|
|
|
14
13
|
private splatDataBuffer;
|
|
15
14
|
private storageBindGroup;
|
|
16
15
|
private bindGroupNeedsUpdate;
|
|
17
|
-
private transformPipeline;
|
|
18
|
-
private useGPUTransform;
|
|
19
|
-
private flamePipeline;
|
|
20
|
-
private flameGPUBuffers;
|
|
21
|
-
private useGPUFLAME;
|
|
22
|
-
private gpuRadixSort;
|
|
23
|
-
private useGPURadixSort;
|
|
24
16
|
private splatCount;
|
|
25
17
|
private presentationFormat;
|
|
26
18
|
private alpha;
|
|
@@ -64,54 +56,10 @@ export declare class WebGPURenderer implements I3DGSRenderer {
|
|
|
64
56
|
* 🚀 完全消除 CPU 重排序开销
|
|
65
57
|
*/
|
|
66
58
|
loadSplatsFromPackedData(packedData: Float32Array, pointCount: number, sortOrder?: Uint32Array): void;
|
|
67
|
-
/**
|
|
68
|
-
* 🆕 上传原始Splats数据到GPU (一次性调用,角色加载时)
|
|
69
|
-
* @param originalSplatsData Float32Array, 每个splat 16 floats (64 bytes)
|
|
70
|
-
* @param splatCount splat数量
|
|
71
|
-
*/
|
|
72
|
-
loadOriginalSplats(originalSplatsData: Float32Array, splatCount: number): void;
|
|
73
|
-
/**
|
|
74
|
-
* 🆕 更新Face Geometry (每帧调用,用于GPU Transform优化)
|
|
75
|
-
* @param faceGeometryData Float32Array, 每个face 8 floats (32 bytes)
|
|
76
|
-
*/
|
|
77
|
-
updateFaceGeometry(faceGeometryData: Float32Array): void;
|
|
78
|
-
/**
|
|
79
|
-
* 🆕 加载 FLAME 模板数据到 GPU (一次性调用,角色加载时)
|
|
80
|
-
* @param templateData FLAME 模板数据
|
|
81
|
-
* @param shapeParams Shape 参数 [300]
|
|
82
|
-
* @param activeShapeParams 活跃shape参数(零参数过滤优化,可选)
|
|
83
|
-
*/
|
|
84
|
-
loadFLAMETemplateData(templateData: FLAMETemplateData, shapeParams: Float32Array, activeShapeParams?: ActiveShapeParams): void;
|
|
85
|
-
/**
|
|
86
|
-
* 🆕 更新 FLAME 帧参数 (每帧调用)
|
|
87
|
-
* @param frameParams FLAME 帧参数
|
|
88
|
-
*/
|
|
89
|
-
updateFLAMEFrameParams(frameParams: FLAMEFrameParams): void;
|
|
90
|
-
/**
|
|
91
|
-
* 🆕 获取是否使用 GPU Transform 路径
|
|
92
|
-
*/
|
|
93
|
-
getUseGPUTransform(): boolean;
|
|
94
|
-
/**
|
|
95
|
-
* 🆕 获取是否使用 GPU FLAME 路径
|
|
96
|
-
*/
|
|
97
|
-
getUseGPUFLAME(): boolean;
|
|
98
|
-
/**
|
|
99
|
-
* 🆕 使用Face Geometry渲染 (GPU Transform优化路径)
|
|
100
|
-
* 数据流: Face Geometry → GPU Transform → Render
|
|
101
|
-
*
|
|
102
|
-
* 支持两种模式:
|
|
103
|
-
* 1. CPU FLAME 路径:传入 faceGeometryData(从 CPU 计算)
|
|
104
|
-
* 2. GPU FLAME 路径:传入 frameParams(在 GPU 上计算 FLAME)
|
|
105
|
-
*/
|
|
106
|
-
renderWithFaceGeometry(faceGeometryDataOrFrameParams: Float32Array | FLAMEFrameParams, viewMatrix: Float32Array, projectionMatrix: Float32Array, screenSize: [number, number], transform?: Transform): Promise<void>;
|
|
107
59
|
/**
|
|
108
60
|
* 渲染一帧
|
|
109
61
|
*/
|
|
110
62
|
render(viewMatrix: Float32Array, projectionMatrix: Float32Array, screenSize: [number, number], transform?: Transform): void;
|
|
111
|
-
/**
|
|
112
|
-
* 🆕 渲染逻辑(提取为独立方法,供Transform和传统路径共用)
|
|
113
|
-
*/
|
|
114
|
-
private renderWithCommandEncoder;
|
|
115
63
|
/**
|
|
116
64
|
* 将 render texture 绘制到屏幕(应用 transform)
|
|
117
65
|
*/
|
|
@@ -124,11 +72,6 @@ export declare class WebGPURenderer implements I3DGSRenderer {
|
|
|
124
72
|
* 更新背景颜色
|
|
125
73
|
*/
|
|
126
74
|
updateBackgroundColor(backgroundColor: [number, number, number, number]): void;
|
|
127
|
-
/**
|
|
128
|
-
* 🔍 关键修复:从GPU读取transform后的positions,进行深度排序,更新sortIndexBuffer
|
|
129
|
-
* 这解决了第一帧GPU路径渲染异常的问题(未排序导致渲染顺序错误)
|
|
130
|
-
*/
|
|
131
|
-
private updateSortIndexFromGPU;
|
|
132
75
|
/**
|
|
133
76
|
* 清理资源
|
|
134
77
|
*/
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Animation Interpolation Utilities (SDK)
|
|
3
3
|
* Layered interpolation with different timing for each facial component
|
|
4
|
-
* Aligned with app implementation and iOS behavior
|
|
4
|
+
* Aligned with app implementation and iOS/Android behavior
|
|
5
|
+
*
|
|
6
|
+
* 贝塞尔曲线和时间缩放配置与 Android FlameFrameData.kt 保持一致
|
|
5
7
|
*/
|
|
6
8
|
export {};
|
|
@@ -74,53 +74,4 @@ export declare class AvatarCoreAdapter {
|
|
|
74
74
|
*/
|
|
75
75
|
releaseCurrentCharacter(): void;
|
|
76
76
|
load3DGSData(_original3DGSPoints: any, _binding: any, _flameFaces: any): Promise<boolean>;
|
|
77
|
-
/**
|
|
78
|
-
* 🆕 GPU 路径: 计算帧并返回 Face Geometry 数据
|
|
79
|
-
*/
|
|
80
|
-
computeFrameAsFaceGeometry(params?: {
|
|
81
|
-
frameIndex?: number;
|
|
82
|
-
characterId?: string;
|
|
83
|
-
}): Promise<Float32Array | null>;
|
|
84
|
-
/**
|
|
85
|
-
* 🆕 获取原始3DGS点数据 (一次性调用)
|
|
86
|
-
*/
|
|
87
|
-
getOriginalSplatsData(): Promise<{
|
|
88
|
-
data: Float32Array;
|
|
89
|
-
count: number;
|
|
90
|
-
} | null>;
|
|
91
|
-
/**
|
|
92
|
-
* 🆕 获取角色 Shape 参数
|
|
93
|
-
*/
|
|
94
|
-
getCharacterShapeParams(characterId?: string): Promise<{
|
|
95
|
-
params: number[];
|
|
96
|
-
} | null>;
|
|
97
|
-
/**
|
|
98
|
-
* 🆕 获取 FLAME 模板数据(用于 GPU FLAME Pipeline)
|
|
99
|
-
*/
|
|
100
|
-
getFLAMETemplateData(characterId?: string): Promise<FLAMETemplateData | null>;
|
|
101
|
-
}
|
|
102
|
-
export interface FLAMETemplateData {
|
|
103
|
-
vTemplate: Float32Array;
|
|
104
|
-
vertexCount: number;
|
|
105
|
-
shapedirs: Float32Array;
|
|
106
|
-
shapeParamCount: number;
|
|
107
|
-
posedirs: Float32Array;
|
|
108
|
-
poseParamCount: number;
|
|
109
|
-
jRegressor: Float32Array;
|
|
110
|
-
jointCount: number;
|
|
111
|
-
lbsWeights: Float32Array;
|
|
112
|
-
parents: Int32Array;
|
|
113
|
-
faces: Uint32Array;
|
|
114
|
-
faceCount: number;
|
|
115
|
-
staticOffset: Float32Array | null;
|
|
116
|
-
staticOffsetCount: number;
|
|
117
|
-
}
|
|
118
|
-
export interface FLAMEIntermediateResults {
|
|
119
|
-
vShaped: Float32Array | null;
|
|
120
|
-
vPosed: Float32Array | null;
|
|
121
|
-
joints: Float32Array | null;
|
|
122
|
-
jointTransforms: Float32Array | null;
|
|
123
|
-
vDeformed: Float32Array | null;
|
|
124
|
-
vertexCount: number;
|
|
125
|
-
jointCount: number;
|
|
126
77
|
}
|
|
@@ -108,19 +108,6 @@ export declare class AvatarCoreMemoryManager {
|
|
|
108
108
|
* ⚠️ 使用 getValue 逐个读取,避免动态内存的 HEAPF32 detachment 问题
|
|
109
109
|
*/
|
|
110
110
|
readSplatPointFlatArray(arrayPtr: number): Float32Array | null;
|
|
111
|
-
/**
|
|
112
|
-
* 🆕 读取 AvatarFaceGeometryArray 结构体数据 (WebGPU优化路径)
|
|
113
|
-
* 每个Face Geometry: center[3] + scale + quat[4] = 8 floats
|
|
114
|
-
*/
|
|
115
|
-
readFaceGeometryArray(arrayPtr: number): Float32Array | null;
|
|
116
|
-
/**
|
|
117
|
-
* 🆕 读取 AvatarOriginalSplatArray 结构体数据 (WebGPU优化路径)
|
|
118
|
-
* 每个Original Splat: 15 floats + 1 int32 = 64 bytes
|
|
119
|
-
*/
|
|
120
|
-
readOriginalSplatArray(arrayPtr: number): {
|
|
121
|
-
data: Float32Array;
|
|
122
|
-
count: number;
|
|
123
|
-
} | null;
|
|
124
111
|
/**
|
|
125
112
|
* 读取AvatarMeshData结构体数据
|
|
126
113
|
*/
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatialwalk/avatarkit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
5
|
-
"packageManager": "pnpm@10.18.2",
|
|
4
|
+
"version": "1.0.0-beta.78",
|
|
6
5
|
"description": "AvatarKit SDK - 3D Gaussian Splatting Avatar Rendering SDK",
|
|
7
6
|
"author": "AvatarKit Team",
|
|
8
7
|
"license": "MIT",
|
|
@@ -38,17 +37,6 @@
|
|
|
38
37
|
"vite.js",
|
|
39
38
|
"vite.d.ts"
|
|
40
39
|
],
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "SDK_BUILD=true vite build --mode library && npm run build:vite-plugin",
|
|
43
|
-
"build:vite-plugin": "tsc vite.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
44
|
-
"dev": "vite build --mode library --watch",
|
|
45
|
-
"clean": "rm -rf dist",
|
|
46
|
-
"typecheck": "tsc --noEmit",
|
|
47
|
-
"test": "cd tests && pnpm test",
|
|
48
|
-
"test:watch": "cd tests && pnpm run test:watch",
|
|
49
|
-
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
50
|
-
"test:perf": "cd tests && pnpm run test:perf"
|
|
51
|
-
},
|
|
52
40
|
"peerDependencies": {
|
|
53
41
|
"@webgpu/types": "*",
|
|
54
42
|
"vite": "^5.0.0"
|
|
@@ -66,5 +54,16 @@
|
|
|
66
54
|
"typescript": "^5.0.0",
|
|
67
55
|
"vite": "^5.0.0",
|
|
68
56
|
"vite-plugin-dts": "^4.5.4"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "SDK_BUILD=true vite build --mode library && npm run build:vite-plugin",
|
|
60
|
+
"build:vite-plugin": "tsc vite.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
61
|
+
"dev": "vite build --mode library --watch",
|
|
62
|
+
"clean": "rm -rf dist",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"test": "cd tests && pnpm test",
|
|
65
|
+
"test:watch": "cd tests && pnpm run test:watch",
|
|
66
|
+
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
67
|
+
"test:perf": "cd tests && pnpm run test:perf"
|
|
69
68
|
}
|
|
70
|
-
}
|
|
69
|
+
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FLAME GPU Buffers 管理类
|
|
3
|
-
*
|
|
4
|
-
* 管理所有 FLAME 模板数据的 GPU 缓冲区
|
|
5
|
-
* - 模板数据在初始化时一次性上传 (~31MB)
|
|
6
|
-
* - 每帧参数通过 uniform buffer 更新 (460 bytes)
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* FLAME 模板数据结构
|
|
10
|
-
*/
|
|
11
|
-
export interface FLAMETemplateData {
|
|
12
|
-
vTemplate: Float32Array;
|
|
13
|
-
vertexCount: number;
|
|
14
|
-
shapedirs: Float32Array;
|
|
15
|
-
shapeParamCount: number;
|
|
16
|
-
posedirs: Float32Array;
|
|
17
|
-
poseParamCount: number;
|
|
18
|
-
jRegressor: Float32Array;
|
|
19
|
-
jointCount: number;
|
|
20
|
-
lbsWeights: Float32Array;
|
|
21
|
-
parents: Int32Array;
|
|
22
|
-
faces: Uint32Array;
|
|
23
|
-
faceCount: number;
|
|
24
|
-
staticOffset: Float32Array | null;
|
|
25
|
-
staticOffsetCount: number;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* 🚀 活跃Shape参数(零参数过滤优化)
|
|
29
|
-
*/
|
|
30
|
-
export interface ActiveShapeParams {
|
|
31
|
-
activeIndices: Uint32Array;
|
|
32
|
-
activeValues: Float32Array;
|
|
33
|
-
count: number;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* FLAME 帧参数 (从动画中获取)
|
|
37
|
-
* 🚀 优化: 移除 shapeParams (静态数据,只需上传一次)
|
|
38
|
-
*/
|
|
39
|
-
export interface FLAMEFrameParams {
|
|
40
|
-
exprParams: Float32Array;
|
|
41
|
-
rotation: Float32Array;
|
|
42
|
-
translation: Float32Array;
|
|
43
|
-
neckPose: Float32Array;
|
|
44
|
-
jawPose: Float32Array;
|
|
45
|
-
eyesPose: Float32Array;
|
|
46
|
-
eyelid: Float32Array;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* GPU Buffer 集合
|
|
50
|
-
*/
|
|
51
|
-
export interface FLAMEGPUBufferSet {
|
|
52
|
-
vTemplate: GPUBuffer;
|
|
53
|
-
shapedirs: GPUBuffer;
|
|
54
|
-
posedirs: GPUBuffer;
|
|
55
|
-
jRegressor: GPUBuffer;
|
|
56
|
-
lbsWeights: GPUBuffer;
|
|
57
|
-
parents: GPUBuffer;
|
|
58
|
-
faces: GPUBuffer;
|
|
59
|
-
staticOffset: GPUBuffer | null;
|
|
60
|
-
activeShapeIndices: GPUBuffer;
|
|
61
|
-
activeShapeValues: GPUBuffer;
|
|
62
|
-
frameParams: GPUBuffer;
|
|
63
|
-
metadata: GPUBuffer;
|
|
64
|
-
}
|
|
65
|
-
export declare class FLAMEGPUBuffers {
|
|
66
|
-
private device;
|
|
67
|
-
private buffers;
|
|
68
|
-
private vertexCount;
|
|
69
|
-
private faceCount;
|
|
70
|
-
private jointCount;
|
|
71
|
-
private shapeParamCount;
|
|
72
|
-
private poseParamCount;
|
|
73
|
-
private staticOffsetCount;
|
|
74
|
-
private activeShapeCount;
|
|
75
|
-
private paramDataCache;
|
|
76
|
-
/**
|
|
77
|
-
* 初始化 GPU 缓冲区并上传模板数据
|
|
78
|
-
* 🚀 优化: 需要传入 characterHandle 以获取静态 shape parameters
|
|
79
|
-
* @param activeShapeParams 活跃shape参数(零参数过滤优化,可选)
|
|
80
|
-
*/
|
|
81
|
-
initialize(device: GPUDevice, templateData: FLAMETemplateData, _shapeParams: Float32Array, activeShapeParams?: ActiveShapeParams): void;
|
|
82
|
-
/**
|
|
83
|
-
* 创建 Storage Buffer 并上传数据
|
|
84
|
-
*/
|
|
85
|
-
private createStorageBuffer;
|
|
86
|
-
/**
|
|
87
|
-
* 创建帧参数 Uniform Buffer
|
|
88
|
-
* 🚀 优化: 移除 shapeParams,减小 70% 大小
|
|
89
|
-
*
|
|
90
|
-
* Layout (std140):
|
|
91
|
-
* - exprParams: vec4[25] (100 floats, padded)
|
|
92
|
-
* - rotation: vec4 (3 floats + padding)
|
|
93
|
-
* - translation: vec4 (3 floats + padding)
|
|
94
|
-
* - neckPose: vec4 (3 floats + padding)
|
|
95
|
-
* - jawPose: vec4 (3 floats + padding)
|
|
96
|
-
* - eyesPose: vec4[2] (6 floats, split into 2 vec4)
|
|
97
|
-
* - eyelid: vec4 (2 floats + padding)
|
|
98
|
-
*/
|
|
99
|
-
private createFrameParamsBuffer;
|
|
100
|
-
/**
|
|
101
|
-
* 创建元数据 Uniform Buffer
|
|
102
|
-
*
|
|
103
|
-
* Layout:
|
|
104
|
-
* - vertexCount: u32
|
|
105
|
-
* - faceCount: u32
|
|
106
|
-
* - jointCount: u32
|
|
107
|
-
* - shapeParamCount: u32
|
|
108
|
-
* - poseParamCount: u32
|
|
109
|
-
* - staticOffsetCount: u32
|
|
110
|
-
* (padding to 256 bytes for alignment)
|
|
111
|
-
*/
|
|
112
|
-
private createMetadataBuffer;
|
|
113
|
-
/**
|
|
114
|
-
* 更新每帧参数
|
|
115
|
-
* 🚀 优化: 移除 shapeParams 打包,减少 70% 上传量
|
|
116
|
-
*/
|
|
117
|
-
updateFrameParams(params: FLAMEFrameParams): void;
|
|
118
|
-
/**
|
|
119
|
-
* 获取所有缓冲区
|
|
120
|
-
*/
|
|
121
|
-
getBuffers(): FLAMEGPUBufferSet;
|
|
122
|
-
/**
|
|
123
|
-
* 获取元数据
|
|
124
|
-
*/
|
|
125
|
-
getMetadata(): {
|
|
126
|
-
vertexCount: number;
|
|
127
|
-
faceCount: number;
|
|
128
|
-
jointCount: number;
|
|
129
|
-
shapeParamCount: number;
|
|
130
|
-
poseParamCount: number;
|
|
131
|
-
staticOffsetCount: number;
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* 清理资源
|
|
135
|
-
*/
|
|
136
|
-
destroy(): void;
|
|
137
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { FLAMEGPUBufferSet } from './flameGPUBuffers';
|
|
2
|
-
/**
|
|
3
|
-
* FLAME Pipeline 输出
|
|
4
|
-
*/
|
|
5
|
-
export interface FLAMEPipelineOutput {
|
|
6
|
-
faceGeometries: GPUBuffer;
|
|
7
|
-
faceCount: number;
|
|
8
|
-
}
|
|
9
|
-
export declare class FLAMEPipeline {
|
|
10
|
-
private device;
|
|
11
|
-
private buffers;
|
|
12
|
-
private vertexCount;
|
|
13
|
-
private faceCount;
|
|
14
|
-
private jointCount;
|
|
15
|
-
private shapeBlendPipeline;
|
|
16
|
-
private poseDeformPipeline;
|
|
17
|
-
private jointRegressPipeline;
|
|
18
|
-
private fkPipeline;
|
|
19
|
-
private lbsPipeline;
|
|
20
|
-
private faceGeometryPipeline;
|
|
21
|
-
private shapeBlendParamsBindGroup;
|
|
22
|
-
private poseDeformParamsBindGroup;
|
|
23
|
-
private jointRegressMetadataBindGroup;
|
|
24
|
-
private fkParamsBindGroup;
|
|
25
|
-
private lbsMetadataBindGroup;
|
|
26
|
-
private shapeBlendBindGroup;
|
|
27
|
-
private poseDeformBindGroup;
|
|
28
|
-
private jointRegressBindGroup;
|
|
29
|
-
private fkBindGroup;
|
|
30
|
-
private lbsBindGroup;
|
|
31
|
-
private faceGeometryParamsBindGroup;
|
|
32
|
-
private faceGeometryBindGroup;
|
|
33
|
-
private vShapedBuffer;
|
|
34
|
-
private vPosedBuffer;
|
|
35
|
-
private jointsBuffer;
|
|
36
|
-
private jointTransformsBuffer;
|
|
37
|
-
private vDeformedBuffer;
|
|
38
|
-
private faceGeometriesBuffer;
|
|
39
|
-
constructor(device: GPUDevice, buffers: FLAMEGPUBufferSet, vertexCount: number, faceCount: number, jointCount: number);
|
|
40
|
-
private initialize;
|
|
41
|
-
/**
|
|
42
|
-
* 创建中间缓冲区
|
|
43
|
-
*/
|
|
44
|
-
private createIntermediateBuffers;
|
|
45
|
-
/**
|
|
46
|
-
* 清零所有中间缓冲区 (避免未初始化的垃圾数据)
|
|
47
|
-
* 🔧 关键修复: LBS shader 如果某些顶点权重全为0,会跳过不写入,导致保留垃圾数据
|
|
48
|
-
*/
|
|
49
|
-
private clearIntermediateBuffers;
|
|
50
|
-
/**
|
|
51
|
-
* 创建计算管线
|
|
52
|
-
*/
|
|
53
|
-
private createComputePipelines;
|
|
54
|
-
/**
|
|
55
|
-
* 创建单个计算管线
|
|
56
|
-
*/
|
|
57
|
-
private createPipeline;
|
|
58
|
-
/**
|
|
59
|
-
* 创建绑定组
|
|
60
|
-
*/
|
|
61
|
-
private createBindGroups;
|
|
62
|
-
/**
|
|
63
|
-
* 计算一帧 FLAME (主入口)
|
|
64
|
-
* 🚀 优化: 拆分为6个独立pass,支持详细的GPU profiling
|
|
65
|
-
*/
|
|
66
|
-
compute(commandEncoder: GPUCommandEncoder): FLAMEPipelineOutput;
|
|
67
|
-
/**
|
|
68
|
-
* 清理资源
|
|
69
|
-
*/
|
|
70
|
-
destroy(): void;
|
|
71
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GPU Radix Sort - FFX 风格实现
|
|
3
|
-
*
|
|
4
|
-
* 核心思想:不用 atomicAdd 来决定写入位置,而是通过分层 Prefix Sum 预计算
|
|
5
|
-
*
|
|
6
|
-
* 每个 Pass (处理 8-bit,共 4 个 pass):
|
|
7
|
-
* 1. Histogram: 每个 workgroup 统计局部 histogram
|
|
8
|
-
* 2. Scan: 对所有 workgroup 的 histogram 做 prefix sum
|
|
9
|
-
* 3. Scatter: 根据预计算的位置写入
|
|
10
|
-
*/
|
|
11
|
-
export interface GPURadixSortOptions {
|
|
12
|
-
device: GPUDevice;
|
|
13
|
-
maxSplatCount: number;
|
|
14
|
-
}
|
|
15
|
-
export declare class GPURadixSort {
|
|
16
|
-
private device;
|
|
17
|
-
private maxSplatCount;
|
|
18
|
-
private paddedCount;
|
|
19
|
-
private numWorkgroups;
|
|
20
|
-
private depthPipeline;
|
|
21
|
-
private histogramPipeline;
|
|
22
|
-
private scanPipeline;
|
|
23
|
-
private addBlockSumsPipeline;
|
|
24
|
-
private scatterPipeline;
|
|
25
|
-
private reversePipeline;
|
|
26
|
-
private uniformBuffer;
|
|
27
|
-
private paramsBuffer;
|
|
28
|
-
private scanParamsBuffer;
|
|
29
|
-
private keysBuffer0;
|
|
30
|
-
private keysBuffer1;
|
|
31
|
-
private valuesBuffer0;
|
|
32
|
-
private valuesBuffer1;
|
|
33
|
-
private histogramBuffer;
|
|
34
|
-
private blockSumsBuffer;
|
|
35
|
-
private blockSumsBuffer2;
|
|
36
|
-
private positionsBuffer;
|
|
37
|
-
constructor(options: GPURadixSortOptions);
|
|
38
|
-
private initialize;
|
|
39
|
-
setPositionsBuffer(buffer: GPUBuffer): void;
|
|
40
|
-
sortAsync(viewMatrix: Float32Array, splatCount: number): Promise<GPUBuffer>;
|
|
41
|
-
private runReversePass;
|
|
42
|
-
private runDepthPass;
|
|
43
|
-
private runHistogramPass;
|
|
44
|
-
private runPrefixSum;
|
|
45
|
-
private runScatterPass;
|
|
46
|
-
destroy(): void;
|
|
47
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebGPU Transform Pipeline
|
|
3
|
-
*
|
|
4
|
-
* 管理3DGS Transform的GPU计算:
|
|
5
|
-
* - Original Splats Buffer (一次性上传)
|
|
6
|
-
* - Face Geometry Buffer (每帧更新)
|
|
7
|
-
* - Transformed Output Buffer (GPU输出)
|
|
8
|
-
*/
|
|
9
|
-
export declare class TransformPipeline {
|
|
10
|
-
private device;
|
|
11
|
-
private computePipeline;
|
|
12
|
-
private bindGroup;
|
|
13
|
-
private originalSplatsBuffer;
|
|
14
|
-
private faceGeometryBuffer;
|
|
15
|
-
private transformedOutputBuffer;
|
|
16
|
-
private positionsOutputBuffer;
|
|
17
|
-
private viewMatrixBuffer;
|
|
18
|
-
private depthsOutputBuffer;
|
|
19
|
-
private splatCount;
|
|
20
|
-
private faceCount;
|
|
21
|
-
private usesExternalFaceGeometryBuffer;
|
|
22
|
-
constructor(device: GPUDevice);
|
|
23
|
-
/**
|
|
24
|
-
* 初始化Pipeline
|
|
25
|
-
*/
|
|
26
|
-
initialize(): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* 上传Original Splats (一次性调用)
|
|
29
|
-
* @param originalSplatsData Float32Array, 每个splat 16 floats (64 bytes)
|
|
30
|
-
* @param splatCount splat数量
|
|
31
|
-
*/
|
|
32
|
-
uploadOriginalSplats(originalSplatsData: Float32Array, splatCount: number): void;
|
|
33
|
-
/**
|
|
34
|
-
* 🆕 设置外部 GPU FaceGeometry Buffer(GPU FLAME 路径)
|
|
35
|
-
* @param externalBuffer 外部 GPU buffer(来自 FLAME Pipeline 的 faceGeometriesBuffer)
|
|
36
|
-
* @param faceCount face 数量
|
|
37
|
-
*/
|
|
38
|
-
setFaceGeometryBufferFromGPU(externalBuffer: GPUBuffer, faceCount: number): void;
|
|
39
|
-
/**
|
|
40
|
-
* 更新Face Geometry Buffer (每帧调用) - CPU 路径
|
|
41
|
-
* @param faceGeometryData Float32Array, 每个face 8 floats (32 bytes)
|
|
42
|
-
*/
|
|
43
|
-
updateFaceGeometry(faceGeometryData: Float32Array): void;
|
|
44
|
-
/**
|
|
45
|
-
* 执行Transform计算 (在给定的command encoder中)
|
|
46
|
-
* @param commandEncoder 外部command encoder (与render共享以保证顺序)
|
|
47
|
-
*/
|
|
48
|
-
executeInEncoder(commandEncoder: GPUCommandEncoder): void;
|
|
49
|
-
/**
|
|
50
|
-
* 获取Transformed Output Buffer (供渲染器使用)
|
|
51
|
-
*/
|
|
52
|
-
getTransformedOutputBuffer(): GPUBuffer | null;
|
|
53
|
-
/**
|
|
54
|
-
* 🚀 获取Positions Output Buffer (供排序使用)
|
|
55
|
-
*/
|
|
56
|
-
getPositionsOutputBuffer(): GPUBuffer | null;
|
|
57
|
-
/**
|
|
58
|
-
* 🆕 获取Depths Output Buffer (供GPU排序使用)
|
|
59
|
-
*/
|
|
60
|
-
getDepthsOutputBuffer(): GPUBuffer | null;
|
|
61
|
-
/**
|
|
62
|
-
* 🆕 更新View Matrix (每帧调用)
|
|
63
|
-
* @param viewMatrix 4x4 view matrix
|
|
64
|
-
*/
|
|
65
|
-
updateViewMatrix(viewMatrix: Float32Array): void;
|
|
66
|
-
/**
|
|
67
|
-
* 获取Splat数量
|
|
68
|
-
*/
|
|
69
|
-
getSplatCount(): number;
|
|
70
|
-
/**
|
|
71
|
-
* 创建Transformed Output Buffer
|
|
72
|
-
* 格式: position[3] + color[4] + covariance[6] = 13 floats = 52 bytes
|
|
73
|
-
*/
|
|
74
|
-
private createTransformedOutputBuffer;
|
|
75
|
-
/**
|
|
76
|
-
* 🚀 创建Positions Output Buffer (用于排序)
|
|
77
|
-
* 格式: position[3] = 3 floats = 12 bytes per splat
|
|
78
|
-
*/
|
|
79
|
-
private createPositionsOutputBuffer;
|
|
80
|
-
/**
|
|
81
|
-
* 🆕 创建View Matrix Buffer
|
|
82
|
-
*/
|
|
83
|
-
private createViewMatrixBuffer;
|
|
84
|
-
/**
|
|
85
|
-
* 🆕 创建Depths Output Buffer (用于GPU排序)
|
|
86
|
-
* 格式: depth (Uint32) = 4 bytes per splat
|
|
87
|
-
*/
|
|
88
|
-
private createDepthsOutputBuffer;
|
|
89
|
-
/**
|
|
90
|
-
* 创建Bind Group
|
|
91
|
-
*/
|
|
92
|
-
private createBindGroup;
|
|
93
|
-
/**
|
|
94
|
-
* 清理资源
|
|
95
|
-
*/
|
|
96
|
-
destroy(): void;
|
|
97
|
-
}
|