PBR——概述、基于物理的材质

article/2025/9/16 16:36:37

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的精髓所在。


http://chatgpt.dhexx.cn/article/wor36MjW.shtml

相关文章

PBR基础理论通俗解释

PBR基础理论通俗解释 今天给大家介绍PBR的基础理论, 不会涉及比较深的具体算法, 算是一篇扫盲的文章, 尽量尝试说人话, 让大家能够对PBR有基本的了解. 什么是PBR? PBR是基于物理的渲染(Physically Based Rendering), 也就是说通过模拟物理世界的方式来渲染. 既然有基于物理…

基于物理的渲染PBR(一):pbr的基础理论和推导

初始PBR 最近刚接触pbr不久,我搜寻了许多文章进行阅读并了解后发现,pbr涉及到的知识点繁琐且不容易理解,所以想在博客上给自己记录并总结一下,方便以后回顾并加深记忆。 这里首先借用知乎上的大佬毛星云关于pbr所涉及到的知识要…

策略路由(PBR)

1、基本概念 PBR (Policy-Based Routing,策略路由): PBR使得网络设备不仅能够基于报文的目的IP地址进行数据转发,更能基于其他元素进行数据转发,例如源IP地址、源MAc地址、目的MAc地址、源端口号、目的端口号、VLAN-ID等等。 用户还可以使用A…

技术美术知识学习_04:PBR的个人理解

一、什么是PBR? PBR(Physically Based Rendering),中文翻译为基于物理的渲染。 PBR是一种渲染方式,是使用基于物理原理和微平面理论的光照模型,以及使用从现实中测量的表面参数来准确表示真实世界材质的渲…

图灵直播|《第一行代码》作者郭霖在线Coding,今晚八点,给你留位!

图源来自Pexels “我们为什么需要 Kotlin?答:消失的 Getter 和 Setter、又见空指针、Smart Cast、打日志、再见Utils、晚安ButterKnife……” 相信很多人初识Kotlin,都是基于谷歌技术大牛 Steve Yegge的一篇文章《为什么说 Kotlin 比你们用的…

撸了郭霖大神写的Framework源码笔记,offer拿到手软

前不久听我一个字节的朋友说了一个神转折的故事。 一名大专生,异常执着地向他们公司投简历,屡战屡败,屡败屡战,前前后后向字节跳动投了九次简历。 你猜后面怎么着?还真让他成功了,第九次居然拿到了offer! 看到这里,不过是一个普普通通的励志故事吧,一个菜鸡凭借自己…

(郭霖)Android图片加载框架最全解析(一),Glide的基本用法

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53759439 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新。 现在Android上的图片加载框架非常成熟,从最早…

图灵专访:郭霖的成长之路

各位小伙伴们大家早上好,最近这段时间我真的是快要忙疯了,好多件事情同时在做,实在抽不出时间写原创文章。 正巧想到前段时间和图灵做了一次专访,记录了一些我的成长经历。这篇专访姑且也可以算是一篇原创吧,因为里面的…

第一行代码-第二版(郭霖著)笔记十一(Material Design)

目录 一、什么是Material Design 二、Toolbar 三、滑动菜单 1.DrawerLayout 2.NavigationView 四、悬浮按钮和可交互提示 1.FloatingActionButton:悬浮按钮 2.Snackbar:提示工具 3.CoordinatorLayout:加强版FrameLayout 五、卡片式…

第一行代码-第二版(郭霖著)笔记二(Activity)

目录 一、Activity的用法 1.Activity 2.Toast 3.菜单 4.销毁一个活动 二、Intent 1.使用显示Intent 2.使用隐式Intent 3.更多隐式Intent的用法 4.向下一个活动传递数据 5.返回数据给上一个活动 三、活动的生命周期 1.返回栈 2.活动的四种状态 3.活动的生存期 4…

android动态权限依赖库,动态申请app权限:郭霖大神的PermissionX库带你告别原生

引言 为什么那么多人想要自定义Android的权限申请PermissonX?因为PermissionX默认的权限提醒弹出实在是太丑了!而且,需要在你需要提醒用户弹出Dialog时,显得捉襟见肘,你可能就在想有没有一款能封装进去Dialog提醒用户,具有超棒的用户体验,还能看起来美观大气的Permissio…

跟随郭霖学Volley

volley 下载导入volleyjar 学习地址: https://blog.csdn.net/guolin_blog/article/details/17482095 2013在Google I/O大会提出 github地址: https://github.com/google/volley 下载volley导入到as 具体的操作是: project模式下 具体看图: 之后的操作是打开lib 选择jar 右…

android 6.0权限 郭霖,Permission——郭霖认为最优的运行时权限方案

Android6.0发布这么久,对运行时权限也看了很多资料,对比过几个流行的库。但是个人还是喜欢在项目里用自己动手封装的东西,哪怕照抄也好。。。不知道是什么原因。 前天无意听郭神的直播。讲解的是运行时权限的封装,收益颇多。依样画…

郭霖LitePal

由于项目需要开始学习sqlite 一开始先学习使用的是 android ormlite 操作 从最基本的建表增删改查一路走来 磕磕碰碰很多 都是在内存中操作sqlite 只能通过sqlitestudio工具进行查看 不能导出 并且应用卸载数据表就丢失 最终考虑在sd卡中操作sqlite 但是ormlite 并没有这方面…

android郭霖博客,Runtime Permissions(郭霖CSDN公开课)

运行时权限 Api23开始,Android权限机制更改,有一部分权限不再是简单的在AndroidManifest.xml中声明即可。而是需要在运行时让用户去选择是否允许该项权限的操作。 那么哪些权限需要在运行时申请呢?危险权限需要这么做,而普通权限仍…

看一看Facebook工程师是怎么评价《第一行代码》的

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。 大家好,我是一名Facebook的工程师,同时也是《第一行代码——Android》的忠实读者。 虽然我最近几年是在国外读书和工…

郭霖:手把手教你实现 App 360 度旋转看车效果

这是郭神号前阵子的推送,应该有不少人还没有看过,现在分享给大家,希望对大家的Android工作和学习有所帮助。 / 作者简介 / 本篇文章来自Youth Lee的投稿,分享了他自己结合Glide写的一个控件,希望对大家有所帮助&#…

第一行代码-第二版(郭霖著)笔记(初识Android)

系列文章目录 第一章 第一行代码-第二版(郭霖著)笔记(初识Android) 目录 一、Android简介 1.android系统架构 2.Android应用开发特色 二、工具准备 Tips:新建项目的时候是否勾选use legacy android.support libraries 三、…

专访郭霖:成长无止境

留意文末赠书活动 嘉宾 | 郭霖 文 | 张霞 郭霖,Android开发工程师,Android GDE(Google认证开发者专家)。从事Android开发工作9年,有着丰富的项目实战经验,负责及参与开发过多款移动应用与游戏,开…

解决http响应状态为canceled

最近写登录的页面,发现通过ajax请求后台的时候,监控台返回该请求的状态是canceled。 原因 仅仅是由于之前为了在输入账号时让浏览器进行自动补全,而将原先的div更换为了form,而不巧的是之前的登录事件源使用的是button。 而至于为什么stat…