形态键预热

This commit is contained in:
yinsx
2025-12-29 11:22:51 +08:00
parent 6e61fd81b3
commit b56492f80f
7 changed files with 314 additions and 86 deletions

View File

@ -141,6 +141,29 @@ class BlendShapeAnimator {
// 注意:不停止眨眼,让眨眼继续运行
// 预演前10帧以避免首次播放卡顿
console.log('预演前10帧...');
const framesToPreview = Math.min(10, this.animationFrames.length);
for (let i = 0; i < framesToPreview; i++) {
const frame = this.animationFrames[i];
const blendShapes = frame?.blendShapes || {};
for (const key in blendShapes) {
if (this.disabledShapesInAnimation.includes(key.toLowerCase())) {
continue;
}
this.morphTargetAdapter.setInfluence(key, blendShapes[key] * this.blendShapeScale);
}
}
// 重置为0
for (let i = 0; i < framesToPreview; i++) {
const frame = this.animationFrames[i];
const blendShapes = frame?.blendShapes || {};
for (const key in blendShapes) {
this.morphTargetAdapter.setInfluence(key, 0);
}
}
console.log('预演完成');
this.stopAnimation(false);
this.isPlaying = true;
this.currentFrameIndex = 0;
@ -149,6 +172,7 @@ class BlendShapeAnimator {
this.streamingStallMs = 0;
this._animateFrame();
this.onStatusChange('info', '播放中...');
}
@ -197,7 +221,8 @@ class BlendShapeAnimator {
_animateFrame() {
if (!this.isPlaying) return;
const now = performance.now();
const frameStartTime = performance.now();
const now = frameStartTime;
if (this.streamingWaitStart !== null && this.animationFrames.length > this.currentFrameIndex + 1) {
this.streamingStallMs += now - this.streamingWaitStart;
this.streamingWaitStart = null;
@ -242,8 +267,11 @@ class BlendShapeAnimator {
? this.animationShapeNames
: Object.keys(currentBlendShapes);
let updateCount = 0;
const setInfluenceStart = performance.now();
for (const key of shapeNames) {
// 跳过禁用列表中的 blendshape让空闲动画继续控制它们
// 跳过禁用列表中的 blendshape,让空闲动画继续控制它们
if (this.disabledShapesInAnimation.includes(key.toLowerCase())) {
continue;
}
@ -254,10 +282,21 @@ class BlendShapeAnimator {
const scaledValue = interpolatedValue * this.blendShapeScale;
this.morphTargetAdapter.setInfluence(key, scaledValue);
updateCount++;
}
const setInfluenceTime = performance.now() - setInfluenceStart;
this.currentFrameIndex = targetFrameIndex;
// 性能监控前100帧
if (targetFrameIndex < 100) {
const totalFrameTime = performance.now() - frameStartTime;
if (totalFrameTime > 16.67) {
console.warn(`${targetFrameIndex}耗时${totalFrameTime.toFixed(2)}ms (setInfluence: ${setInfluenceTime.toFixed(2)}ms, 调用${updateCount}次)`);
}
}
// 更新当前句子显示
const sentenceIndex = currentFrame?.sentenceIndex ?? -1;
if (sentenceIndex !== this.currentSentenceIndex) {