Chapter18 基于物理的渲染——Shader入门精要学习
Chapter18 基于物理的渲染
- 一、PBS理论和数学基础
- 1.光是什么
- 微表面模型
- 2.渲染方程
- 3.精确光源
- 4.双向反射分布函数 BRDF
- 5.漫反射项
- (Lambert 模型)Lambertian BRDF为:
- Disney BRDF中漫反射项
- 6.高光反射项
- 微面元理论
- BRDF的高光反射项
- ①菲涅尔反射函数
- ②法线分布函数
- ③阴影-遮挡函数
- 7.PBS中的光照
- 8.Unity中PBS实现
- 二、Unity的Standard Shader
- 1.如何实现
- 2.如何使用
- 三、复杂例子
- 1.设置环境光照
- 2.设置反射探针
- 3.设置材质
- 4.设置线性空间
一、PBS理论和数学基础
1.光是什么
光是一种电磁波,由光源射出,与场景中的物体相交,一部分被吸收,一部分被散射,最后被感应器(眼睛等)吸收成像。光的传播方向会受到介质折射率的影响,折射率突变会导致散射现象。
我们一般假设两个介质的边界是无限大并且光滑的。用菲涅尔等式来描述光的反射与折射的各自占比

微表面模型
- 微表面模型:真实物体表面由许多微小的凹凸不平的表面组成,这些表面称为微表面,微表面模型假设每个微表面都是光学平滑的
- 光滑表面反射光线方向变化小,高光反射清晰;粗糙表面反射光线方向变化大,高光反射模糊

- 金属材质所有被折射的光会被吸收,转化为其他能量;非金属材质一部分会吸收,一部分又会散射到外部,散射出去的光叫做 次表面散射光(subsurface-scattered light)

- 次表面散射距离:次表面散射光从内部射出的位置与入射点之间的距离称为次表面散射距离

由于像素大小有限,如果次表面散射距离小于像素大小,可以忽略次表面散射光的影响,在局部范围内进行渲染;如果次表面散射距离大于像素大小,则需要使用特殊的渲染技术来模拟次表面散射效果——次表面散射渲染技术
2.渲染方程
- 辐射率 radiance:单位面积、单位方向上光源的辐射通量,用L来表示,被认为是单一光线的亮度和颜色评估
- 着色(shading)过程:通常使用入射光线的 L i L_{i} Li 来计算出射光线 L o L_{o} Lo
- 渲染方程:给定观察视角v,该方向上的出射辐射率 L o L_{o} Lo = 该点向观察方向发出的自发光辐射率 L e L_{e} Le + 所有有效入射光 L i ( ω i ) L_{i}(\omega_{i}) Li(ωi) 到达观察点的辐射率积分和

在实时渲染中,自发光项通常是直接加上某个自发光值,累加部分也基本无法实现,因此积分部分基本会被若干精确光源的叠加所替代,而不需要计算所有入射光线在半球面上的积分
3.精确光源
在实时渲染中,会用 精确光源 来近似模拟面光源 —— 点光源、平行光、聚光灯等。用 l c l_{c} lc 来表示方向,使用 c l i g h t c_{light} clight 来表示颜色,使用下面等式来计算在某个观察方向v上的出射辐射率:

若场景中包含多个点光源,把它们结果相加即可

- f ( l c , v ) f(l_{c},v) f(lc,v) :当给定入射光方向后,有多少百分比的光照被反射到了观察方向上——双向反射分布函数
4.双向反射分布函数 BRDF
-
两种理解 f ( l , v ) f(l,v) f(l,v)
- 给定入射角度 l 后,BRDF可以给出所有出射方向上的反射和散射光线的相对分布情况
- 给定出射角度 v 后,BRDF可以给出所有入射方向到该出射方向的光线分布
- (更直白)当一束光沿着入射方向 l 到达表面某点时, f ( l , v ) f(l,v) f(l,v) 表示有多少能量被反射到了观察方向上
-
BRDF是基于物理的:满足交换律和能量守恒
- 交换律:交换 l 和 v 后不变 f ( l , v ) = f ( v , l ) f(l,v) = f(v,l) f(l,v)=f(v,l)
- 能量守恒:表面反射能量不能超过入射能量 ∫ Ω f ( l , v ) ( n ⋅ l ) d ω o ≤ 1 \int_{Ω}{}f(l,v)(n·l)d\omega_{o} ≤ 1 ∫Ωf(l,v)(n⋅l)dωo≤1
BRDF可以用于描述两种物理现象:表面反射(高光反射项)和次表面散射(漫反射项)

