前端开发者的福音:用JavaScript实现Live2D虚拟人口型同步

先上效果

DEMO体验: 虚拟人驱动口型体验

Live2d 虚拟人

Live2D是一种应用于电子游戏的绘图渲染技术,该技术由日本Cybernoids公司(现已更名为Live2D)开发。通过一系列的连续图像和人物建模来生成一种类似三维模型的二维图像,对于以动画风格为主的游戏来说非常有用。

简单来说,Live2D就是一项在不增加绘图工作量的基础上,让2D人物"活"起来的技术。画师只需要绘制一张原画,然后将身体、五官、发型、服装等2D图片放到全3D的模型模板上。

live2d主要应用在游戏和虚拟直播比较多。效果偏向于卡通动漫,写实效果差。

前端web引入Live2d

官方是提供Live2d Web SDK,但是文档写的很差,几乎必须查阅源代码才能上手。比较好的是有基于pixijs封装的

pixi-live2d-display,方便在Web中接入Live2d模型。下面是按需引入的方式,可以减少打包体积。

ts 复制代码
import { Live2DModel } from 'pixi-live2d-display/cubism4'
import { Application } from '@pixi/app'
import { Ticker, TickerPlugin } from '@pixi/ticker'

// register Ticker for Live2DModel
Live2DModel.registerTicker(Ticker as any)

// register Ticker for Application
Application.registerPlugin(TickerPlugin)

onMounted(async () => {
   const app = new Application({
    view: canvasRef.value,
    resizeTo: canvasRef.value.parentElement,
    backgroundAlpha: 0,
    antialias: true, // 启用抗锯齿

  })

  const model = await Live2DModel.from('model.json')
  model.scale.set(props.scale)

  model.x = (app.view.width - model.width) / 2
  model.y = (app.view.height - model.height) / 2

  app.stage.addChild(model)

})

live2d口型同步是一个难点,大多数是通过不同播放中的音频的声调大小来控制口型的开合程度,实现效果较差。如果要想实现相对好一点的效果需要用到最新版本的 Cubism5 新出的MotionSync功能,可以支持日语元音AEIOU五种类型口型,效果会好一些。Live2d官方在GITHUB开源了他的口语同步demoCubismWebMotionSyncComponents,通过分析demo源码分析,抽取核心功能代码并在上面二次修改实现MotionSync类以接入我们现有的应用。实现的原理就是通过一些算法提取音频流的信息,在每一帧中不断的分析,得到设置口型开合的大小以及设置日语元音AEIOU最接近的元音口型。Live2d口型同步相关代码和更新日志可以在Cubism SDK MotionSync查看。

live2d-motionSync

我创建了一个 npm 库 live2d-motionSync,可以方便的让 Live2d 模型支持口型同步

源代码:github

DEMO体验: 虚拟人驱动口型体验

接入方式

ts 复制代码
import * as PIXI from "pixi.js";
import { Live2DModel } from "pixi-live2d-display";
import { MotionSync } from "live2d-motionsync";

// expose PIXI to window so that this plugin is able to
// reference window.PIXI.Ticker to automatically update Live2D models
window.PIXI = PIXI;

(async function () {
  const app = new PIXI.Application({
    view: document.getElementById("canvas"),
  });

  const model = await Live2DModel.from("kei_vowels_pro.model3.json");

  // 初始化 motionsync
  const motionSync = new MotionSync(model.internalModel);
  // 加载 motionsync 文件
  motionSync.loadMotionSyncFromUrl("kei_vowels_pro.motionsync3.json");
  // 没有 motionsync3 文件可以加载默认 motionsync3 配置
  // motionSync.loadDefaultMotionSync();

  // 确保已经页面交互
  // 播放音频
  motionSync.play("/audio/test.wav").then(() => {
    console.log("播放完毕");
  });
  // 停止音频
  // motionSync.stop();

  app.stage.addChild(model);

  // transforms
  model.x = 100;
  model.y = 100;
  model.rotation = Math.PI;
  model.skew.x = Math.PI;
  model.scale.set(2, 2);
  model.anchor.set(0.5, 0.5);

  // interaction
  model.on("hit", (hitAreas) => {
    if (hitAreas.includes("body")) {
      model.motion("tap_body");
    }
  });
})();

实现虚拟人对话流程

有了控制口型的能力,只需要把虚拟人和我们业务联动起来就可以实现虚拟人对话了。

附上一张虚拟人对话的流程图:

技术通过TTS+GPT+Live2d实现的

最后

感觉有用的兄弟们,给个start吧。源代码:github

相关推荐
计算机毕设指导64 分钟前
基于Springboot美食推荐商城系统【附源码】
java·前端·spring boot·后端·spring·tomcat·美食
!win !7 分钟前
外部H5唤起常用小程序链接规则整理
前端·小程序
染指悲剧19 分钟前
vue实现虚拟列表滚动
前端·javascript·vue.js
林涧泣35 分钟前
【Uniapp-Vue3】navigator路由与页面跳转
前端·vue.js·uni-app
浩浩测试一下1 小时前
Web渗透测试之XSS跨站脚本之JS输出 以及 什么是闭合标签 一篇文章给你说明白
前端·javascript·安全·web安全·网络安全·html·系统安全
一棵开花的树,枝芽无限靠近你2 小时前
【PPTist】插入形状、插入图片、插入图表
前端·笔记·学习·编辑器·ppt·pptist
不会玩技术的技术girl2 小时前
获取淘宝商品详情高级版 API 接口 Java 示例代码
java·开发语言·前端
金州饿霸3 小时前
hadoop-yarn常用命令
大数据·前端·hadoop
肖老师xy3 小时前
h5使用better scroll实现左右列表联动
前端·javascript·html
一路向北North3 小时前
关于easyui select多选下拉框重置后多余显示了逗号
前端·javascript·easyui