如何让3D角色动起来

前言

先看看这张图,那是在2023年以ChatGPT为首的AI技术开始火爆互联网的时候,我们做过的一个AI技术应用场景探索,回头发现很多设想都已经在市面上实现并产品化了。那时我很想把虚拟小助手应用里面的智城IP小Z做出来,实现一个立体的、有动作的形象, 苦于当时能力没能投入。时隔1年多,AI能力又有了许多涌现,除了最初的语言大模型,AI在生成图像和生成3D模型方面有非常大的能力提升,甚至已经可以辅助把这个立体生活的角色形象实现,我觉得是时候动手了。

经过这几天的摸索,终于实现了在网页上展示小Z的3D形象,并控制它做出各种指定动作,下面我来有所侧重地分享整个工作流程。

实现思路

  1. 设计小Z的形象轮廓,提供正面、侧面、背面三视图
  2. 使用SD生成质感的角色图
  3. 角色建模,可以人工建模也可以AI辅助生成
  4. 模型骨骼绑定,在动作库挑选动作合并入模型
  5. 使用three.js调用模型

使用工具

工具 版本 说明
illustrator 2020 角色线稿绘制
StableDiffusion 简称SD,AI生图工具,可以根据线框图,生成立体的、有质感的角色图片
blender 4.2 角色建模,绑定骨骼,添加动作
autoRig 3.70 blender插件,用于自动绑定骨骼,生成姿态控制器
quad remesher 1.2 blender插件,模型的网格优化工具(非必须)
mixamo Adobe官方的3D角色动画工具网站,可以提供各种各样的角色姿态和动作
wander3D AI工具,1张图片生成高质量3D模型(非必须)
three.js 0.157 经典的前端3d引擎,用于加载和控制模型

具体步骤

  1. 设计小Z的形象轮廓,提供正面、侧面、背面三视图,设计的时候需要注意各个身体部件在后面的步骤里能够实现。这里我就踩了一个坑,小Z最初是形象一个章鱼腿,后来在建模的时候发现做成手办会站不稳,才在第二版改成了阿童木的靴子腿。

  2. 将正面图片导入StableDiffusion,使用插件ControlNet辅助生成质感的角色图,网上已经有很多教程了,这里碍于篇幅就不赘述,AI生图的诀窍就是要耐心、且不断调整提示词抽卡和局部重绘,最终达到理想的效果。

  3. 根据三视图对小Z角色进行建模,如果不会建模可以用Wander3D,本文的示例模型是我曾经的好同事刘睿博帮忙创建的,他还顺便帮我用3D打印机把模型打印出来了(他哭死,我真的),这里着重表扬他。

  4. 将模型导入blender,可以用quad remesher进行网格优化,再进行稍微的调整、UV帖图

  5. 贴图,最省事的做法是使用视角投影贴图。模型朝向正面,全选顶点后按U,选择"从视角投影",但是这样的话贴图会直接映射在正面和背面模型上,不适合会展示到背面的场景。拆分组件后各自UV贴图,虽然费时间,但产出的模型精细化程度高;需要注意的是组件接缝处如果面没没有封闭好,可能会因为做动作出现破面的问题,可以适当把关节对接处延长。

  6. 使用autoRig进行骨骼自动绑定,导出FBX格式的文件备用,这里看后面小技巧部分。

  7. 打开mixamo,上传FBX文件成功后,即可选择并下载各种姿态动作。我们只需要下载一个蒙皮的动作,其余的动作全部选择不带皮的就可以了,这样文件体积更小容易下载成功。

  8. 使用blender合并动作到一个模型上,并导出模型文件FBX或gltf,使用系统自带的3D查看器就可以看到动作被合成进来,具体教程可以看参考链接

  9. 使用three.js调用模型,核心操作就是加载模型和控制动作切换两个,源代码我放在这里了

    jsx 复制代码
    // 加载模型
    import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
    const loader = new FBXLoader();
    loader.load("../static/gltf/xiaoz.fbx", function ( object ) {
        const size = 0.05
        object.scale.set(size, size, size);
    		//
        const index = object.children.findIndex(v=>v.name=="Light")
        object.children.splice(index, 1)
    
        object.children.forEach(element => {
            const {material ,name } = element
            if(['Retopo_ball','Retopo_face'].includes(name)){
                const material = element.material
                material.transparent = false
            }
        });
    
        scene.add( object );
        createGUI(object, object.animations)
    } );
    
    function createGUI(model, animations) {
      const states = animations.map(v=>{
          return v.name
      });
    
      gui = new GUI();
      mixer = new THREE.AnimationMixer(model);
      actions = {};
    
      for (let i = 0; i < animations.length; i++) {
        const clip = animations[i];
        const action = mixer.clipAction(clip);
        actions[clip.name] = action;
      }
    
      const statesFolder = gui.addFolder("States");
      const clipCtrl = statesFolder.add(api, "state").options(states);
      clipCtrl.onChange(function () {
        fadeToAction(api.state, 0.5);
      });
      statesFolder.open();
      activeAction = actions[states[0]];
      activeAction.play();
    }
    
    /**
     * @description 切换动作
     * @param name {String} 动作名
     * @param duration {Number} 切换过渡时间
     */
    function fadeToAction(name, duration) {
      previousAction = activeAction;
      activeAction = actions[name];
    
      if (previousAction !== activeAction) {
        previousAction.fadeOut(duration);
      }
    
      activeAction
        .reset()
        .setEffectiveTimeScale(1)
        .setEffectiveWeight(1)
        .fadeIn(duration)
        .play();
    }
  10. 页面实现的效果如下图

