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.…...

网页制作技术在未来会如何影响人们的生活?
网页制作技术在未来会如何影响人们的生活? 李升伟 网页制作技术在未来可能会从以下几个方面显著影响人们的生活: 1. 工作与学习方式的变革:远程办公和在线教育将更加普及和高效。通过精心制作的网页,人们能够实现更便捷的协作…...

【计算机网络】网络层——IPv4地址(个人笔记)
学习日期:2024.7.24 内容摘要:IPv4地址,分类编址,子网,无分类编址 IPv4地址概述 在TCP/IP体系中,IP地址是一个最基本的概念,IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…...

c++ 学习笔记之多线程:线程锁,条件变量,唤醒指定线程
基于CAS线程加锁方式 CAS(Compare-And-Swap)和 mutex 都是用于实现线程安全的技术,但它们适用于不同的场景,具有不同的性能和复杂性。下面是对两者的区别和使用场景的详细解释: CAS(Compare-And-Swap&…...

《0基础》学习Python——第二十三讲__网络爬虫/<6>爬取哔哩哔哩视频
一、在B站上爬取一段视频(B站视频有音频和视频两个部分) 1、获取URL 注意:很多平台都有反爬取的机制,B站也不例外 首先按下F12找到第一条复制URL 2、UA伪装,下列图片中(注意代码书写格式) 3、Co…...

第13周 简历职位功能开发与Zookeeper实战
第13周 简历职位功能开发与Zookeeper实战 本章概述1. Mysql8窗口函数over使用1.1 演示表结构与数据1.2 案例1:获取男女总分数1.3 案例2****************************************************************************************本章概述 1. Mysql8窗口函数over使用 参考案例…...

什么是大型语言模型 (LLM)
本章探讨下,人工智能如何彻底改变我们理解和与语言互动的方式 大型语言模型 (LLM) 代表了人工智能的突破,它采用具有广泛参数的神经网络技术进行高级语言处理。 本文探讨了 LLM 的演变、架构、应用和挑战,重点关注其在自然语言处理 (NLP) 领…...

【人工智能】AI时代:探索个人潜能的新视角
文章目录 🍊Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉1.5.2 局限二:Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 …...

pyaudio VAD通过声音音频值分贝大小检测没人说话自动停止录制
效果可能说话声音小可能不被监听到,需要更改QUIET_DB阈值,另外delay_time值是低于阈值多久就可以停止保存当前的语音 import pyaudio import waveimport sys import numpy as npdef record_auto(MIC_INDEX=1):开启麦克风录音,保存至temp/speech_record.wav音频文件音量超过…...

《后端程序猿 · @Value 注释说明》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

【LeetCode】71.简化路径
1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码: class Solution:def simplifyPath(self, path: str) -> str:operator [] # 操作符的栈dir_name [] # 文件名的栈idx 0cur_dir_name ""while(idx < len(path)):if path[idx] /:operator.ap…...