您当前的位置: 首页 > 

VT LI

暂无认证

  • 4浏览

    0关注

    126博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

角色渲染分享

VT LI 发布时间:2020-08-10 17:18:48 ,浏览量:4

先看看效果:

 

全局光加次表面散射

 

 

 

 

没有全局光

 

没有次表面散射

 

我们是urp管线的处理,默认的渲染是最后这张,既没做全局光也没做次表面散射的。效果会比较塑料。

那么要达到比较像人的渲染我们就必须要经历一个处理,次表面散射。

为什么要做此表面散射?

这要从我们当代光栅化器的图形学说起。

我们都指导用PBR来渲染,他是一个基于物理的真实渲染,一般的游戏引擎都会集成他。他是一个立体角下对光照的采样后计算的积分。

而其中最重要的是渲染方程,渲染方程包括BRDF,BTDF,BSDF。BSDF=BRDF+BTDF

现代的引擎普遍用的是brdf,既是对当前点的双向反射做的渲染方程,包括法线分布,几何遮蔽和菲涅尔。公式就不列了。

关于BTDF和BSDF其实也类似,BTDF一般是对当前法向的反向做渲染方程的,BSDF就是前两个的结合。

 

左边是基于单个像素的反射,右图是包括次表面散射的表现。

但是,这些渲染方程都是基于当前点的渲染,这会有什么问题呢?问题就在于在我们的现实中,比如人的皮肤是会有大量的次表面散射的。次表面散射就是上面的右图。可以看出来当前点的颜色并不是像上面的brdf之类的用一个点的光照信息来决定的,他还会受到周围其他大量像素的散射过来的颜色。但是当代光栅化器下的gpu是没办法得到当前渲染帧下其他像素的光照信息的(不然怎么并行?),所以我们就比较难的去做次表面散射了。

但是经过大量的科学研究,包括gpugem3和一些论文里有介绍一些方法。

理论上皮肤的散射有两个方面的具体表现。

一是高光的分布更加广而弱,也就是类似金属他的高光聚焦在一个范围内,其他范围更黑,但散射的话光会从当前的皮肤点到散射到其他皮肤点,而导致当前的皮肤点更弱的高光,而其他皮肤点本身比较弱的高光却因为散射而有了一定的高光。这就是所谓的高光会分布更加广而弱。

 

二是通透感,通透感的发生是因为光的方向过来后因为一些部位皮肤比较薄或某些角度导致皮肤比较薄而导致光透过了皮肤到另一面射出。因为人体内有大量的血液,而透过后展示的更多是血脂的颜色,所以也会现实得更红。

 

所以我们要做得核心就是把这两块给完善下。

 

实现:

1.高光得分布,高光的分布基本参考的是Beckmann的方案,这个方案是在一个半球表面对镜面BRDF进行预积分的方式。因为积分在计算机中的运算是比较复杂的,一般要用也是用蒙特卡洛的累加方式做的。但是在手机上要跑起来可能性还是比较低的,所以后面就被预积分下来到一张图片上。

 

然后用法线与半角向量做点乘来得到u方向,用粗糙度来决定v方向来确定uv。

最后的高光是用菲涅尔和预积分以及半角向量的模的平方来决定的。

float ndotl = max(dot(N, L), 0); float PH = pow(2.0 * SAMPLE_TEXTURE2D(_BeckmannTex, sampler_BeckmannTex, float2(ndoth, m)).x, 10.0); float F = FresnelLerp(H, V, 0.028); float frSpec = max(PH * F / dot(h, h), 0.0); return ndotl * frSpec;

用这个作为高光分布,再乘高光颜色就得到了比较好看的高光了。

 

后来看了下这个高光缺少了一些东西,我会认为人的皮肤不是纳闷平滑的,人的皮肤总是有一些凹凸不平的细微的疙瘩,所以如果要做一个稍微粗糙点的人脸。

 

现在普遍做法要么是三角面处理,要么是贴图做细。如果都没有而且美术改起来麻烦的话也有一种方法,就是做一个噪音图采样,然后噪音图中像素比较亮的则现实高光,不然就显示比较弱的光。

 

specular *= scatterBlurNoiseTex

关注
打赏
1649603425
查看更多评论
立即登录/注册

微信扫码登录

0.0629s