在Blender中使用代码控制人物模型的嘴部动作 - 嘴部张开
flyfish 环境 无需iphone,不限制平台
原始的3D模型
控制之后的样子
3D模型部分
中英文对照 此次使用的是形态键(Shape Keys)控制, 如果遇到Blendshapes,Morphs,Morphtargets,Sliders也都是形态键的意思
eyeBlinkLeft 左眼眨眼
eyeLookDownLeft 左眼目视下方
eyeLookInLeft 左眼注视鼻尖
eyeLookOutLeft 左眼向左看
eyeLookUpLeft 左眼目视上方
eyeSquintLeft 左眼眯眼
eyeWideLeft 左眼睁大
eyeBlinkRight 右眼眨眼
eyeLookDownRight 右眼目视下方
eyeLookInRight 右眼注视鼻尖
eyeLookOutRight 右眼向左看
eyeLookUpRight 右眼目视上方
eyeSquintRight 右眼眯眼
eyeWideRight 右眼睁大
jawForward 努嘴时下巴向前
jawLeft 撇嘴时下巴向左
jawRight 撇嘴时下巴向右
jawOpen 张嘴时下巴向下
mouthClose 闭嘴
mouthFunnel 稍张嘴并双唇张开
mouthPucker 抿嘴
mouthLeft 向左撇嘴
mouthRight 向右撇嘴
mouthSmileLeft 左撇嘴笑
mouthSmileRight 右撇嘴笑
mouthFrownLeft 左嘴唇下压
mouthFrownRight 右嘴唇下压
mouthDimpleLeft 左嘴唇向后
mouthDimpleRight 右嘴唇向后
mouthStretchLeft 左嘴角向左
mouthStretchRight 右嘴角向右
mouthRollLower 下嘴唇卷向里
mouthRollUpper 下嘴唇卷向上
mouthShrugLower 下嘴唇向下
mouthShrugUpper 上嘴唇向上
mouthPressLeft 下嘴唇压向左
mouthPressRight 下嘴唇压向右
mouthLowerDownLeft 下嘴唇压向左下
mouthLowerDownRight 下嘴唇压向右下
mouthUpperUpLeft 上嘴唇压向左上
mouthUpperUpRight 上嘴唇压向右上
browDownLeft 左眉向外
browDownRight 右眉向外
browInnerUp 蹙眉
browOuterUpLeft 左眉向左上
browOuterUpRight 右眉向右上
cheekPuff 脸颊向外
cheekSquintLeft 左脸颊向上并回旋
cheekSquintRight 右脸颊向上并回旋
noseSneerLeft 左蹙鼻子
noseSneerRight 右蹙鼻子
tongueOut 吐舌头
上述名字可以和自己模型中的名字进行对应 例如eyeBlink_L就是EyeBlinkLeft 这里定义左右是对于3D人物模型的左右。例如3D人物模型的eyeBlinkRight,我们看到的实际在左边。 数值说明以张嘴为例,数值是浮点类型值,张嘴程度值的范围为[0,1],0表示没有张嘴,1表示完全张嘴。 代码部分 根据人脸关键点计算嘴部纵横比,将结果赋值给JawOpen 根据已经定义好的jawOpen,代码可以这样控制嘴部
import bpy
ob=bpy.data.objects['Body']
shape_keys = ob.data.shape_keys.key_blocks
shape_keys['jawOpen'].value = x
shape_keys['jawOpen'].keyframe_insert(data_path='value')
如何通过关键点计算x的值呢 x的数值是浮点类型值,张嘴程度值的范围为[0,1],0表示没有张嘴,1表示完全张嘴 这里需要用到两个shape key,先使用一个jawOpen 大图在这里https://flyfish.blog.csdn.net/article/details/122448347 下载下来看
def mouth_aspect_ratio(image_points):
p1 = image_points[78]
p2 = image_points[81]
p3 = image_points[13]
p4 = image_points[311]
p5 = image_points[308]
p6 = image_points[402]
p7 = image_points[14]
p8 = image_points[178]
mar = np.linalg.norm(p2-p8) + np.linalg.norm(p3-p7) + np.linalg.norm(p4-p6)
mar /= (2 * np.linalg.norm(p1-p5) + 1e-6)
return mar
嘴部纵横比的值肯定会有大于1的情况,而这里3D模型限制最大值是1。也可以根据3D模型和嘴部纵横比再调整下。 这样将每次检测出的关键点,计算出嘴部纵横比赋值给模型就可以了。
参考网址 动图展示各个Shape Key的样子和3D的样子
https://arkit-face-blendshapes.com/ https://hinzka.hatenablog.com/entry/2021/12/21/222635 https://developer.apple.com/documentation/arkit/arfaceanchor/blendshapelocation
|