5.漫反射项
(Lambert 模型)Lambertian BRDF为:
c d i f f c_{diff} cdiff: 表示漫反射光线所占比例——漫反射颜色;
除以 π \pi π :假设漫反射在所有方向上的强度都是相同的,而BRDF要求半球内的积分值为1。

给定入射方向 l 的光源在表面某点的出射漫反射辐射率值为:

Disney BRDF中漫反射项

- baseColor 是表面颜色,通常由表面纹理采样得到
- roughness 是表面粗糙度。
- 使用了 Schlick 菲涅尔近似等式来模拟在掠射角的反射变化,同时使用了表面粗糙度来改变 —— 使得光滑材质在掠射角具有更为明显的阴影边,又使得粗糙材质在掠射角具有亮边
6.高光反射项
微面元理论
计算BRDF时,入射方向 l 和 出射方向 v 都会被给定,只有一部分微面元反射的光线会进入我们眼睛中,即它们的法线 m 等于 l 和 v 的一半,即半程向量 h;这些微面元反射也不一定会全部被添加到BRDF中,因为可能出现其他面元遮挡的情况
BRDF的高光反射项


- D ( h ) D(h) D(h):微面元的法线分布函数 NDF——计算有多少比例的微面元法线满足 m = h
- G ( l , v , h ) G(l,v,h) G(l,v,h):阴影-遮掩函数——计算满足 m = h 的微面元中有多少不会被遮挡(活跃微面元的所占浓度)
- F ( l , h ) F(l,h) F(l,h):菲涅尔反射——反射光线占入射光线的比率
- 分母 4 ( n ⋅ l ) ( n ⋅ v ) 4(n·l)(n·v) 4(n⋅l)(n⋅v):于校正从微面元的局部空间到整体宏观表面数量差异的校正因子
①菲涅尔反射函数
描述了当光照方向和观察方向夹角逐渐增大时高光反射强度增大的现象
- Schlick 菲涅尔近似等式

- c s p e c c_{spec} cspec 是材质的高光反射颜色
②法线分布函数
值是非负的标量,决定了高光区域的大小、亮度和形状
- Blinn-Phong 模型:(归一化的Phong法线分布函数)
- g l o s s gloss gloss 是表面粗糙度相关参数
- 是一种经验模型,不能真实反映真实世界

- GGX分布(Trowbridge-Reitz法线分布函数)
- α \alpha α是表面粗糙度参数
- 具有更明亮、更狭窄且拖尾更长的高光区域

- GTR分布(Generalized-Trowbridge-Reitz法线分布函数),把分母指数的2变为可调参数
- Disney 还发现让 α = r o u g h n e s s 2 \alpha = roughness^{2} α=roughness2可以在粗糙度上得到更加线性的变化
③阴影-遮挡函数
G ( l , v , h ) G(l,v,h) G(l,v,h) 也被称为几何函数,具有给定面法线 m 的微面元在沿着入射方向 l 和观察方向 v 上不会被其他微面元挡住的概率,是一个0~1的概率值
习惯把 G ( l , v , h ) G(l, v, h) G(l,v,h) 和高光反射项的分母 ( n ⋅ l ) ( n ⋅ v ) (n ⋅ l)(n ⋅ v) (n⋅l)(n⋅v) 部分结合起来,即把 G ( l , v , h ) / ( n ⋅ l ) ( n ⋅ v ) G(l, v, h)/(n ⋅ l)(n ⋅ v) G(l,v,h)/(n⋅l)(n⋅v) 的部分合在一起讨论,称这个合项为可见性项(visibility term)
- Smith 模型(为GGX设计的)
- θ v \theta_{v} θv 表示观察方向 v 和表面法线 n 之间的夹角

