• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

PBR——概述、物理的材质

武飞扬头像
THRASH_T
帮助1

PBR概述

PBR,即Physically Based Rendering,主要分为基于物理的材质、基于物理的光照和基于物理的相机三个部分,目前来说对大家最为所熟知的是基于物理的材质部分。本文围绕基于物理的材质进行相关介绍。

什么是PBR

其实最早听说PBR这玩意,是在各种建模培训班的广告上听的。来某州、火*、x众学次世代PBR建模,挑战月薪过W…类似的广告数不胜数。那段时间对于PBR的认知是,一种建模的全套流程,从低模到高模接着拓扑然后烘培再到去Substance做贴图最后还去八猴做渲染的那一套ddc一条龙流程。与之相对的则是手绘建模流程。
这样理解PBR这个词不能说它完全错,但是是片面的。PBR是一套从上到下的流程,上游从图形、渲染开始,中间经历了Shader等,再到下游的美术资产制作,PBR贯穿着这一整套流程链,而非简简单单的烘个法线、画两张贴图就是PBR了。
至于为什么PBR能成为各大培训班的卖点呢?主要是以PBR流程制作出来的模型渲染之后“一眼顶真”,所以广受小白们的青睐。
那么为什么PBR能够以假乱真呢?这里就要引出PBR的概念了。PBR是基于物理的渲染过程,是一套着色和渲染技术,更精确低描述光如何与物体表面进行交互。PBR“基于物理”,是对现实的一种模拟仿真近似,所以渲染结果往真实的方向去靠拢。

为什么要PBR

PBR的好处是什么?
我将PBR的优点总结为真实性、易用性、广泛性。
真实性就是渲染的结果非常具有真实感。
随便从网上找了几张图让带伙大致感受一下PBR的效果。
学新通
学新通

PBR的材质便于设置。最简单的PBR只需要金属度和粗糙度两个参数就能让美术随手调出各种质感的材质。
Unity官方给了metallicroughness和specularglossiness两种工作流的图表,照着这张表设置参数很快就能出材质。
学新通
学新通
复杂一点的其他的参数来调更加牛逼的效果,这里提一嘴迪士尼原则
学新通
学新通

此外,便于统一美术的工作流程。而且事实上PBR流程已经得到了广泛的推广。现在随便去市面上找款三维软件都能看到PBR的身影。玛雅里面把standardsurface材质球拖出来再点下阿诺德渲染,油腻体里自带的标准/Lit材质,UE默认的标准材质,以及SP里的MetalRoughness工作流,都是PBR。所需要的那几张贴图,法线金属度粗糙度自发光环境光遮蔽透明度…制作一个模型需要用到哪些贴图,大家都已经达成共识。拿着这几张贴图去三维软件里对着材质面板一个个贴上去,就可以渲染出想要的效果。不想自己做材质?直接去Quixel、Substance、Bridge里面找别人做好的资产,下载下来就能直接用。写shader的要对材质进行修改,也以几个参数为基本框架即可,不必凭空从Unlit开始手撸。

基于物理的材质

几个重要理论

既然基于物理,那就先搬出几条物理理论

微表面理论

没有绝对光滑的表面,至少在微观层面,物体的表面是凹凸不平的。光与物体表面发生交互的过程,实际上就是在这些凹凸不平的表面发生反射、散射等过程。我们宏观上看到物体表面的光照,实际上是这些微表面发生的光线交互的结果的总和。
学新通

能量守恒

出射光能量永远不会大于入射光能量。
比如,随着粗糙度的提高,高光区域增加,亮度减小
学新通

学新通
一束光照到材质表面上,通常会分成反射部分和折射部分。反射部分直接从表面反射出去,而不进入物体内部,由此产生了镜面反射光。折射部分会进入物体内部,被吸收或者散射产生漫反射。折射进物体内部的光如果没有被立即吸收,将会持续前进,与物体内部的微粒产生碰撞,每次碰撞有一部分能量损耗转化成热能,直至光线能量全部消耗。有些折射光线在跟微粒发生若干次碰撞之后,从物体表面射出,便会形成漫反射光。在不考虑损失和散射的情况下,我们近似地认为入射光能量等于漫反射和镜面反射能量之和。

渲染方程

学新通

学新通

先贴出来,下文细嗦。

两种工作流

PBR有两种工作流

Metallic/Roughness

Metallic用来调节金属程度,本质上是对漫反射和镜面反射比例的控制,Roughness调节微表面法线的一致性。

Specular/Glossiness

Specular可以调节高光反射的颜色,Glossiness即光滑度,和粗糙度同理。

优缺点

高光工作流的优点在于对于高光的控制自由度更高,这可能导致不符合能量守恒。

BRDF

双向反射分布函数,和BTDF双向透射分布函数加起来即为BSDF双向散射分布函数。
学新通

BRDF描述的是在不同的入射光方向上,有多少光能被反射到指定的观察方向。
我们把上文渲染方程(其实是反射方程)的fr项单独拿出来,拆一下
学新通
再拆
学新通
学新通
代回去渲染方程
学新通
没那么头晕了吧?起码能从只看得懂一个个字母到几个字母凑一起也能大概知道表示的啥了。

然后就是老生常谈的解释各个字母了,当然此部分网上的许多文章已经讲得非常好了。

D项

法线分布函数,Normal Distribution Function
直接贴GGX公式
参数:normal,viewDir, lightDir, Roughness(即α)
注意:这里的粗糙度不是贴图里的粗糙度,从贴图里取出来的叫PerceptualRoughness,平方后才是放到shader里计算的粗糙度。下文中如无特别提及一般都是指平方后的粗糙度。
学新通
近似的表示了与某些(如中间)向量h取向一致的微平面的比率。
与常用的布林冯做个对比
学新通
学新通
拖尾更长,得到的高光更漂亮。

F项

菲涅尔方程,Fresnel Equation
参数:F0, normal, viewDir, lightDir
我们以前学过1-NdotV
学新通

但是由于我们需要的法线方向并不是模型本身的宏观法线n,而是经过D项筛这就是那条著名的Fresnel-Schlick公式
学新通
视线和平面越平行,反射现象越明显。万物均有菲涅尔。理论上,以与法线呈90°的视线方向观察物体都会出现全反射现象。

G项

几何遮蔽函数,Geometry Function
参数:normal, viewDir, lightDir, Roughness
描述几何体的自遮挡导致表面产生自阴影。
上公式
学新通
学新通

漫反射

c就是经典NdotL,Unity中的标准材质用了高级点的迪士尼公式,KD是漫反射系数,意义是满足能量守恒,KD=1-KS,KS即为F(所以上面的KS可以直接划掉)。

Unity中的V项

UnityURP中把DGF换成了DVF,V项用了改进后的Cook-Torrance函数,F项设置为1(但是KD不会直接变成0,而是为1,所以可以直接理解成忽略系数直接加起来)。这里不展开讲了,源码在lighting.hlsl

关于PI

回去看看渲染方程,除去brdf部分,有个Li表示入射光的能量,剩下的∫(ωi · n)dω=pi,和漫反射底下的除pi直接化掉就是我们常见的KD*NdotL。直接光高光也可以这样把D项简化掉。间接光不能直接化简
简单点理解漫反射下面的pi就是去配平∫(ωi · n)dω的,从物理意义上理解∫(ωi · n)dω就是我们要算的是半球上所有入射光方向 ωi 的积分

实现

简单的pbr框架包括直接光和间接光部分,而根据渲染方程两者又有各自的漫反射和镜面反射部分。

直接光

其实上面的理论讲完之后直接光就信手拈来了,直接brdf公式一套,直接光和间接光算出来,kd ks一乘或者学urp直接加起来就完事了

间接光

仅仅把直接光的brdf换成cook-torrance并不能叫pbr,间接光的实现方式才是pbr的精髓所在。谈到间接光更离不开IBL——基于图像的光照。它将周围的大环境当作光照,一般结合cubemap使用。

漫反射

学新通
稍微化简,把能提的先提出来。现在要做的是把积分搞定。这里我们要算一张辐照度图,它在每个采样方向——也就是纹素——中存储漫反射积分的结果
咋算呢?用卷积,简单来说就是对半球 Ω 上的大量方向进行离散采样并对其辐射度取平均值,来计算每个输出采样方向 wo 的积分。用来采样方向 wi 的半球,要面向卷积的输出采样方向 wo ,在此方向存储输出结果。在每个采样方向 wo 上存储其积分结果,可以理解为场景中所有能够击中面向 wo 的表面的间接漫反射光的预计算总和
学新通

镜面反射

学新通
一通操作把渲染方程中镜面反射部分化成现在这样,前一部分像漫反射那样算就好了,为了加入粗糙度的影响,要将得到的卷积结果存在不同的Mipmap中,得到的图叫预滤波环境贴图。
第二部分叫镜面积分
学新通
这张图叫BRDF积分图,是预计算好的BRDF值
学新通
那就可以用给定的粗糙度和n⋅ωi来预计算BRDF的值并存储于2D采样纹理(LUT)中,横坐标是n⋅ωi,纵坐标是粗糙度。2D采样纹理输出一个缩放(红色)和一个偏移值(绿色)给菲涅尔方程式

unity中的间接光

漫反射对光照探针进行采样,使用了球谐函数,给带伙截个urp源码
学新通
这些公式是啥呢?简单来说就是算球谐光照要用到一个叫伴随勒让德多项式的东西,Unity 使用了三阶的伴随勒让德多项式作为基函数,其在欧拉坐标系下长这样
学新通
以法线方向作为 x,y,z 其在球面上如图所示
学新通
看眼图,哦,大概就是不同方向下受到的光照。把光照烘焙到这些球面上之后,间接光就有了,照着源码取出来就行
至于代码里面变量的意思,unity_SHAr的3个分量对应于表中l=1的各项Y的红色光分量对应的c的乘积,最后一个分量对应于l=0时Y常数值与对应的c的乘积,unity_SHAg对应于绿光分量;untiy_SHAb对应于蓝光分量。

高光反射就是经典采样反射探针,可以理解成拿个360°相机把周围的环境照一遍,把照片按照粗糙度存在不同的miplevel,然后给物体表面采样,还要乘上cook-torrance和影响因子。直接去采样上面的那张LUT不太好,所以用一条和粗糙度有关的曲线去近似拟合。
反射探针的化有俩,unity_SpecCube0存的是场景的数据,unity_SpecCube1存的是离物体最近的Reflection Probes的数据。
把上述混合就是一个简单的pbr框架

不得不说,间接光这一套实现方法,从各种公式到探针,尽力将周围环境的影响表现出来,才是pbr的精髓所在。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgafgjj
系列文章
更多 icon
同类精品
更多 icon
继续加载