小技巧

在绑定骨骼时如何创建镜像

  1. 选择想要复制镜像的骨骼,修改骨骼中各关节的命名,注意目前是在人体的右边,所以命名以R.开头,比如R.hand如下图所示。否则无法正常生成对称的骨骼。

  2. 在编辑模式下,再次选择骨骼,点击左上角"骨架 - 对称",即可直接生成镜像,且骨骼会自动以L.为开头命名

如何使用autoRig绑定骨骼

  1. 安装插件auto-rig-pro,选择所有模型相关Mesh,点击Auto-Rig Rro:Smart 折叠项,展开后点击 "Get Selected Objects"。此时将模型朝向正面,根据控制面板按钮提示选择模型的关键节点(Neck、Chin、Spine root等)后就能自动生成骨骼,调整好骨骼以适应当前的模型。

  2. 回到最初的Atuo-Rig Pro折叠项,点击Match To Ring,此时就会生成一堆姿态控制器

  3. 打开在"蒙皮"TAB,点击其中的"绑定"按钮,此时就会自动将骨骼与模型绑定。选中某个控制器,R可以控制旋转,G可以移动位置,S可以进行缩放,Alt+G可以重置位置移动,以此类推。

如何让模型表面更光滑有质感

  1. 使用blender,在物体模式下,选中模型,右键平滑着色

  2. 在编辑材质的时候,设置"材质属性-表面曲面 - 光泽BSDF"

创建姿态资产

  1. blender 4.0+版本姿态库有所变化,创建资产需要在"动画摄影表"等其他栏目中才能打开。

  2. 切换到"资产管理器"栏目 可以对资产进行重命名、截图等编辑操作。

  3. 所有的姿态可以是共存关系,比如姿态A设置了脸部表情,姿态B设置了动作,那么就可以点击姿态A和姿态B将脸部表情和动作结合起来。

  4. 我们还可以预览2个姿态直渐的动作过渡。在姿态资产选中默认姿态A,在主场景选中会发生动作的几个控制器,然后将鼠标按住目标姿态B,然后拖动鼠标,此时就会出现两个姿态之间的切换动画,顶部还有进度条。

写在最后

至此让小Z从二维平面走入三次元,动起来的这一步实现了,这里面仍有许多需要完善的地方,比如模型做动作时不时出现的穿模和破面等情况,如何给小Z加上脸部表情,实现表情与动作的组合等等。

然而这不是终点,最终的目标是让小Z模型成为一个被调用的前端模块,结合我们的企业AI聊天助手同步各种动作姿态;而在宣传层面,我们可以把小Z的姿态和动作库完善起来,作为各种周边产品的视觉物料,或者形成各种短视频动画,当然这些工作量很大,都需要其他伙伴的参与了。

参考链接

手把手教你用AI把草图做成3D骨骼动画

React+Lingo 实现一个超好玩的3D游戏

为模型添加骨骼绑定

Blender3D模型如何进行骨骼和动作自动绑定

【Blender】UV详细解释及各种UV操作

Youtbue教程: 4.2 中使用 Mixamo 动画

在blender合并mixamo动画

使用autoRig同步骨骼动作

合并多个mixamo动作到fbx

相关推荐
wumu_Love6 分钟前
npm 和 node 总结
前端·npm·node.js
顾辰呀10 分钟前
css 文字一行没有放满不进行换行
前端·javascript·css·vue.js·css3
nixiaoge36 分钟前
Web前端第二次作业
前端·javascript·css3
浮华似水1 小时前
Docker入门系列——镜像原理
前端
Gavin_9151 小时前
【JavaScript】数组-集合-Map-对象-Class用法一览
开发语言·前端·javascript
张保瑞1 小时前
十一:java web(3)-- Spring框架 -- Spring简介
java·前端·spring
墨柳烟2 小时前
ABAQUS高亮显示网格节点方法:Python为每个节点建立集合
开发语言·前端·python·abaqus
琴~~2 小时前
前端根据后端返回的文本流逐个展示文本内容
前端·javascript·vue
zhaocarbon2 小时前
el-scrollbar 动态更新内容 鼠标滚轮无效
前端·javascript·vue.js
一纸忘忧2 小时前
Nuxt 3.14 发布!全新功能与性能提升
前端·javascript·vue.js