This is an extremely primitive test of how the face shader is achieved in Genshin Impact.
A dynamic facial shadow map texture (referred to as ‘shadow map’, or ‘lightmap’ in the code) is used to define how facial shadows respond to main light directions. This shadow map could be created by drawing a couple of characteristic shadow textures under some lighting angles, then combining the results of their SDF interpolations. @橘子猫 shared a solution for automated creation of such shadow maps: https://zhuanlan.zhihu.com/p/356185096.
This shadow map feature can be integrated into UnityURPToonLitShaderExample by ColinLeung-NiloCat. This is the resulting shader:
repo 里的面部 shader 就是我在这期视频里使用的→【仿原神/实时渲染】啊,这光!啊,这水!芭芭拉的Solo☆MV (?)【2D卡通渲染】://。目前有些限制,但配置好以后还是可以用用的,能达到近似游戏内的效果。
限制:
- 完全覆盖了原本的卡通阴影实现方法,必须赋予 _LightMap (即面部动态阴影贴图,本文统称阴影贴图) 才有阴影
- 不受光照强度或光照颜色影响
- 获取 Forward & Right vectors(2)
- 根据光照方向选择原始或翻转(1)的阴影贴图
// Use r value from the original lightmap(left part in shadow) or flipped lightmap (right part in shadow) depending on normalized light direction;
float LightMap = RightLight > 0 ? surfaceData._lightMapR.r : surfaceData._lightMapL.r;
即使角色背对光源也要有鼻翼光,可以看情况用 dirThreshold 延展阴影贴图(差不多0.1~0.
float lightAttenuation_temp = (FrontLight > 0
min((LightMap > dirThreshold * RightLight), (LightMap > dirThreshold * -RightLight)) :
min((LightMap > (1 - dirThreshold * 2)* FrontLight - dirThreshold), (LightMap > (1 - dirThreshold * 2)* -FrontLight + dirThreshold));</pre>
最后糊上阴影颜色((不知道一般怎么做暂时先这样吧
half3 shadowColor = lerp(1 * surfaceData._shadowColor, 1, faceShadowMask);
half3 rawLightSum = max(indirectResult*shadowColor, mainLightResult + additionalLightSumResult); // pick the highest between indirect and direct light
参考:
(1) ruofeng133,https://blog.csdn.net/A13155283231/article/details/109705794
(2) 黑魔姬,https://zhuanlan.zhihu.com/p/279334552
(3) xibanya,https://answers.unity.com/questions/1686727/is-there-a-way-to-change-the-shadows-to-blue.html