unity3d Human skin real time rendering plus 真实模拟人皮实时渲染 plus篇
最近逃课做游戏,逃的有几门都要停考了,呵呵呵,百忙之中不忘超炒冷饭,感觉之前的人皮效果还是不够好,又改进了一些东西
首先上图
放大看细节
显而易见的比上次的效果要好很多,此次我把模型用3dmax进行了细化,模型裂缝情况有所好转,但是嘴唇等处还是有明显裂缝(没办法,网上没有比这个再细致的贴图了)
去除了之前所有大量的rim,换成了SSS次表面散射之前一篇文章详细讲过,
SSS次表面散射的参数真心难调= =;
漫反射换成了基于物理的Oren Nayar反射模型
specular
高光反射与之前一篇相同,这里简单介绍下
BRDF首先由Fred Nicodemus在1965年提出
L是辐射率,或射线方向中立体角的能量,E是辐照度,或每单位角度的辐照能,theta_i是法线与wi的夹角,i表明是入射光incident light,r表明是反射光reflected light。
Cook-Torrance模型
F(l,h)是菲涅尔函数,
D(h)为分布函数,这个函数负责表面的光滑度,高光的形状与大小,也与粗糙度相关,可以达到完美镜面反射。
G(l,v,h)是几何函数,
float _SP = pow(8192, _GL); float d = (_SP + 2) / (8 * PIE) * pow(dot(n2, H), _SP); float f = _SC + (1 - _SC)*pow(2, -10 * dot(H, lightDir)); float k = min(1, _GL + 0.545); float v = 1 / (k* dot(viewDir, H)*dot(viewDir, H) + (1 - k)); float all = d*f*v; all = saturate(all); diff = (1 - all)*diff; diff = saturate(diff); spec3 *= Luminance(diff); spec3 = saturate(spec3); spec3 *= _SpecularPower;
diffuse
Oren–Nayar 反射模型由 Michael Oren和 Shree K. Nayar研发,是依据粗糙表面的漫反射模型,可以模拟很大范围的物体,混凝土,塑料,沙子等。
它是基于物理的反射模型。
现
在大多数情况都在用Lambertian 模型,包括unity的diffuse,编写surface
shader的都知道,有lambert光照。Lambertian
模型在所有方向均匀的反射所有光线,这种方法模拟的diffuse不怎么真实,没有根据roughness 粗糙度来计算漫反射。
真实图像与Lambertian和Oren–Nayar的比较
Oren–Nayar和Lambertian 的亮度曲线
具体求法和wiki中的一样
Sigma是表面粗糙度
E0是正面照射时的辐照度
Rho是表面反射
中间的步骤比较简单
最终公式为
风之旅人journey 中的沙子渲染也用了这种方法
次表面散射(Subsurface Scattering)
光经过哪,就带一部分那里的颜色,可以发现光从入射到出射,位置和方向都变了
光走的路径数量是无穷大,光反射回来的都为漫反射,油脂表面的透明度也都是不一样的,
这就产生了次表面散射
具体算法公式在这里此处不再赘述
相要变得更真实还可以加一些noise进去
加了bloom效果之后:
感觉此次效果还不是很完美,随着学习的深入还会继续改进;
全部代码已上传至github
----by wolf96