Based Rendering之specular BRDF

在实时渲染中Physically-Based Rendering(PBR)中文为基于物理的渲染它能为渲染的物体带来更真实的效果,而且能量守恒

稍微解释一下字母的意思,为对后文的理解有帮助,从右到左L为光线方向,H为半角向量,L是和V的中间,N为法线方向,V为我们眼睛的观察方向(相机看的方向),,R为反射方向Torrance-Sparrow光照模型的镜面反射公式

D为法线分布函数(NDF)F为反射函数(Fresnel 函数)G为阴影遮罩函数(几何函数),未被shadow或mask的比例此处的E就是上面的VCook-Torrance光照模型的镜面反射公式

接下来我们只用Cook-Torrance光照来做实验通常来说BRDF是关于表面多种属性的反射结果之间的线性组合(在实时渲染中一般只考虑diffuse和specular两种即可)这是unity的specular

看起来是不是特别像塑料?还是粗糙的塑料接下来我们就来讨论D函数的不同带来的specular的不同BlinnPhong的分布函数Call of Duty : black Ops 2/使命召唤:黑色行动2就使用了它

在中说明Microfacet 微平面模型是广泛应用的对rough surface建模的工具, blinn,ward,beckmann都属于microfacet的推导结果。基本思想也很简单,就是用很小的微平面的组合去模拟粗糙的物体表面。而这些微小的平面元则可以当做完美的反射或者折射表面。每个microfacet把一个入射方向的光反射到单独的一个出射方向,这取决于microfacet的法向m。当计算BRDF的时候,光源方向l和视线方向v都得给定。这意味着在表面上的所有microfacet中,只有刚好把l反射到v的那部分对BRDF有贡献。在下图中,我们可以看到这些有效microfacet的表面法向m正好在l和v的中间,也就是h。

D为法线分布函数(NDF),在大部分表面上,microfacet的方向不是均匀分布的。Microfacet的法线越接近宏表面的法线,就越光滑。这个分布由microfacet的法线分布函数D(m)来定义。函数D()决定了specular高光的大小、亮度和形状。 法线分布函数一般有类似于“粗糙度”这样的参数。F为反射函数(Fresnel 函数),计算光学上的反射比率。分母4(nl)(nv)是个校正因子,用来校正从microfacet的局部空间转到整体表面的数量差异。V为能见度函数,阴影遮罩分类为透视缩减关于G ,%E5%9F%BA%E4%BA%8E%E7%89%A9%E7%90%86%E7%9A%84BRDF给出了解释

G为阴影遮罩函数(几何函数),未被shadow或mask的比例在上半部分,平的宏表面为绿色,粗糙的微观表面为蓝色。m = h的 microfacet标记为红色。宏表面投到视线方向就是左上角的绿线。同时,投出来的单个红色的microfacet显示成独立的红线。左下图表示在没 有遮挡项的情况下,红色的microfacet加起来的面积,结果就是有效面积大于总面积,所以BRDF的反射能量错误地大于了接收能量。右下图里红色区 域考虑了遮挡,重叠的区域不再计算多次,所以有效面积小于总面积。

α为Specular的强度,Specular的强度是根据光泽度gloss确定的Schlick提出的fresnel方法:

rf0是反射颜色,也是roughness粗糙程度遮挡项使用了Schlick-Smith提出的方法

处于能量守恒考虑,漫反射多了镜面反射就要少,反之亦然所以:

效果如下:

看起来很像抛光的大理石效果吧主要代码如下:插入代码:#define PIE 3.1415926535float4 frag(v2f i) :COLOR{float3 viewDir = normalize(i.viewDir);float3 lightDir = normalize(i.lightDir);float3 H = normalize(lightDir + viewDir);float3 N = normalize(i.normal);float d = (_SP + 2) / 8 * pow(dot(N, H), _SP) / 4 * PIE;float f = _SC + (1 – _SC)*pow((1 – dot(H, lightDir)), 5);float k = 2 / sqrt(PIE * (_SP + 2));float v = 1 / ((dot(N, lightDir)*(1 – k) + k)*(dot(N, viewDir)*(1 – k) + k));float all = d*f*v;float3 c = tex2D(_MainTex, i.uv_MainTex);float3 diff = dot(lightDir, N);diff = (1 – all)*diff;return float4(c *(diff+all), 1) * _LightColor0;}_SC 为specularcolor,_SP为specularpowerPhong的分布函数

为D值(NDF)cosθ值为N与H的点积,以下皆是如此,H为半角向量,也就是light direct光线方向和view direct视角的一半。α即为本函数的specular power

这是不同specular power的实现曲线,越高代表约粗糙,越低代表约光滑效果也很不错

核心代码如下:float d = (_SP + 2) / 8 * pow(dot(N, H), _SP)/(2*PIE);Beckmann的分布函数你必须百分之百的把自己推销给自己。

Based Rendering之specular BRDF

相关文章:

你感兴趣的文章:

标签云: