当前位置: 首页 > news >正文

GAMES101-现代计算机图形学入门(Ray Tracing)

目录

  • Shadow Mapping
  • Ray Tracing
    • Why Ray Tracing
    • 图形学对光线的假设
    • Ray Casting 光线投射
    • Recursive Ray Tracing(Whitted风格)
      • Ray-Surface Intersection (隐式几何与光线求交)
      • Ray Intersection With Triangle Mesh(显示几何与光线求交)
      • Accelerating Ray-Surface Intersection(加速求交方法)
      • Uniform Spatial Partitions (Grids) 均匀网格
      • Spatial Partitions 不均匀的网格
      • Bounding Volume Hierarchy(BVH)
    • Basic Radiometry(辐射度量学)
      • 引入定义
        • Radiant Energy and Flux (Power) 辐射能量和辐射通量/功率
        • Radiant Intensity 辐射强度
        • Irradiance
        • Radiance
      • BRDF
  • Monte carlo Path Tracing 蒙特卡洛路径追踪
    • Monte Carlo Integration 蒙特卡洛积分
    • Path Tracing 路径追踪
    • 用蒙特卡洛积分解渲染方程
    • Sampling the Light 光源采样
  • 最后来感受一下Path Tracing的强大

GitHub主页:https://github.com/sdpyy
games101项目作业代码:https://github.com/sdpyy1/CppLearn/tree/main/games101

Shadow Mapping

如果使用光栅化,对一个像素shading时考虑光源,考虑摄影机位置,但是没有考虑模型其他位置对该位置的影响,因为在光源与该像素点之间有别的东西挡住,那光源就会被挡住,形成阴影。shading解决不了阴影问题请添加图片描述
该算法为图像空间算法。生成阴影并不需要模型的几何位置信息,当前该算法还是存在走样现象
该算法的关键思想是:一个点不在阴影的前提是摄像机能看见这个点,并且光源能看见这个点
算法步骤:

  1. Render from Light:把光源当作摄像机,做一遍光栅化,从而得到光源会看到什么东西,只需要记录看到点的深度请添加图片描述

  2. 从设定好的摄像机位置去真正的渲染场景得到摄像机视角的深度Buffer,如下图橙线下的点两次都看见了,而红线上的点只有光源嫩看见,摄像机是看不见的

请添加图片描述
请添加图片描述
举一个实际的例子请添加图片描述
上图左上角有一个点光源,下图则展示了从点光源看向模型的样子
请添加图片描述
当然这一步只需要记录每个点的深度
请添加图片描述
最终再回到摄像机的视角,绿色就是摄像机和光源都能看见的位置,不是绿色的位置就是阴影的位置
请添加图片描述
shadow maps的问题
首先解释一下硬软阴影区别,看两幅图就能理解

  • 硬阴影 :请添加图片描述
  • 软阴影: 产生软阴影是因为光源具有体积,导致,有的地方完全看不到光源(本影, Umbra), 有的地方能看到一部分光源(半影,Penumbra)。所以阴影的边缘会有过渡的情况,从而产生软阴影,就像上图中太阳与地球的示意一样(全日食与半日食)。请添加图片描述
    请添加图片描述

Ray Tracing

Why Ray Tracing

为什么需要光线追踪?

  • 光栅化不能很好地处理全局效果,如软阴影(光栅化可通过Shadow Mapping实现硬阴影(老师说目前也有技术实现软),由于缺乏全局信息,需要多次计算,如上一节提到的把光源当作摄像机先计算一遍深度缓存)。另外是当光多次弹射时,光栅化不好处理
  • 光栅化很块,但是质量低
  • 光线追踪很准确,光栅化主要用于实时,光线追踪用于离线

图形学对光线的假设

  • 光线沿直线传播
  • 光线和光线不会碰撞
  • 光线从光源出发经过各种反射到达人眼(光路可逆,光线追踪利用的就是光路的可逆性)

Ray Casting 光线投射

