当前位置:网站首页>(待补充)GAMES101作业7提高-实现微表面模型你需要了解的知识
(待补充)GAMES101作业7提高-实现微表面模型你需要了解的知识
2022-06-24 19:24:00 【flashinggg】
目录
微表面材质模型
Microfacet Material,也是真实感材质模型,同时是PBR(Physicallly-Based-Rendering 基于物理渲染)基于的东西。
之前作业中涉及到的 BRDF,即Bidirectional Reflectance Distribution Function,双向反射分布函数,微表面模型就是基于物理的BRDF,也是最常用的一种物理BRDF,Disney Priciple BRDF中也加了
微平面理论 Microfacet Theory
下面是我结合课程内容对微平面理论的一些理解。
现实生活中,物体表面都是不规则的,离近了看会有坑坑洼洼的感觉,这就意味着这些坑坑洼洼的小表面反射的光方向都不同。但对于每个小表面来说,入射的光线只会被分为反射光和折射光。基于此,微表面模型假设:①微表面的尺寸小于着色区域大于可见光波长;物体表面从远处看是外观(diffuse、glossy),近处看是一个个微小的、平的几何面,②这些平坦的几何面都符合几何光学定律,可以看成是一个个非常小的镜子;③光线只在微表面之间弹射一次(single-bounce),一次之后弹射的光线不改变着色结果。(关于假设③,这里不考虑下图所示的光线多次弹射的情况,次表面散射技术后面会单独开一贴讲讲)
有了这些假设,解微表面材质模型的关键在于:解微表面朝向的分布,具体来说就是微表面的法线分布。如下图,对于两种典型的材质与法线分布的关系:法线集中->glossy;法线发散->diffuse。
微表面BRDF的实现
我们常用Cook-Torrance BRDF来实现Microfacet:
Cook-Torrance BRDF
Cook-TorranceBRDF考虑了微表面的漫反射和镜面反射,公式如下:
其中:——折射光占入射光比例;
——反射光占入射光比例;
——漫反射(diffuse)的BRDF;
——镜面反射(specular)的BRDF;
漫反射项
漫反射的BRDF是个常数项,漫反射朝半球方向均匀弹出,由之前GAMES101课的辐射度量学计算出来的结果,可以直接写出漫反射的计算式:
镜面反射项
公式如下:
其中,为入射方向;
为出射方向;
为半角向量(halfway vector),即二者中间向量;
为菲涅尔项;
为阴影遮挡函数;
为法线分布函数。
值得一提的是,Cook-Torrance BRDF模型的镜面反射项(specular reflection)是根据Torrance-Sparrow BRDF描述的完整各向同性材质反射模型,再将他应用于图形学得到的。这一项值用来刻画材质的高光。漫反射diffuse项用来刻画材质的着色,下面分别对漫反射项
接下来分别对法线分布函数、阴影遮挡系数和菲涅尔项做介绍。
1 法线分布函数 D
首先要明确一点的是,法线分布函数有Phong分布、Beckmann分布、GGX分布(Trowbridge-Reitz 分布),下文中将只结合GGX分布来介绍法线分布函数。
法线分布函数(Normal Distribution Fuction),NDF,记作:.关于法线分布函数的定义,How Is The NDF Really Defined? – Nathan Reed’s coding blog中是这么描述的:“NDF statistically describes the microscopic shape of the surface as a distribution of microfacet orientations.”,即:把微表面的形状描述为表面朝向的分布。目前,主流的法线分布函数已经从传统的Blinn-Phong分布和Beckmann分布,发展到更接近真实世界材质外观的GGX分布。
GGX分布简介
简单介绍一下GGX这个符号,GGX我们经常在各种地方看到。其实GGX分布是Walter等人在论文Microfacet Models for Refraction through Rough Surfaces (cornell.edu)
中提到的一个新的微表面分布函数,该函数能够模拟出粗糙表面的透射效果,下图是论文中展示的利用GGX渲染出的一个玻璃球效果图:
GGX分布是Walter等人的提出的,其认为NDF遵循以下方程:
其中,——表示宏观(远处看)表面一小块平的区域;
——方向是
的所有小的平的区域的总面积。
这个公式就可以看出,NDF并不表示密度,而是单位面积、单位立体角的微平面的面积。对上式积分:
其中,——微表面投影到宏观表面上的面积;式右边表示正半球立体角的积分,左边表示在所有朝向
的微平面面积和,且宏观表面所有方向上的微表面投影面积和等于
。因此式右边应等于1.
此外,GGX分布还有一个限制条件:对于任意观察方向,有:
该式的几何意义如下图:
可以看到,在方向上,要想求在宏观表面上的投影面积,如果如上图所示中朝向为橙色箭头的微表面,求投影后会正负抵消,剩下的就是朝向是蓝色箭头的微表面的投影和。因此投影可以表示为
。
Trowbridge-Reitz 分布(GGX分布) 公式
又称为GGX分布,论文Microfacet Models for Refraction through Rough Surfaces中给的形式为:
化简后得到可以用于计算的式子:
其中:
:表面粗糙度,一般在[0,1]之间,越大越粗糙;
:宏观表面法向量;
:微平面法向量,与上文相同,即入射方向和出射方向的中间向量。
表面粗糙度
的取值
关于表面粗糙度的取值,参考文章中是这么说的:“在迪士尼原理着色模型Disney principled shading model中,推荐将粗糙度控制以暴露给用户,其中
是0到1的用户界面粗糙度参数值,可以让GGX分布更线性的方式变化,且这种方式更加实用,不少使用GGX分布的引擎与游戏都采用了这种映射方式。”这里的
表示
,粗糙度.
实现代码
float DistributionGGX(float NdotH, float roughness) {
float a2 = roughness * roughness;
float pi = 3.1415;
float m = NdotH * NdotH * (a2 - 1) + 1;
return a2 / (pi * m * m);//注意分母不能为0,真正使用需要给定一个最小值
}
了解到这里,已经足够写出GGX密度分布函数的代码了,如果想要深入了解公式如何推到的,可以细看论文中的推导过程。
到这里我们就能理解了:为什么说与Phong和Beckmann相比,GGX更接近真实情况呢?因为GGX可以更好的表现金属高光边缘的消散(拖尾)效果,这里可以参考图形渲染基础:微表面材质模型 - 知乎 (zhihu.com)一文中的解释:
由于GGX的高光有更长的拖尾,因此在表现真实金属表面的时候更胜一筹。
2 阴影遮挡函数 G
微表面是凸凹不平的,从不同观察方向看难免会产生一个表面被另一个表面遮挡的情况(如下图,图源水印)。其中,光照illumination遮挡称为自阴影;从视线viewing看过去被遮挡叫做自遮挡。
BSDF定义了一个几何函数 用以模拟微表面由于相互遮挡而导致光线的能量丢失的现象,这个函数就叫做阴影遮挡函数,从定义不难看出,这个函数的取值应该也是从[0,1]的。同时,几何函数有两种形式:
——微平面在单个方向(光照方向
or视线方向
)上可见比例,光照对应遮蔽函数 masking function;视线对应阴影函数 shadowing function.
——微平面在光照和视线方向共同可见的比例,称为联合遮蔽阴影函数 joint masking-shadowing function.
其中,由
推导而来,同时一般微表面材质计算所说的几何函数就是指
Smith遮蔽函数
Smith遮蔽函数,即Smith masking function。由于自阴影本质与自遮挡是一样的,都是可见微表面才能对着色有贡献,因此Smith认为二者是相互独立的,有了如下的乘积的Smith Function:
其中 分别表示入射和出射方向,对应的话就是光源和观察方向。
Smith遮蔽函数对于随机表面的非常准确,但对于一些非随即表面、重复性的图案表现精度会降低(例如面料这种高重复性的结构)。因此在进行布料这种重复性结构图案一般会采用一些专门的shading model去计算。
Disney实现方法
参考上图, 定义函数,,表示法线方向为
的微表面们在观察方向
上未被遮挡的比例。根据上述已经讨论过的一个GGX的规定,对于任意观察方向
,有:
那么就有:
其中,用来剔除背向观察方向的微表面。
记下来为了简化的计算,假设其与微表面朝向无关,可以把它提出来。再通过与视线夹角大于和小于
的微表面面积和都表现出来,分别命名为
和
,得到:
根据该式,结合能推导出准确的
.
其中:,将粗糙度重映射以减少光泽面的极端增益,使粗糙度变化更加平滑。
实现代码
//对G1的实现
float SmithG_GGX(float NdotV, float roughness) {
float r = 0.5 + roughness / 2.0f;
float m = r * r + (1 - r * r) * NdotV * NdotV;
return 2.0f * NdotV / (NdotV + std::sqrt(m));
}
//光源方向和观察方向分别计算ggx1和ggx2,相乘得到G
float GeometrySmith(Vector3f N, Vector3f V, Vector3f L, float roughness) {
float NdotV = std::max(dotProduct(N, V), 0.0f);
float NdotL = std::max(dotProdoct(N, L), 0.0f);
float ggx1 = SmithG_GGX(NdotL, roughness);
float ggx2 = SmithG_GGX(NdotV, roughness);
return ggx1 * ggx2;
}
UE4方法-SchlickGGX
UE4采用的方法是用Schlick近似Smith来计算几何函数,具体怎么算的可以参考这篇文章:
图形学|PBR:Schlick近似方法 - 知乎 (zhihu.com)
其中:
实现代码
float GeometrySchlickGGX(float NdotV, float roughness) {
float r = roughness + 1;
float k = r * r / 8;
float m = NdotV / NdotV * (1.f - k) + k;
return NdotV / m;
}
//光源方向和观察方向分别计算ggx1和ggx2,相乘得到G
float GeometrySmith(Vector3f N, Vector3f V, Vector3f L, float roughness) {
float NdotV = std::max(dotProduct(N, V), 0.0f);
float NdotL = std::max(dotProdoct(N, L), 0.0f);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
return ggx1 * ggx2;
}
除了以上两种方法还有其他的,想了解的话可以看看这篇文章:PBR GGX Specular G 几何函数 - 掘金 (juejin.cn)
3 菲涅尔项 F
就是计算反射光占比。对于菲涅尔效应和菲涅尔项的计算在作业5中有介绍,这里就不赘述了,直接贴代码,想要了解的可以移步GAMES101作业5-从头到尾理解代码&Whitted光线追踪_flashinggg的博客
实现代码
这里直接贴出框架中菲涅尔项的计算函数:
//菲涅尔方程,与作业5相同
void fresnel(const Vector3f &I, const Vector3f &N, const float &ior, float &kr) const
{
float cosi = clamp(-1, 1, dotProduct(I, N));
float etai = 1, etat = ior;
if (cosi > 0) { std::swap(etai, etat); }
// Compute sini using Snell's law
float sint = etai / etat * sqrtf(std::max(0.f, 1 - cosi * cosi));
// Total internal reflection
if (sint >= 1) {
kr = 1;
}
else {
float cost = sqrtf(std::max(0.f, 1 - sint * sint));
cosi = fabsf(cosi);
float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost));
float Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost));
kr = (Rs * Rs + Rp * Rp) / 2;
}
什么是BSDF
BSDF(Bidirectional Scattering Distribution Function,S表示的就是“散射”),描述了光如何在物体表面散射,反映了光入射和出射强度的对应关系。之前我们涉及到的反射模型BRDF和透射模型BTDF(T指Transmittance,透射)是BSDF分别只限制了反射和透射的模型结果。BSDF本身是BRDF和BTDF综合作用。
Disney Principle BRDF
Disney有一套自己的基于微表面理论的BRDF实现模型,形式如下:
其中:DIFFUSE——非金属的次表面散射
看到这里,实现作业7中的微表面材质提高部分就没问题了,会另开一贴介绍具体的实现代码.
以及之后会再总结一下微表面材质学习引出的其他拓展内容,例如PBR除了微表面其他的内容是什么?Disney Principle是什么?等等...
参考
图形渲染基础:微表面材质模型 - 知乎 (zhihu.com)
【基于物理的渲染(PBR)白皮书】(四)法线分布函数相关总结 - 知乎 (zhihu.com)
How Is The NDF Really Defined? – Nathan Reed’s coding blog (reedbeta.comd
边栏推荐
- Intelligent fish tank control system based on STM32 under Internet of things
- JMeter basic learning records
- 基于STM32的物联网下智能化养鱼鱼缸控制控制系统
- The first day of handwritten RPC -- review of some basic knowledge
- Codeforces Round #720 (Div. 2)
- Volcano becomes spark default batch scheduler
- Oauth2.0 introduction
- Remember the frequently forgotten problem of continuously reading pictures -%04d
- Splicing audio files with ffmpeg-4.3
- regular expression
猜你喜欢
Php-pdo parameter binding problem
基于STM32的物联网下智能化养鱼鱼缸控制控制系统
Appium introduction and environment installation
The virtual currency evaporated $2trillion in seven months, and the "musks" ended the dream of 150000 people becoming rich
XTransfer技术新人进阶秘诀:不可错过的宝藏Mentor
Appium desktop introduction
Return of missing persons
【产品设计研发协作工具】上海道宁为您提供蓝湖介绍、下载、试用、教程
Oauth2.0 introduction
Summary of message protocol problems
随机推荐
Dijkstra seeking secondary short circuit (easy to understand)
Use of kubernetes storage volumes
HCIA assessment
memcached全面剖析–2. 理解memcached的内存存储
Memcached comprehensive analysis – 3 Deletion mechanism and development direction of memcached
123. 买卖股票的最佳时机 III
基于STM32的物联网下智能化养鱼鱼缸控制控制系统
Why are life science enterprises on the cloud in succession?
Static routing job supplement
Rip/ospf protocol notes sorting
Pattern recognition - 0 introduction
Advanced secret of xtransfer technology newcomers: the treasure you can't miss mentor
DHCP operation
Interpretation of ebpf sockops code
Call process of package receiving function
Reflect package
Pytest test framework II
Alibaba cloud lightweight servers open designated ports
Please open online PDF carefully
Docking of arkit and character creator animation curves