当前位置:网站首页>角色妆容的实现
角色妆容的实现
2022-07-31 19:18:00 【肖远行】
前段时间做了下角色妆容的实现,想写个文章记录一下这个事情。妆容看起来很复杂,实际上整理实现思路很简单,主要是两个方面的内容,改变基础色和改变高光(金粉效果)。
先贴一个妆容效果:
没有开启妆容的情况下,基础色就是从颜色贴图和基础颜色中获得;开启妆容后,要根据各个状态模块的模板和比例来插值妆容颜色和基本颜色;金粉则是改变特定区域的高光,金粉的浓淡可以用滑块控制,最好同时结合妆容色的浓淡;额外可能需要改变特定妆容区域的光滑度,比如唇彩。
妆容界面
妆容开关
最上面有一个Toggle来开关妆容模块,可以使用shader_feature_local的关键字,比如_MAKEUP来区分。
妆容金粉
最上面的界面是指定金粉贴图贴图和相应的缩放,使用同样的UV缩放和位移的好处是避免重复读取金粉贴图,提高性能,避免每个妆容模块都要去读一次贴图。毕竟贴图是存储在内存中,要读取到GPU内的话,如果没有Cache中,则速度相比一个计算来说要慢一个数量级的可能。
妆容模块
接下来是具体的妆容模块,虽然模块比较多,实际上大同小异。功能都是通过通道贴图去改变指定位置的基础颜色,有些通道贴图还有图案的作用。有一些模块有额外的功能,比如唇彩的光滑度滑块、面纹的UV变化。
妆容的实现原理
下面介绍妆容的具体实现原理。
妆容颜色
这里的妆容颜色实际上对应的就是界面上具体的妆容模块。以第一个腮红为例子来说明,参考如下代码:
half3 makeup = baseColor;
half4 blush = SAMPLE_TEXTURE2D(_BlushMap, sampler_BlushMap, uv0);
makeup = lerp(makeup, blush.rgb * _BlushColor, blush.a * _BlusIntensity);
从代码可以看到妆容色makeup是基础颜色和妆容颜色的插值结果。妆容颜色是从通道贴图读取的rgb和腮红颜色的结合,同样插值比例是通道贴图的a和腮红比例的结合。不过大部分妆容模块的妆容颜色不需要通道贴图的rgb,这种通道贴图实际上可以做合并处理。
妆容模块的结合
妆容模块有一定的叠加顺序,最底部的是基础色,然后是按照顺序叠加的妆容模块,比如界面上的妆容模块顺序。那么,计算的时候,首先也是一个个按照顺序插值过来,比如先插值基础颜色和腮红,然后用插值结果继续和下一个妆容模块做插值,这样得到的最终妆容颜色就是多个妆容模块的结合。
妆容金粉
金粉实际上改变的是高光。没有金粉的话,高光就是默认的情况,比如pbr的金属流高光或者Bling-Phong的高光。有金粉的话,根据金粉计算出一个高光,同时与默认高光进行插值,插值的因子同具体妆容模块的颜色计算。
可以参考以下代码实现:
half3 golddustUV0 = SAMPLE_TEXTURE2D(_GolddustMap, sampler_GolddustMap, _GolddustUVTile * uv0 + _GolddustUVSpeed * _Time.x).rgb;
half4 blush = SAMPLE_TEXTURE2D(_BlushMap, sampler_BlushMap, uv0);
half3 specular = lerp((half3)0, _BlusGolddustColor * golddustUV0 * _BlusGolddustIntensity, blush.a * _BlusIntensity);
对于Pbr的金属流,默认的高光是0,所以金粉是为了增加额外的高光。关键的一句是在默认的高光和金粉高光之间做插值,插值比例是金粉浓度和妆容的比例。金粉高光是从金粉贴图读取出来同时应用金粉颜色和强度。
其它功能
比如唇彩模块可以改变光滑度,这个改变的前提是唇彩的通道贴图a通道是大于0的;另外还有面纹的一些UV变化,实际上这个是简单模仿贴花的功能。
性能优化
下面介绍一些妆容性能相关的优化策略。
妆容通道贴图采样器的合并
上述界面的妆容模块过多,如果每个妆容通道贴图一个采样器,肯定会超过限制。方式是所有妆容模块共用一个或者几个采样器。不过,理解上来说,一个贴图采样器对应一个贴图设置,所以去改变贴图的设置会不会有一些影响这个待验证。
妆容通道贴图合并
其实根本没必要一个妆容模块一个贴图,完全可以做贴图合并,比如不需要使用rgb的妆容模块,那么一个贴图可以对应四个妆容模块了。实际上,跟美术沟通后发现,妆容的效果主要是依赖妆容的通道掩码和妆容颜色,所以基本上不需要使用妆容贴图的rgb。
妆容颜色渲染到基础贴图
这个理论上来说算是终极优化吧。妆容会暴露很多参数给美术或者用户,用户调整这些参数后会得到一个化妆后的效果。关键的地方是,调整完成之后,可以理解为妹子化妆完成后,效果已经固定了。那么实际上,我们不需要每次再去计算妆容颜色,而是可以将妆容颜色渲染到一张单独的贴图上或者直接覆盖原本的BaseMap。以后的渲染,就不需要使用妆容模块了。
具体实现思路
可以新建一个Pass,将妆容颜色的计算结果单独走一遍Pass,同时结合原本的BaseMap作为基础颜色,渲染目标是一个RT,比如是BaseMap。这个Pass的开关可以提供接口供业务代码控制,在化妆完成后调用来覆盖原本的BaseMap。
妆容效果
最后上一点效果图吧,从美术大佬那边要来的图,凑合看看吧。
边栏推荐
- MySQL---基本的select语句
- MySQL---operator
- 【PIMF】OpenHarmony 啃论文俱乐部—盘点开源鸿蒙三方库【3】
- Apache EventMesh distributed event-driven multi-runtime
- MySQL---多表查询
- spark报错OutOfMemory「建议收藏」
- UserAgent 解析
- leetcode 665. Non-decreasing Array 非递减数列(中等)
- INeuOS industrial Internet operating system, the equipment operational business and "low code" form development tools
- Combinatorics Notes (6) Associative Algebra of Locally Finite Partially Ordered Sets, Möbius Inversion Formula
猜你喜欢
[TypeScript] OOP
Unity 之 音频类型和编码格式介绍
Go basic part study notes
20.支持向量机—数学原理知识
The whole network is on the verge of triggering, and the all-round assistant for content distribution from media people - Rongmeibao
Bika LIMS 开源LIMS集—— SENAITE的使用(检测流程)
Architect 04 - Application Service Encryption Design and Practice
This 985 professor is on fire!After 10 years of Ph.D. supervisor, no one has graduated with a Ph.D.!
九齐ny3p系列语音芯片替代国产方案KT148A性价比更高420秒长度
PCB叠层设计
随机推荐
pytorch lstm时间序列预测问题踩坑「建议收藏」
新型电信“套路”,我爸中招了!
【码蹄集新手村600题】通向公式与程序相结合
20.支持向量机—数学原理知识
STM32 full series development firmware installation guide under Arduino framework
Bika LIMS 开源LIMS集—— SENAITE的使用(检测流程)
rj45 to the connector Gigabit (Fast Ethernet interface definition)
MATLAB程序设计与应用 2.4 MATLAB常用内部函数
常用的安全渗透测试工具(渗透测试工具)
Taobao/Tmall get Taobao password real url API
基于WPF重复造轮子,写一款数据库文档管理工具(一)
程序员如何学习开源项目,这篇文章告诉你
深度学习中的batch(batch size,full batch,mini batch, online learning)、iterations与epoch
Apache EventMesh 分布式事件驱动多运行时
[PIMF] OpenHarmony Thesis Club - Inventory of the open source Hongmeng tripartite library [3]
Mobile web development 02
TestCafe总结
SiC MOSFET的短路特性及保护
Tkinter 入门之旅
The article you worked so hard to write may not be your original