如下图所示,摄像机连出一根线到屏幕的一个像素点,点到达物体表面时,该点也能连接到光源,就可以计算出这一点的光的强度来进行着色请添加图片描述
具体例子如下图
从眼睛发出线打到一个像素,紧接着达到场景中的某个位置上(eye ray),只考虑与场景最近的一个交点,所以后边的虚线就不考虑了(在作业5中可知,生成eve ray的流程:屏幕是Raster Space(光栅空间),为了找到摄像机到每个栅格真正代表的空间坐标,需要将Raster Space还原成NDC space再进一步还原成
请添加图片描述
紧接着连接一条线到光源位置(shadow ray),有了法线、入射方向、观察方向,就可以利用光照模型来计算着色了(例如 Blinn Phong model)
请添加图片描述

Recursive Ray Tracing(Whitted风格)

上一节的模型仍然只考虑了光线只反射一次的情况,还是从上一节的图开始,假设eye ray打到的是一个玻璃球,可能会发生折射和反射,每一个弹射点都进行着色计算(都连接到光源),每个着色都会被加到这个像素点的着色上去。
请添加图片描述
里边具体的技术点会在后边讲到

Ray-Surface Intersection (隐式几何与光线求交)

首先用数学定义一下光线:光线被定义为由起点和方向的向量,点光源的描述如下,这样定义的目的是将光线与物体求交点的问题转化为求t值的问题请添加图片描述
从简单的开始,光线如何与球求交点,其实就是点P在球面上,也在光线上,联立即可
请添加图片描述
最终可以解出来t的大小,t取小的一个,表示第一个交点
请添加图片描述

Ray Intersection With Triangle Mesh(显示几何与光线求交)

由上边内容可知,给出一个隐式的几何,求光线与几何的交点,就是联立后求t的值,那显式的表达呢?如下图,如何判断光线与mesh有交点呢?一个一个三角形求光线与三角形的交点么?太慢了请添加图片描述
虽然太慢了,但是还是要先学习一下怎么求一个光线与三角形的交点。 基本思路就是先找出光线与三角形所在平面的交点,之后判断这个交点是不是在三角形内部。
请添加图片描述
首先来看一下平面如何定义,一个向量和一个点就可以定义一个平面
请添加图片描述
如何判断一个点P是否在平面上呢?只要下图两点形成的向量与平面法向量垂直即可
请添加图片描述
所以又回到了上一节的联立,点P在平面上,也在光线上,进行联立求解,最后得到光线与平面的交点,再判断点是否在三角形内,就可以得到光线与三角形的交点。
请添加图片描述
Möller Trumbore Algorithm
那有没有方法直接判断呢?如果光线与三角形有交点,那这个交点就可以用重心坐标表示,直接建立如下等式,用克莱默法则求解方程组就可以直接求出来(三个未知数,三个方程,所以是可以解出来的)请添加图片描述

Accelerating Ray-Surface Intersection(加速求交方法)

现在已经知道了光线与三角形求交,那如何判断光线与mesh的交点呢。一个一个三角形遍历太慢了。如下图三角形实在太多了。这就引入了Accelerating Ray-Surface Intersection请添加图片描述
先介绍一个概念 Bounding Volumes,如果光线都打不到包围盒,更打不到mesh了请添加图片描述
想象一下一个box相对的两个面是一个无限大的平面(称为对面),box就是三个对面的交集,通常使用的是Axis-Aligned Bounding Box (AABB) (轴对⻬包围盒),这个东西就是这个盒子的边都是和坐标轴对齐的,简化计算。
请添加图片描述
下面就来看下光线与包围盒的求交问题(与包围盒有交点,才去考虑与包围盒内部的Mesh求交)
先从二维平面情况下看, x 0 x_0 x0 x 1 x_1 x1是一个对面, y 0 y_0 y0 y 1 y_1 y1是一个对面
x 0 x_0 x0 x 1 x_1 x1对面上看可以求出两个交点
请添加图片描述
y 0 y_0 y0 y 1 y_1 y1对面上看也可以求出两个交点
请添加图片描述
求交集后,就求出光线进入和出去盒子的时间

请添加图片描述
从三维情况下开,3组对面的时间t进行求交集,当进入时间小于离开时间,就是有交点请添加图片描述
另外,用上诉算法算出来的t可能是负数,用下图进行处理,总结来说,进入小于退出,退出大于0即可
请添加图片描述
最后解释一下为什么要用AABB盒,光线与平面求交点是有公式的,如下图General。对准坐标轴后计算更容易,下图为计算量对比。
请添加图片描述

Uniform Spatial Partitions (Grids) 均匀网格

通过上节的加速算法,我们已经知道如果把物体包在盒子里,先判断与盒子求交,再考虑与盒子内物体求交,但采用包围盒并不一定会提升性能,例如下面两种情况

  1. 整个场景只有一个极其复杂的单一人物模型,那么只对这一个物体做包围盒的话,相当于对效率没有任何提升
  2. 整个场景充斥着大量的细小模型,如草,花之类的,每个模型可能只有很少的面,如果此时对每个物体求包围盒,得到的包围盒数量会相当之多,对于光线追踪效率来说效率提升有限。

所以还要对包围盒进行进一步的处理
首先来进行预处理
4. 找到包围盒
5. 画出格子(盒子内部再分成很多的格子)
6. 标记有物体的格子
请添加图片描述
预处理完成后,光线从一侧打进来,只会处理被标记的格子,如果有标记,就算一下是否有交点,这就避免了和包围盒中所有的物体求交,这种方法主要就是解决了,包围盒中有多个物体,只要光线打到了具体一个范围时,才判断是否有交点。
请添加图片描述
Uniform Grids表现比较好的场景如下
请添加图片描述但分布特别不均匀的场景,就不适合用上述方法

Spatial Partitions 不均匀的网格

在物体比较少地方没必要用统一大小的格子,那如何进行场景划分呢,有如下3中方式
第一种Oct-Tree,也就是八叉树,每次将空间分为8个相等的部分,再递归的对子空间进行划分。因为图中是2维例子,所以只划分了4部分。当划分的子空间足够小或是空间中三角形面的数量很少的时候会停止划分。这种方法的显著缺点是,随着维度的上升划分的空间数量会呈指数级增长。

第二种KD-Tree,其每次将空间划分为两部分,且划分依次沿着 x − a x i s , y − a x i s , z − a x i s x-axis,y-axis,z-axisx−axis,y−axis,z−axis (保持最规整的空间区域),如图中所示,第一次横着将2维空间分为上下,第二次再竖着将上下两个子空间分别划分为左右部分,依次递归划分,终止条件与八叉树类似。

第三种BSP-Tree,其与KD-Tree类似,唯一不同的是划分不再沿着固定一轴,可以任意方向划分,缺点自然是划分的空间没有规则性,求交困难。在与轴对齐更好计算的场景下不适用

本节知识主要以KD-Tree来建立
请添加图片描述
给定一个场景,先建立KD-Tree,做好加速结构,再进行光线求交。
下面从预处理开始介绍,竖直先来一刀
请添加图片描述
水平再来一刀,蓝绿都需要做,这里演示只砍绿色
请添加图片描述
再来两刀
请添加图片描述
明白了KD-Tree的流程之后,介绍一下KD-Tree的数据结构
实际的三角形object只存在叶子结点上
请添加图片描述
下一步介绍光线来了之后如何与KD-Tree交互,如下图的这条光线
请添加图片描述
首先判断与最大的盒子是否有交点,如下图所示是有的请添加图片描述
紧接着判断A结点的子结点1是否有交点,此时发现确实有交点,1是叶子结点,那光线就必须和这个盒子里的物体进行计算求交
请添加图片描述
之后又发现与右边也有交点,那么就需要继续看子结点
请添加图片描述
子结点2也有交点,是叶子结点,那就得和2中所有物体求交,后续流程一样
请添加图片描述

Bounding Volume Hierarchy(BVH)

KD-Tree并不完美,缺点是判断包围盒与三角面的是否相交较难,因此划分的过程不是那么想象的简单,其次同一个三角面可能被不同的包围盒同时占有,这两个不同包围盒内的叶节点会同时存储这一个三角形面。
BVH不再通过场景进行划分,而是通过物体来划分,得到了广泛应用。
首先把一个包围盒内的三角形组织成两部分,并对两部分三角形重新求包围盒,如下图
请添加图片描述
之后重复操作,划分到一个叶子结点只有比如5个三角形就停止,这样一个三角形只会出现在一个包围盒里。避免了KD-Tree一个三角形可能出现在不同的叶子结点里的问题
请添加图片描述
那如何进行结点划分呢?首先向KD-Tree学习,每次选一个x、y、z其中一个轴进行划分。技巧:每次都找最长的轴进行划分,例如场景在x轴上是一个长条,就利用x轴划分。如何分成两半呢(如何保证划分后两部分三角形数量差不多呢)?通过三角形的重心坐标,在x轴上排序(其实不用排序,有更好的找中位数算法叫快速旋转算法,可以在O(n)时间内找到中位数),就知道中间那个三角形是哪个了,这样就进行了划分。
请添加图片描述
下来介绍光线与BVH求交的过程,用代码演示
请添加图片描述
划分空间vs划分物体
请添加图片描述
到这里,求交的内容就结束了

Basic Radiometry(辐射度量学)

在之前实现 Blinn-Phong模型时,光照强度I设置为10,但是10是什么呢?

  1. whited-style光线追踪只考虑了光滑面的镜面反射与折射,并没有对漫反射的光线进行追踪,而是直接返回当前着色点颜色
  2. 在计算光源直接照射的贡献时,使用了Blinn-Phong模型,而Blinn-Phong模型本身就是一个不准确的经验模型,使用的这种模型的whited-style光线追踪自身自然也是不正确的

为此,更好的渲染模型路径追踪出现了,而在这之前,我们必须掌握一些辐射度量学的知识,它是对光照的一套测量系统和单位,能够准确的描述光线的物理性质。辐射度量学是物理上准确定义光照的方法。首先来引入一些概念

引入定义

Radiant Energy and Flux (Power) 辐射能量和辐射通量/功率

辐射能量就是光源射出来的电磁能量,单位为焦耳 (功)
请添加图片描述
Radiant flux(power) 辐射能量的基础之上除以时间,也就是单位时间的能量(功率、流明)
请添加图片描述
在计算机图形学来看,主要关注一下三个东西
请添加图片描述

Radiant Intensity 辐射强度

从一个点光源发射的每单位立体角下的功率,光源向四面八方辐射能量,在单位立体角上的功率就是辐射强度
请添加图片描述
那什么是立体角呢?
首先2维下的角度就是弧度/半径,3维空间中立体角就是一块面积/半径的平方,立体角就是用来描述空间中角有多大,一个球体总的立体角就是4pi
请添加图片描述
下图描述了单位立体角。在微分下,形成的一个很小的面积的立体角,是一个微分立体角dw,计算公式如下
请添加图片描述
最终可以得到 辐射强度 = 辐射功率/4pi
请添加图片描述

Irradiance

每单位照射面积dA所接收到的power/flux
请添加图片描述
光源能量在距离上有r平方的衰减,可以用irradiance来解释,远处单位面积更大,按r平方衰减,Intensity并没有变化,单位角也没有变化,变化的是单位面积,进而影响了Irradiance

请添加图片描述

Radiance

请添加图片描述
Radiance是 单位立体角、单位面积上的power
请添加图片描述
请添加图片描述
Incident Radiance是到达表面的irradiance 在 per 立体角下
请添加图片描述
Exiting Radiance 是 开表面辐射强度在per单位面积上请添加图片描述
最后看一下Irradiance和Radiance的关系

  • Irradiance是单位面积上的总能量
  • Radiance是总能量在单位立体角上的大小,就是在Irradiance上增加了方向性(radiance在方向上积分就是Irradiance)
    请添加图片描述

BRDF

Bidirectional Reflectance Distribute Function 双向反射分布函数,在介绍完上边概念的定义后,可以这样理解光线的反射,一个微分面积元在接受到一定方向上的亮度后,再向不同方向把能量辐射出去,所谓BRDF就是描述一个从不同方向入射之后,反射光线分布情况的函数

请添加图片描述
下图为BRDF的方程,只需要两个参数入射光方向 ωi,反射光方向 ωr,函数值为反射光的radiance与入射光的irradiance的比值
请添加图片描述
摄像机所在方向上的反射光,是由来自不同方向入射光线的irradiance经过反射得到的,不同方向上的入射光线的irradiance的贡献由BRDF函数决定
请添加图片描述
但是入射光的radiance不仅仅来自光源,也可能是其他物体的反射光恰好反射到了该点,这是一个递归的过程
请添加图片描述进一步,如果这个点本身就会发光,需要额外加上这部分,最终的渲染方程为下图
请添加图片描述
如何理解渲染方程呢?
从反射方程来看,如果有多个光源,就把这些radiance进行累加
请添加图片描述
如果有一个面光源,对这个面对应的立体角进行积分
请添加图片描述
那么更进一步再在场景当中加入其它物体,使得物体之间发生光线交互之后是什么情况呢。如下图所示,可以把其它物体同样考虑成面光源,对其所占立体角进行积分即可,只不过对其它物体的立体角积分不像是面光源所有入射方向都有radiance,物体的立体角可能只有个别几个方向有入射的radiance(即多次物体间光线反射之后才恰好照射到着色点),其它方向没有,但本质上都可以视作是面光源。
请添加图片描述
最终整理方程,只有入射和反射的radiance不知道,其他项都是知道的
请添加图片描述
简化形式
请添加图片描述
经过一系列变化后得到,L是所要求的反射光,E是自己的发光,K是一个算子
请添加图片描述
最终可以得到
请添加图片描述
最终最终整理成如下形式,E是自身发光,KE是光源反射一次结果(光源直接照射),Blinn-phong模型就只考虑到这一层,K2E是弹射一次的光照…
请添加图片描述下图展示了处理弹射次数变多时的变化,场景越来越亮并且逐渐收敛
请添加图片描述请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述
这一部分就结束了,主要就是从辐射度量学角度来计算光照。直接光照和弹射后的光照混合就形成了全局光照

Monte carlo Path Tracing 蒙特卡洛路径追踪

Monte Carlo Integration 蒙特卡洛积分

蒙特卡洛是用来解一个原函数不好解析的定积分计算
请添加图片描述
它的基本思想就是通过随机采样获得很多f(x),取平均后*(b-a)来计算线下面积请添加图片描述
更一般情况下,概率函数取任意一个,用下边公式就可以求一个定积分
请添加图片描述

Path Tracing 路径追踪

之前已经学习了Whitted-Style Ray Tracing,从摄像机射出光线遇到物体进行镜面反射或折射,每次弹射都与光源连线,但这里面有一些不符合物理的情况
问题一: Whitted-Style假设反射时完美的,没有任何模糊或扩散,但是对于Glossy表面,现实中光线会在一个范围内散射,而不是单一方向的镜面反射
请添加图片描述
问题二:光的漫反射应该真正的向四面八方反射开,例如下边右图柱子被墙壁的红色光反射到而呈现了红色请添加图片描述
所以最终得到Whitted-Style Ray Tracing是错的
请添加图片描述

用蒙特卡洛积分解渲染方程

考虑下图场景
请添加图片描述
解渲染方程,就是求在半球上的积分,所以可以用蒙特卡洛来解
请添加图片描述
被积函数如下
请添加图片描述
选择概率密度函数如下
请添加图片描述
最终要求的就是 请添加图片描述
用算法描述就是要求p点向wo方向的辐射,首先通过概率密度函数随机选择N个样本,对于每个选中的方向wi,从p点连接到wi形成一条光线,如果这个方向打到了光源,就用公式进行累加 (这里的描述只考虑直接光照)
请添加图片描述
上边已经解决了直接光照问题,下来再解决全局光照,p点在wi方向上并没有看到光源,但是看到了Q点,这时候把P点当作摄像机,Q点当作要处理的点,对Q点进行上边介绍的处理,就能算出Q点对P点的贡献
请添加图片描述
全局光照的算法描述如下,注意红色位置
请添加图片描述
到这里还是有问题
问题一: 点越打越多请添加图片描述
问题一的解决就是只采样一次
请添加图片描述
用N=1来进行积分就叫做Path Tracing,虽然在一个点位只会采样一次,但是整体路径可以进行多次,也就是从像素出发的线不只一条,但接触到物体时只采样一次
请添加图片描述
请添加图片描述
问题二:没有设置递归出口,可是真实情况光就是会弹射无数次,引入俄罗斯轮盘赌来解决,以一定的概率停止递归

请添加图片描述
根据期望,这种概率性做法最终的期望还是Lo
请添加图片描述
最终最终的算法步骤如下:
请添加图片描述
下面看一下用这个算法生成的图,算法是正确的,但是像素采样点设置很少时(low SPP)效果并不好,在High SPP下速度又太慢
请添加图片描述

Sampling the Light 光源采样

需要的采样数与光源大小有关系
请添加图片描述
解决效率问题思想就是在点P不再四面八方采样,而是在光源上进行采样,现在存在的问题蒙特卡洛积分的采样概率密度函数是在P点半球面的采样,需要把公式转换成在光源上采样的形式
请添加图片描述
从数学上说就是dw的积分改为dA积分,需要先研究dw和dA的关系,就是用两者的关系进行换元
请添加图片描述
最终重写渲染方程
请添加图片描述
请添加图片描述
请添加图片描述
到这还有一个小小问题
如果光源被挡住呢?
请添加图片描述
点光源路径追踪不好处理,建议改成小面积的面光源

最后来感受一下Path Tracing的强大

请添加图片描述
如何渲染一张图:要么光栅化要么光线追踪

相关文章:

  • SpringBoot集成kafka极简教程
  • 宝塔:网站监控监控表没有数据异常处理
  • ROS多机通信(三)——Ubuntu Ad-Hoc 组网通信配置指南
  • 更新docker 容器时,提前换后端jar 包,为什么会存在异常
  • Oracle到达梦数据库迁移:技术要点与实践分享
  • Python SciPy面试题及参考答案
  • 推荐 --召回模型 DSSM, YoutubeDNNd
  • OPTICS聚类算法原理详解
  • 目标检测20年(四)——最终章
  • 使用MyBatis Plus的QueryWrapper实现复杂的SQL查询
  • macbook电脑如何清理键盘防止误触
  • SpringBoot 3+ Lombok日志框架从logback改为Log4j2
  • 深入浅出Spring-Boot-3.x.pdf
  • 游戏引擎学习第184天
  • Linux操作系统7- 线程同步与互斥7(RingQueue环形队列生产者消费者模型改进)
  • RK3568 设备树基础语法讲解
  • QLoRA和LoRA 微调
  • RK3568笔记八十一: Linux 小智AI聊天机器人移植
  • ctfshow做题笔记—栈溢出—pwn73、pwn74
  • 在 Mermaid 流程图里“驯服”quot;的魔法指南!!!
  • 阿曼外交部:美伊谈判因故推迟
  • 戴上XR头盔,五一假期在上海也能体验“登陆月球”
  • 小核酸药物企业瑞博生物递表港交所,去年亏损2.81亿元
  • 学有质量、查有力度、改有成效,广大党员干部落实中央八项规定精神
  • “光荣之城”2025上海红色文化季启动,红色主题市集亮相
  • 浙商银行外部监事高强无法履职:已被查,曾任建行浙江省分行行长