解决用Three.js实现嘴型和语音同步时只能播放部分部位的问题 Three.js同时渲染播放多个组件变形动画的方法

前言

参考这篇文章ThreeJS+ChatGPT 实现前端3D数字人AI互动,前面搭后端、训练模型组内小伙伴都没有什么问题,到前端的时候,脸部就出问题了。看我是怎么解决的。

好文章啊,可惜百度前几个都找不到,o(╥﹏╥)o

问题情况

展示到页面上,是这么个效果(模型动作有夸大部分):

这样的:

《眉飞色舞》

这样的:

《流连赏目》

这样:

《目无全牛》

这样:

眼角:我不感动

以及这样:

嘴巴:该配合你演出的我演视而不见

很明显,这整个脸就没打算一起好好动。

解决方法

原因

出现这个问题,是因为你的网格分开了,但Threejs的混合器AnimationMixer创建一次只能混合一个网格Mesh。

这样子写,一次就只能混合其中一个Mesh:

...  // 省略了很多地方,只列出了关键的细节
loader.load('path/to/your/model.gltf', function(gltf) {
    const model = gltf.scene;
    scene.add(model);

    model.traverse(o => {
        ...
        if(o.isMesh) {
            ...
            if (o.morphTargetDictionary) {
                // 这里混合器只混合了一个mesh
                const mixer = new THREE.AnimationMixer(o);  
                ...
            }
        }
    }
}

...

const clip = getAnimationClip(msg);  // 调用参考文章中得到动画的方法

let action = mixer.clipAction(clip);  // 此时此刻也只有一个mixer的动画
action.play();  // 播放动画

function animate() {
    mixer.update(0.016); // 更新动画混合器

    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

其实得一个Mesh一个混合器,最后把所有混合器都播放好。这样就能实现脸部的协调啦~

代码示例

const mixers = []  // 先准备好一个数组,存放mixer们

...

loader.load('path/to/your/model.gltf', function(gltf) {
    const model = gltf.scene;
    scene.add(model);

    model.traverse(o => {
        ...
        if(o.isMesh) {
            ...
            if (o.morphTargetDictionary) {
                // 不再只混合一个了
                // const mixer = new THREE.AnimationMixer(o); 

                // 这里把混合了其中一个mesh的混合器给push进数组了
                mixers.push(new THREE.AnimationMixer(o));
                ...
            }
        }
    }
}

...

const clip = getAnimationClip(msg);  // 调用参考文章中得到动画切片帧的方法

// 播放动画也不能只用一个的了
// let action = mixer.clipAction(clip);
// action.play();

for(let i = 0; i < mixers.length; i++) {
    let action = mixers[i].clipAction(clip); //所有mixer都生成对应的动作
    action.play();  // 动画全都给播放了
}


function animate() {
    // 这里也记得都要播放哦
    // mixer.update(0.016); 
    
    for(let i = 0; i < mixers.length; i++) {
        mixers[i].update(0.016);  // 更新全部动画混合器
    }

    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

效果展示

当当当当!~

不好意思,搞错了,再来:

效果还不错的赶脚~

后记

网上这方面的资料太少了,这次真就是自己在脑子里构思一个个方案,做出一小步一小步的修改,最终给我试出来是这个毛病了……不容易啊不容易(o(╥﹏╥)o)

希望本文能给其他用Threejs的小伙伴带来帮助,不要放下你敲代码的热情,总有前人在为你们探路中~(✿◠‿◠)

参考

ThreeJS+ChatGPT 实现前端3D数字人AI互动

(偷偷告诉你,这种开源社区大佬的实现项目,不是一般人能随便搜到的哦)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/711593.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++提高编程-05】----C++之Deque容器实战

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

ubuntu vnc

如何在Ubuntu 18.04安装VNC | myfreax sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt install tigervnc-standalone-server tigervnc-common vncserver sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt ins…

用Python向Word文档添加页眉和页脚

用Python向Word文档添加页眉和页脚 添加页眉和页脚效果代码 添加页眉和页脚 在本文中&#xff0c;我们将用python向文档中添加页眉和页脚。 效果 添加前的文档&#xff1a; 添加页眉和页脚后&#xff1a; 代码 from docx import Documentdef add_header_footer(doc_path…

【数据结构】——常见排序

文章目录 一、 冒泡排序二、 选择排序三、插入排序四、 快速排序1. hoare版本2. 优化版本3. 前后指针法4. 非递归版本 五、 堆排序六、 希尔排序七、 归并排序1. 递归版本2. 非递归版本 八、 计数排序 在开始之前先准备一个交换数据的函数&#xff0c;排序会经常用到 //交换位置…

牛客热题:兑换零钱(一)

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;兑换零钱(一)题目链接方法一&am…

解读ROS功能包模块的步骤

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言解读ROS功能包模块的步骤前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 推荐开发经验及方法博客专栏: [https:/…

抢占人工智能行业红利,前阿里巴巴产品专家带你15天入门AI产品经理

前言 当互联网行业巨头纷纷布局人工智能&#xff0c;国家将人工智能上升为国家战略&#xff0c;藤校核心课程涉足人工智能…人工智能领域蕴含着巨大潜力&#xff0c;早已成为业内共识。 面对极大的行业空缺&#xff0c;不少人都希望能抢占行业红利期&#xff0c;进入AI领域。…

软件工程实务:软件产品

目录 1、软件产品的基本概念 2、软件工程是什么&#xff1f; 为什么产生软件工程? 软件工程是做什么的? 3、定制软件和软件产品的工程比较 4 、软件产品的运行模式 5、软件产品开发时需要考虑的两个基本技术因素 6、产品愿景 7、软件产品管理 8、产品原型设计 9、小结…

如何区分人工智能生成的图像与真实照片(上)

随着最先进扩散模型&#xff08;如Midjourney、Stable Diffusion和Firefly&#xff09;生成的图像具有高度的逼真度&#xff0c;未经训练的我们很难区分真实照片和AI生成的图像。为了解决这个问题&#xff0c;这份指南&#xff0c;帮助读者培养更批判的眼光&#xff0c;识别AI生…

056、PyCharm 快速代码重构的方法

在实际的编程过程中&#xff0c;如果有一段代码需要在多个地方重复使用&#xff0c;我们应该将这段代码封装成一个函数。这样可以提高代码的可重用性和可维护性。 在PyCharm编辑器里&#xff0c;可以使用以下操作对代码块进行快速的重构。 &#xff08;1&#xff09;、选中一…

【数据分析】推断统计学及Python实现

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(五)质量设计方法与工具

第五节 质量设计方法与工具 1 任 务 分 解 法 1.1 概念 任务分解法&#xff0c;又称工作分解结构 (Work Breakdown Structure, 简 称 WBS) 。WBS 指以可交付成果为 导向&#xff0c;对项目团队为实现项目目标并完成规定的可交付成果而执行的工作所进行的层次分解。W…

mysql 8 创建用户,并对用户授权

创建用户&#xff1a; 对MySQL创建新用户。命令如下&#xff1a; create user devuser% identified by 123456; 授予权限 grant all privileges on joolun_ry.* to devuser% with grant option; 参数说明&#xff1a; joolun_ry&#xff1a;表明对那个库进行授权&#xf…

C语言概述与历史

引言 C语言是一门历史悠久且影响深远的编程语言。它不仅为后继的许多编程语言奠定了基础&#xff0c;同时因其高效性和灵活性在系统编程和嵌入式开发领域得到了广泛应用。本篇文章将全面介绍C语言的起源与发展、设计目标与理念&#xff0c;以及C语言的标准演化历程&#xff0c;…

解决MyBatis获取刚插入数据的ID值

解决MyBatis获取刚插入数据的ID值 Mybatis获取刚插入数据的ID值有很多解决方法&#xff0c;目前采用以下方式进行获取。 添加完数据后直接返回刚添加数据的id // UserDao.java public static void addUser() throws Exception{InputStream resourceAsStream Resources.getR…

学习资料分析

学习资料分析 速算运算 √截位直除分数比较等比修正其他速算方法基期与现期基本概念求基期求现期增长率与增长量增长相关统计术语求一般增长率比较一般增长率增长量比重比重相关公式求比重平均数倍数间隔增长乘积增长率年增长率混合增长率资料分析:主要测查报考者对文字、数字…

N3 中文文本分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 前面学习了相关自然语言编码&#xff0c;这周进行相关实战 导入依赖库和设置设备 import torch import torch.nn as nn import torchvision fro…

湘潭大学信息与网络安全复习笔记2(总览)

前面的实验和作业反正已经结束了&#xff0c;现在就是集中火力把剩下的内容复习一遍&#xff0c;这一篇博客的内容主要是参考教学大纲和教学日历 文章目录 教学日历教学大纲 教学日历 总共 12 次课&#xff0c;第一次课是概述&#xff0c;第二次和第三次课是密码学基础&#x…

Android入门第68天-自动更新/升级怎么做(生产级实例)

开篇 今天我们进入第68讲。 在第60天左右其实很多同学们已经进入了APP应用开发了,因为60天内容足以让大家踏上正实的Android开发生涯。 随着开发的深入,我们发觉日常工作中无非就是一些组件的嵌套、合理应用。当代码迭代、功能迭代越来越频繁后我们面临着另一个问题,即:…

Vue3 生命周期函数及其与Vue2的对比总结

Vue3 继续保留了 Vue2 的生命周期钩子&#xff0c;但在 Composition API&#xff08;setup 函数&#xff09;中&#xff0c;它们被改为了一组导入函数。以下是它们的对比&#xff1a; Vue2 生命周期钩子和 Vue3 对应的生命周期函数&#xff1a; 在 Vue3 中&#xff0c;所有的…