- θ v \theta_{v} θv 表示观察方向 v 和表面法线 n 之间的夹角
- Smith-Joint 模型
Λ(ωo) 和 Λ(ωi) 分别评估出射方向和入射方向上的阴影和遮掩,基于这种分开计算的 Λ(ωo) 和 Λ(ωi)的 Smith 模型
7.PBS中的光照
随着新的技术不断被提出,实时面光源也不再是一个奢侈的梦想
- 基于图像的光照(imag-based lighting,IBL)
- 是把场景中远处的光照存储在类似环境贴图的图像中
- 环境贴图可以表示光滑物体表面反射的环境光
- 在 Unity 中,这种光照通常是由反射探针(Reflection Probes)机制来实现的,我们可以在 Shader中获取当前物体所在的反射探针并在需要时对它们的采样结果进行混合
8.Unity中PBS实现
基于GGX模型,与Disney BRDF中的漫反射项相同
- 漫反射项:

- 高光项:
- 菲涅尔反射函数

- 法线分布函数

- 阴影-遮掩函数(Smith-Joint 模型)
Λ(ωo) 和 Λ(ωi) 分别评估出射方向和入射方向上的阴影和遮掩,基于这种分开计算的 Λ(ωo) 和 Λ(ωi)的 Smith 模型
- 菲涅尔反射函数
二、Unity的Standard Shader
Unity创建模型或者材质时,默认着色器都是一个名为Standard 的着色器——基于物理的渲染
- Unity支持的两个工作流:金属工作流(metallic workfollow)和高光反射工作流(specular workflow)
- 金属工作流:定义了材质表面的金属值(是金属类型的还是非金属类型的)
- 高光反射工作流:可以直接指定表面的高光反射颜色(有很强的高光反射还是很弱的高光反射)等
1.如何实现
Standard.shader 和 StandardSpecular.shader
- SubShader:都定义了两个SubShader
- 第一个定义了前向渲染路径和延迟渲染路径的Pass,以及用于投射阴影和提取元数据的Pass
- 第二个定义了四个Pass,两个用于前向渲染路径,一个用于提取投射阴影,另一个用于提取元数据(相比于第一个取消了一些计算——视差贴图、不计算软阴影等)
- 两个shader最大的区别在于设置BRDF的输入时,使用了不同的函数来设置各个参数—— MetallicSetup 和 SpecularSetup
2.如何使用
- 需要在 Edit →Project Setttings→Player→Other Settings→Color Space 中选择Linear 才可以,这是因为基于物理的渲染需要使用线性空间
三、复杂例子

