厘米秀3d形象diy渲染技术揭秘
如果无法正常显示,请先停止浏览器的去广告插件。
1. 厘米秀3D形象DIY渲染技术揭秘
Wendycheng
腾讯QQTeam
高级前端工程师
2. 目录
•
• 3D形象DIY技术揭秘
• 自定义肤色
• 化妆装扮
• 自由捏脸
3. 厘米秀3D in QQ
抽屉&资料卡
聊天表情
头像录制
个人主页
厘米小游戏
4. 厘米秀3D in QQ
搭配服装
自定义面部化妆效果
自定义捏脸 + 肤色
5. 厘米秀3D in QQ
• 业务特点
• 多场景复用
• 高度个性化
• 轻量级渲染
• 技术选型
• 缺乏轻量级跨平台渲染引擎
• 化妆、捏脸等DIY功能,复杂度高
• 需兼顾效率和效果
6. 厘米秀3D业务系统架构
H5
美术资源
3D首页
小屋页
CDN
自研Unity插件
阿童木
管理系统
brickjs
dress.zip
dress.zip
私有二进制
格式
(js渲染引擎)
native
(js runtime)
抽屉页
技术选型
• 基于threejs二次开发JS引擎
• 使用WebGL渲染
资料卡
3D头像、表情
7. 目录
• 厘米秀3D业务简介
•
• 自定义肤色
• 化妆装扮
• 自由捏脸
8. 基础知识——3D模型的构成
一个典型3D模型
几何数据
顶点
网格
决定物体的形状
法线
uv坐标
决定物体运动(骨骼动画)
材质参数
骨骼信息
纹理贴图
纹理贴图
纹理贴图
纹理贴图
纹理贴图
纹理贴图文件
决定物体的
颜色/材质
9. 基础知识——渲染管线
metallic=1.0
specular=1.0
……
材质参数
纹理缓冲区
纹理贴图
顶点缓冲区
顶点着色器
片元着色器
几何数据
显存
应用程序层
GPU渲染管线
操作系统层
10. 理解渲染管线
• 传统JS编程:代码运行在JS引擎中
• 图形JS编程:通过api发起系统调用,经过操作系统定制渲
染管线,下放到硬件层面
• 可编程通用管线,支持着色器的自定义
• WebGL,就是系统图形api
• OpenGL ES 2.0标准 的 JS绑定版本,通过JS下发系统调用
• 抹平系统差异,得到浏览器厂商广泛支持
11. 厘米秀资源拆分
Dress
Action
cloth
makeup
skeleton
Role
face
FaceData
通用资源
个性化资源
12. 厘米秀服装材质
• 厘米秀服装采用Disney标准的PBR材质渲染
13. DIY肤色渲染原理
• skinMaskMap
• 用遮罩标出albedo Map中皮肤区域
• 渲染肤色时,只改变该部分的颜色值
face
top dress
bottom dress
默认肤色
自定义肤色
14. DIY肤色渲染原理
• 肤色的改变用HSV色彩空间表示
• 色相(H) 饱和度(S) 明度(V)
• 肤色不是纯色,所以记录相对值更合理
+HSV(-6,52,-70)
15. DIY化妆渲染原理
• 化妆装扮全部作用于面部
beauty.png
• 省略几何模型,只存储 贴图 + 偏移坐标
• 运行时,把化妆贴图“叠”在面部贴图上
• 用叠加后的贴图参与后续绘制
—— 转3D为2D,降低复杂度
dress.bin
"cropping": {
"0": 463,
"1": 633,
"2": 591,
"3": 697
},
16. DIY化妆渲染流程
• 1. 使用独立shader,离屏预渲染
• 2. 只渲染一次,输出结果作为新的面部贴图,参与主绘制流程(帧循环)
• 3. 多个makeup可同时叠加,节省开销
面部贴图
makeup贴图
makeup贴图
makeup贴图
离屏
渲染器
面部贴图
(带makeup)
面部模型
服装模型
骨骼动画
帧信息
帧循环
17. 基础知识——骨骼蒙皮动画
• 概念
•
抽象出骨骼结构,骨骼带动顶点,把复杂的网格运动简化成
骨骼的运动
• 一根骨骼 = 单个位置矩阵
• 一套骨骼 = 树状结构的矩阵集合
• 计算规则
• 用矩阵变换表达骨骼运动
• 用蒙皮权重表示每个顶点受骨骼影响的系数
(一个顶点最多关联四根骨骼)
18. 骨骼蒙皮动画的优势
• 1. 降低动画存储体积
• 厘米秀模型的规模——2w+面,200+根骨骼
• 动画素材只需要存储200根骨骼的关键帧
• 2. 降低动画计算复杂度
• 200+次矩阵乘法(复杂)
• 2w+次权重线性加法(简单)
• 3. 跨装扮复用
• 所有厘米秀模型通用一套骨骼
19. DIY捏脸渲染原理
• 捏脸 = 动画
• 捏脸:从状态A变化到状态B
• 动画:一系列状态变化的集合
面部骨骼一览
• 骨骼捏脸
• 用于控制眼距,眼形,嘴型等等
• 可表达较大的变化值
• 不够直观,不够丰富,对设计不友好
• 通道捏脸
• 用于更细致的面部网格形状控制
• 作为骨骼捏脸的补充
用面部骨骼控制眼睛的形状
20. DIY捏脸渲染原理
• 通道形变(blend shape)
• 又名shape keys、morph targets
• 不借助骨骼,直接将一组顶点聚合为“通道”
• 通道 (变化极限值) 由设计师指定,存储在模型中
原始状态
cheek_bulge 通道
chin_short 通道
21. • 用户通过指定通道的“权重”,得到“与众不同”的面部
用户一
• 多个通道可以叠加作用
用户二
用户三
22. • 通道叠加函数
通道信息:二进制格式,存储在通用模型里(数据量大)
权重信息:json格式,存储在用户数据里(数据量小)
渲染模型前,预先提取通道权重信息,对面部网格做一次性修改
23. BlendShape的其他应用
制作预设五官
制作形变动画
AI扫描捏脸
24. 体验骨骼和blendshape
25. 骨骼 vs 通道(效率比较)
用于动画时
• 骨骼
用于捏脸时
• 骨骼
• 每个顶点计算四次 • • 骨骼数目影响计算效率 一次性预计算
计算次数取决于可编辑骨骼数
• 可放进顶点着色器,用GPU并行计算 •
(GPU Skinning)
• 通道
• 顶点计算次数,取决于通道复杂度
• 通道越多,计算越慢
• 常用于局部动画(如面部表情)
• 通道
• 一次性预计算
• 计算次数取决于通道复杂度
26. 用户DIY数据的存储
{
"deltaHSV": {
"skin": {"H": 10, "S": -15, "V": 0 }, // 肤色自定义HSV
"lipstick": {"H": 10, "S": -15, "V": 0 }, // makeup自定义HSV
"blusher": {"H": 10, "S": -15, "V": 0 },
……
},
"skeleton": [ // 用骨骼变化表达的捏脸信息
{
"name": "Eye_C_L",
"scale": [1,1,1],
"position": [0.092,0.053,0.043]
},
……
],
"blendshape": { // 用BS通道权重表达的捏脸信息
"eyebrow_upper_eyelid_up": 0.7262569666,
"eyebrow_upper_eyelid_down": 0,
"eyebrow_lower_eyelid_up": 0.156424582,
"eyebrow_lower_eyelid_down": 0,
"eyebrow_inner_eye_corner_in": 0.2122904956,
"eyebrow_inner_eye_corner_out": 0,
"eyebrow_inner_eye_corner_up": 0.486033529,
"eyebrow_inner_eye_corner_down": 0,
……
}
}
• 将大量数据放在模型中
• 用户数据只存储简单的JSON配置
• 以uin(qq号)为维度存储
• 每个用户的数据只有3K
27. DIY渲染方案总结
化妆预处理
离屏
渲染器
面部贴图
(带makeup)
捏脸骨骼/通道
预处理
面部模型
骨骼动画
帧信息
服装模型
肤色处理
DIY化妆、捏脸在渲染前一次性预处理
DIY肤色在渲染管线片元着色器中处理
帧循环
28. 感谢倾听
大会官网