第一弹主要介绍原理部分,第二弹 是可以在游戏中运用的。
要渲染皮肤,首先要知道皮肤的整体构成及属于一种什么样的材质,根据现代医学分析,皮肤大致的整体结构分为表皮层,真皮层和皮下组织,并且是轻微半透明的,所以我们知道了,皮肤是一种多层半透明材质。
然后我们分析光射射到皮肤上的变化。
一小部分光在接触到皮肤的时候会直接发生镜面反射,这部分光大约占据入射光光能的百分之六,这主要以为菲涅尔互动和最上层含油的皮肤。下图展示了光在皮肤表面反射示意图。
另一部分光穿过皮肤表层会发生来回的反射,一部分被皮肤吸收,一部分再穿过表层皮肤在某个位置穿出。下图展示了光在皮肤次表面散射的示意图。
皮肤渲染总流程
1.位皮肤实现一个基于物理的镜面反射模型
我们使用BRDF进行渲染。通常BRDF的高光反射项用以下形式来表示。
其中F代表菲涅反射项,G代表阴影遮蔽函数,D代表微面元的法线分布函数,具体BRDF的详细细节可参考:https://boblchen.github.io/images/brdf/brdf.pdf
其中F的实现如下:
其中halfDir代表半角向量,ViewDir代表顶点点到摄像机的方向,F0是入射时的反射值,对于皮肤我们用0.28.
float fresnelReflectance(float3 halfDir, float3 viewDir, float F0)
{
float base = 1.0 - dot(viewDir, halfDir);
float exponential = pow(base, 5.0);
return exponential + F0 * (1.0 - exponential);
}
我们这里对BRDF进行分解以高效的计算,我们这里预计算Beckmann法线分布函数的单个纹理并使用上述的fresnel近