以ChatGPT为基础结合ChatVRM,讯飞语音合成和语音识别实现的前端方案中,单纯的从前端角度出发简要描述各个技术的结合.

1.ChatVrm

ChatVRM目前是基于SpeechRecognition,ChatGPT,Koemotion/KoeiromapAPI(语音合成),@pixiv/three-vrm(3D展示)几个部分组成

SpeechRecognition:是JS的默认API,不过多介绍
ChatGPT:不过多介绍
Koemotion/Koeiromap API:一个语音合成的API,目前可以用讯飞语音代替
@pixiv/three-vrm(3D展示):数字人物的3D展示


这里的难点主要在于@pixiv/three-vrm(3D展示)这个库,本身是使用VRM技术,并且基于Three.js实现的一套3D数字人头像;在Three.js基础上封装了一组API,用于控制数字人的一些列表情和动作;

这里面需要解决的技术

  • VRM素材文件,
  • Three.js要有一定的基础知识的了解
  • three-vrm这个库的一些API要完全了解

1.1 VRM

这里贴一下VRM的一些简单介绍 如何创建VRM

VRM(Virtual Reality Model)是一种基于three.js的格式,用于表示3D虚拟角色模型。它是由日本电子工业协会(JEITA)提出和推广的开放标准。VRM文件可以包含角色的模型、材质、骨骼、动画等信息,并且还支持表情和物理效果的定义。

使用VRM格式可以让开发者更方便地在各种应用程序中使用和共享3D角色模型,例如虚拟现实(VR)、增强现实(AR)、游戏和社交平台。通过使用VRM,开发者可以将自己的虚拟角色模型从一个应用程序转移到另一个应用程序,而无需重新创建或重新导入模型。

VRM还支持一些特殊功能,例如人脸捕捉和表情控制,以及物理效果模拟,如头发和衣服的运动。这使得VRM模型可以更加逼真地呈现,并且具有更好的互动性。

总之,VRM是一种基于three.js的开放标准,用于表示和共享3D虚拟角色模型,在虚拟现实、游戏和社交领域有着广泛的应用潜力。

1.2 Thress.js

基于JS的一套3D动画

1.3 three-vrm

目前对整体API的粗略翻译大概如下图

整体分为以下几部分

  1. VRM文件(VRM模型文件),要使用unity和UniVRM来打开,就是gltf格式的,增加了vrm的extension
  2. VRMA文件,手部的动画文件,主要影响人物的抖动和手臂的动作,也是gltf格式的,增加了vrmc-animation-extension
  3. 基于Three.js的一些基础构建主要用来构建画布并且将VRM文件填充进来
  4. 基于Three.js和three-vrm的API的动画插件(目前从API名称上看是一些动画帧和轨道帧之类的实现,目前可以判断主要是用来实现人物的抖动和手臂动作)
  5. 针对数字人的动作和面部控制,主要是three-vrm的API
//以下为人物可控制的关节节点
const VRMHumanBoneName = {
Hips: 'hips', //臀部
Spine: 'spine', //脊柱
Chest: 'chest', //胸部
UpperChest: 'upperChest', //上胸
Neck: 'neck', //脖子
Head: 'head', //头
LeftEye: 'leftEye', //左眼
RightEye: 'rightEye', //有眼
Jaw: 'jaw', //下巴
LeftUpperLeg: 'leftUpperLeg', //左大腿
LeftLowerLeg: 'leftLowerLeg', //左小腿
LeftFoot: 'leftFoot', //左脚
LeftToes: 'leftToes', //左脚趾
RightUpperLeg: 'rightUpperLeg', //右大腿
RightLowerLeg: 'rightLowerLeg', //右小腿
RightFoot: 'rightFoot', //右脚
RightToes: 'rightToes', //右脚趾
LeftShoulder: 'leftShoulder', //左肩
LeftUpperArm: 'leftUpperArm', // 左大臂
LeftLowerArm: 'leftLowerArm', //左小臂
LeftHand: 'leftHand', //左手
RightShoulder: 'rightShoulder', //右肩
RightUpperArm: 'rightUpperArm', //右大臂
RightLowerArm: 'rightLowerArm', //右小臂
RightHand: 'rightHand', //右手
LeftThumbMetacarpal: 'leftThumbMetacarpal', //左手大拇指(手掌)
LeftThumbProximal: 'leftThumbProximal', //左手大拇指(根部)
LeftThumbDistal: 'leftThumbDistal', //左手大拇指(关节)
LeftIndexProximal: 'leftIndexProximal', //左手食指(根部)
LeftIndexIntermediate: 'leftIndexIntermediate', //左手食指(第二关节)
LeftIndexDistal: 'leftIndexDistal', //左手食指(第一关节)
LeftMiddleProximal: 'leftMiddleProximal', //左手中指(根部)
LeftMiddleIntermediate: 'leftMiddleIntermediate', //左手中指(第二关节)
LeftMiddleDistal: 'leftMiddleDistal', //左手中指(第一关节)
LeftRingProximal: 'leftRingProximal', //左手无名指(根部)
LeftRingIntermediate: 'leftRingIntermediate', //左手无名指(第二关节)
LeftRingDistal: 'leftRingDistal', //左手无名指(第一关节)
LeftLittleProximal: 'leftLittleProximal', //左手小指(根部)
LeftLittleIntermediate: 'leftLittleIntermediate', //左手小指(第二关节)
LeftLittleDistal: 'leftLittleDistal', //左手小指(第一关节)
RightThumbMetacarpal: 'rightThumbMetacarpal',
RightThumbProximal: 'rightThumbProximal',
RightThumbDistal: 'rightThumbDistal',
RightIndexProximal: 'rightIndexProximal',
RightIndexIntermediate: 'rightIndexIntermediate',
RightIndexDistal: 'rightIndexDistal',
RightMiddleProximal: 'rightMiddleProximal',
RightMiddleIntermediate: 'rightMiddleIntermediate',
RightMiddleDistal: 'rightMiddleDistal',
RightRingProximal: 'rightRingProximal',
RightRingIntermediate: 'rightRingIntermediate',
RightRingDistal: 'rightRingDistal',
RightLittleProximal: 'rightLittleProximal',
RightLittleIntermediate: 'rightLittleIntermediate',
RightLittleDistal: 'rightLittleDistal',
};
 //以下为控制人物面部表情的种类,均有权重可以控制程度大小
const VRMExpressionPresetName = {
Aa: 'aa',
Ih: 'ih',
Ou: 'ou',
Ee: 'ee',
Oh: 'oh',
Blink: 'blink',
Happy: 'happy',
Angry: 'angry',
Sad: 'sad',
Relaxed: 'relaxed',
LookUp: 'lookUp',
Surprised: 'surprised',
LookDown: 'lookDown',
LookLeft: 'lookLeft',
LookRight: 'lookRight',
BlinkLeft: 'blinkLeft',
BlinkRight: 'blinkRight',
Neutral: 'neutral',
};

2.讯飞语音识别和语音合成

最终需要实现的效果是语音识别问题后发送至GPT,GPT流式返回的同时调用语音合成并同步语音输出
,基于此大概得流程图如下

结语

此篇文章只是简要介绍,后续会详细介绍ChatVRM和讯飞语音合成和语音识别在结合的过程中的前端技术问题