1.设置环境光照
- 使用 HDR 格式的 Skybox 可以让场景中物体的反射更加真实,有利于我们得到更加可信的光照效果
- 实时全局光照 GI 系统,场景中的物体可以接受直接光照和间接光照的影响
- 直接光照:需要保证平行光的方向和 Skybox 中的太阳或其他光源的位置一致,使得物体产生的光照信息可以与 Skybox 互相吻合
- Mode 设置:
- Realtime 模式进行实时的光照计算;
- Baked模式烘焙到一张光照纹理(lightmap)中,物体移动时阴影等光照效果不改变;
- Mix模式混合使用实时模式和烘焙模式,它会把场景中的静态物体(即那些被标识为 Static 的物体)的光照烘焙到光照纹理中,但仍然会对动态物体产生实时光照
- 间接光照:Indirect multiplier可以调整间接光强度
2.设置反射探针
- 在实时渲染中,我们经常使用Cubemap来模拟反射效果,但是当物体移动时,就容易穿帮——可以使用反射探针
- 反射探针的工作原理:它允许我们在场景中的特定位置上对整个场景的环境反射进行采样,并把采样结果存储在每个探针上
- 探针有三种类型:
- Baked:提前烘焙,只会处理那些静态物体(标识为 Reflection Probe Static)
- Realtime:实时更新当前的 Cubemap,并且不受静态物体还是动态物体的影响
- Custom:既可以让我们从编辑器中烘焙它,也可以让我们使用一个自定义的 Cubemap 来作为反射映射,但自定义的 Cubemap 不会被实时更新
- 反射探针应该被放置在那些具有明显反射现象的物体的旁边,或是一些墙角等容易发生遮挡的物体周围
- 反射探针还可以模拟互相反射
3.设置材质
真实可信的渲染效果,我们需要为场景中的物体指定合适的材质
4.设置线性空间
线性空间可以得到更加真实的效果
相关文章:
Chapter18 基于物理的渲染——Shader入门精要学习
Chapter18 基于物理的渲染 一、PBS理论和数学基础1.光是什么微表面模型 2.渲染方程3.精确光源4.双向反射分布函数 BRDF5.漫反射项(Lambert 模型)Lambertian BRDF为:Disney BRDF中漫反射项 6.高光反射项微面元理论BRDF的高光反射项①菲涅尔反射…...
DolphinScheduler学习
1.查看文档 点击访问:https://dolphinscheduler.apache.org/zh-cn/docs 我们可以看到相关的文档简介里有 介绍 DolphinScheduler是Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景,提供了一个可视化…...
我用Tauri开发的待办效率工具开源了!
开源仓库地址 gitee Git仓库地址:https://gitee.com/zhanhongzhu/zhanhongzhu.git 应用地址 windows应用地址下载 https://kestrel-task.cn 具体内容 也可以看🎉使用Taurivitekoa2mysql开发了一款待办效率应用 这篇文章。 💻技术栈 Tauri: Tauri…...
【黑科技】:Laravel 项目性能提升 20 倍
令人激动的黑科技:Laravel 项目性能提升 20 倍 这个项目能够在无需修改任何代码且无需第三方扩展的前提下,将你的 Laravel 项目性能提高 20 倍。它仅依赖于 PHP 原生的 pcntl、posix、fiber 和 sockets。 项目灵感 起因是看到官方发布的 PHP 8.1 更新…...
User Allocation In MEC: A DRL Approach 论文笔记
论文:ICWS 2021 移动边缘计算中的用户分配:一种深度强化学习方法 代码地址:使用强化学习在移动边缘计算环境中进行用户分配 目录 Ⅰ.Introduction II. MOTIVATION-A.验证假设的观察结果 II. MOTIVATION-A Motivating Example 数据驱动…...
leetcode 69. x 的平方根
可以使用二分查找法或牛顿迭代法来实现 LeetCode 问题 69. x 的平方根。下面是使用二分查找法和牛顿迭代法的 C 实现。 二分查找法 #include <iostream>class Solution { public:int mySqrt(int x) {if (x 0) return 0;int left 1, right x, ans 0;while (left <…...
基于词级ngram的词袋模型对twitter数据进行情感分析
按照阿光的项目做出了学习笔记,pytorch深度学习实战项目100例 基于词级ngram的词袋模型对twitter数据进行情感分析 什么是 N 符? N 格是指给定文本或语音样本中 n 个项目的连续序列。这些项目可以是音素、音节、字母、单词或碱基对,具体取…...
Linux-Centos-改密码(单用户登陆)
笔记一: centos7单用户修改root密码 在CentOS 7中,如果您是唯一的用户或者您确信其他用户不会登录,您可以按照以下步骤来修改root密码: 1.重启系统。 2.启动时出现引导界面时,按任意键进入GRUB菜单。 3.选择要启动的内…...
java实现OCR图片识别,RapidOcr开源免费
先看一下识别效果(自我感觉很牛逼),比Tess4J Tesseract省事,这个还需要训练,安装软件、下载语言包什么的 很费事,关键识别率不高 RapidOcr不管文字的横竖,还是斜的都能识别(代码实现…...
PCB工艺边设计准则
在PCB设计时,通常会在电路板的边缘预留一定的空间,这部分空间被称为工艺边。它有助于在生产过程中确保电路板的尺寸和形状的准确性。以使得组装时更加顺畅、便捷。而工艺边的加工,使得线路板上的元件可以精准地与设备对接,从而提高…...
CTF-NSSCTF题单[GKCTF2020]
[GKCTF 2020]CheckIN 这道题目考察:php7-gc-bypass漏洞 打开这道题目,开始以为考察反序列化,但实际并不是,这里直接用$_REQUEST传入了参数便可以利用了。这里出现了一个eval()函数,猜测考察命…...
redis的分片集群(仅供自己参考)
前言:为什么使用分片集群:因为redis的主从和哨兵机制主要是用来解决redis的高并发读的问题,还有redis的高并发的写的问题没有解决。使用分片集群就可以很好的解决redis写的问题,有多个master就可以实现并发的写。同时,…...
自动驾驶-机器人-slam-定位面经和面试知识系列01之常考公式推导(01)
李群李代数扰动bundle adjustment 这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新,基本涵盖了自己秋招历程被问过的面试内容(除了实习和学校项目相关的具体细节)。在知乎和牛客也会同步更新,全网…...
netty入门-5 ServerBootstrap与Bootstarp
前言 本来这篇应该紧接着说明Future和Promise。 但是考虑前文第三篇即用到了ServerBootstrap来启动一个服务器,并且我读的闪电侠netty,先写的服务器与客户端启动这部分。索性就先写出来了。主要内容来自闪电侠netty ServerBootstrap ServerBootstrap就…...
JavaEE - Spring Boot 简介
1.Maven 1.1 什么是Maven 翻译过来就是: Maven是⼀个项⽬管理⼯具。基于POM(Project Object Model,项⽬对象模型)的概念,Maven可以通 过⼀⼩段描述信息来管理项⽬的构建,报告和⽂档的项⽬管理⼯具软件。 可以理解为:Maven是一个项目管理工具…...
SwiftUI革新:Xcode UI开发的新纪元
SwiftUI革新:Xcode UI开发的新纪元 SwiftUI作为Apple推出的声明式UI框架,彻底改变了在Xcode中构建用户界面的方式。它不仅简化了代码,还提高了开发效率,并且使得UI设计更加直观和灵活。本文将深入探讨如何在Xcode中使用SwiftUI进…...
22、基于共享内存的数据结构——用十个块来提高并发性
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 为了提高并发性,把…...
【ffmpeg命令入门】实现画中画
文章目录 前言画中画是什么画中画的外观描述效果展示为什么要用画中画应用场景示例 使用FFmpeg添加画中画示例命令参数解释调整嵌入视频的位置调整嵌入视频的大小处理音频 总结 前言 FFmpeg 是一款强大的多媒体处理工具,广泛用于音视频的录制、转换和流处理。它不仅…...
基于 LangChain+LangGraph 来实现一个翻译项目
相信大家在看文档的时候,有时会比较苦恼,比如 AI 相关的文档都是外文,中文文档比较少,看起来会比较吃力,有的时候会看不懂,翻译软件又翻得很乱,完全看不了,今天就基于 LangChain 和 …...
javascript 如何将 json 格式数组转为 excel 表格| sheetJS
案例 // https://unpkg.com/xlsx0.18.5/dist/xlsx.full.min.js function exportXlsx(jsonData, fileName , mine null) {const workbook XLSX.utils.book_new();// 将JSON数组转换成工作表const worksheet XLSX.utils.json_to_sheet(jsonData);// 向工作簿添加工作表XLSX.…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
