1
This commit is contained in:
@ -24,11 +24,7 @@ class BlendShapeAnimator {
|
||||
this.deltaThreshold = typeof config.deltaThreshold === 'number'
|
||||
? config.deltaThreshold
|
||||
: 0.002; // Skip re-applying nearly identical values
|
||||
this.prewarmFrameCount = typeof config.prewarmFrameCount === 'number'
|
||||
? config.prewarmFrameCount
|
||||
: 30;
|
||||
this.lastFrameBlendShapes = {};
|
||||
this._hasPrewarmed = false;
|
||||
|
||||
// 空闲动画参数
|
||||
this.blinkParams = config.blinkParams || {
|
||||
@ -97,7 +93,6 @@ class BlendShapeAnimator {
|
||||
this.animationFrames = frames || [];
|
||||
this.animationShapeNames = this._collectAnimationShapeNames(this.animationFrames);
|
||||
this.lastFrameBlendShapes = {};
|
||||
// 不重置 _hasPrewarmed,因为全局预热只需要做一次
|
||||
}
|
||||
|
||||
appendAnimationFrames(frames) {
|
||||
@ -107,7 +102,6 @@ class BlendShapeAnimator {
|
||||
|
||||
this.animationFrames.push(...frames);
|
||||
const newNames = this._collectAnimationShapeNames(frames);
|
||||
// 不重置 _hasPrewarmed
|
||||
|
||||
if (newNames.length === 0) {
|
||||
return;
|
||||
@ -227,49 +221,6 @@ class BlendShapeAnimator {
|
||||
this.lastFrameBlendShapes = {};
|
||||
}
|
||||
|
||||
_prewarmAnimation() {
|
||||
// 同步预热已移除,改用异步预热
|
||||
this._hasPrewarmed = true;
|
||||
}
|
||||
|
||||
// 异步分帧预热 - 预热所有 morph targets,确保 GPU 真正渲染
|
||||
async prewarmAsync(scene) {
|
||||
if (!this.morphTargetAdapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取所有可用的 morph targets,而不只是当前动画用到的
|
||||
const allShapes = this.morphTargetAdapter.morphTargetCache
|
||||
? Object.keys(this.morphTargetAdapter.morphTargetCache)
|
||||
: this.animationShapeNames;
|
||||
|
||||
const shapes = allShapes.filter(
|
||||
name => !this.disabledShapesInAnimation.includes(name.toLowerCase())
|
||||
);
|
||||
|
||||
if (shapes.length === 0) return;
|
||||
|
||||
console.log(`异步预热 ${shapes.length} 个 morph targets...`);
|
||||
|
||||
// 用不同的值组合预热,触发所有可能的 shader 变体
|
||||
const testValues = [0.2, 0.5, 0.8, 1.0];
|
||||
for (const val of testValues) {
|
||||
shapes.forEach(name => this.morphTargetAdapter.setInfluence(name, val));
|
||||
if (scene) scene.render();
|
||||
await new Promise(r => requestAnimationFrame(r));
|
||||
}
|
||||
|
||||
// 重置并等待几帧确保稳定
|
||||
shapes.forEach(name => this.morphTargetAdapter.setInfluence(name, 0));
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (scene) scene.render();
|
||||
await new Promise(r => requestAnimationFrame(r));
|
||||
}
|
||||
|
||||
this._hasPrewarmed = true;
|
||||
console.log('异步预热完成');
|
||||
}
|
||||
|
||||
_primeFirstFrame() {
|
||||
if (!this.morphTargetAdapter || this.animationFrames.length === 0) {
|
||||
return;
|
||||
@ -297,24 +248,6 @@ class BlendShapeAnimator {
|
||||
}
|
||||
}
|
||||
|
||||
_touchAnimationShapes() {
|
||||
if (!this.morphTargetAdapter || !Array.isArray(this.animationShapeNames) || this.animationShapeNames.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const touchValue = Math.max(this.minBlendShapeValue * 1.2, 0.05);
|
||||
const touched = [];
|
||||
|
||||
this.animationShapeNames.forEach(name => {
|
||||
this.morphTargetAdapter.setInfluence(name, touchValue);
|
||||
touched.push(name);
|
||||
});
|
||||
|
||||
touched.forEach(name => {
|
||||
this.morphTargetAdapter.setInfluence(name, 0);
|
||||
});
|
||||
}
|
||||
|
||||
_scheduleAnimationStart() {
|
||||
// 只设置开始时间,动画由统一的 RAF 循环驱动
|
||||
this.animationStartTime = performance.now();
|
||||
|
||||
Reference in New Issue
Block a user