game101阶段性总结⑤(坑)
光线追踪(Ray Tracing)
光栅化无法解决全局效果,比如软阴影(soft shadow),粗糙表面反射以及间接光照
所有得引入光线追踪来完成全局效果,但是代价是消耗大,且极慢
一般都是用光栅化来实现Real—Time实时效果,光线追踪都是用在离线offline,比如动画电影CG
Light ray
- 我们假设光是一条有起点的射线,且沿着直线传播(现实是光波)
- 光线不会发射碰撞,无限接近且不会碰撞(现实是会碰撞的)
- 然后光线可逆,我们都知道,我们如何看到物体表面颜色,除了物体本身吸收的波长,也会发射到我们人眼处,由人眼吸收,那么假设我们人眼也是一条Ray,felling Ray,逆推导就可以知道光线位置以及方向
光线投影(Ray Casting)

从Camera(View)出发,连接成像图的一个像素点,穿过像素点打到与之最近物体表面上某一点,取这个点,以这个点与光源做连线(假设是完全完美发射,光线并非就是物体完美反射方向),通过判定对光源是否可见从而判断这个点是否在阴影里,最后计算光路的能量,带入我们计算光照模型的算式(漫反射+高光+环境光)
上面的这个方法其实和我们在光栅化按着色点算一个点光源没什么区别
所有就有了我们的光线追踪技术
递归式光线追踪 Recursive (Whitted-Style) Ray Tracing
其实这主要运用在能够折射和反射的,反射大部分物体都有,但折射一般发生在透明物体里
此时的反射是有能量损失的反射,且每弹射一次,都会由不同程度的能量损失
只有一个Primaty Ray,多个Second Ray,判断可见性,最后将这些点按照光线投影(Ray Casting)的方法,按权重计算颜色最后叠加形成像素颜色

光线与物体的交点(Intersection)
像上面所说的,我们假设光线就有起点与方向组成的,那么就有这样的定义,对于光线的上的某一点,我们都有一个算式可以表达它

对于每一个封闭物体,有奇数交点,那么这条光线在物体内,偶数个交点,在物体外
那么回到我们的模型上,我们模型一般都是由多边形面组成的,那么在早期的光线追踪,是计算每个三角形面的递归式光线追踪,虽然有用,但很慢
如何做到:
首先每个面都有它的法线,且法线是一定垂直于这个面的,那么再拿一个面里的点P',假设我们要求的的点在这个面上,首先得到这条向量P-P',拿这条向量与法线做点乘即可等于0,最后通过叉积判断这个点是否在三角形内

利用重心坐标即可一次性算出点来,O、D、P0、P1、P2都是一个三维的点,都有xyz,就可以利用克拉姆法则,就可以算出|Dx|,|Dy|,|Dz|,进而与|D|相除得到x,y,z

但是运用于有上千万个面的大场景中,这种一个一个计算显然不合适,所有人们有引入了一种测试方法,包围体积盒(AABB)
包围体积(Bounding Volumes)
思想就是,光线连这个包围盒都没碰到,那我自然就不去渲染它了
如何定义一个包围盒,一个矩形,都是3对对面的交集组成的,分别前后一个对面,上下一个对面,左右一个对面

那么此时的t如何计算,直接丢进一条轴即可,如O+tD=P

如何定义t的进入时间与离开时间
对于一个3D盒子
- 光线进入只有3个面都满足有交集时
- 光线离开其中一个面即是离开

当tenter早于texit时,当且仅当texit大于等于0时,光线与盒子有交点
加速光线追踪
这是对包围盒的加速操作,更加快速的筛选要渲染的物体,而且画出的包围盒中的格子不能太稀疏与密集,计算量增大或者不精确,假设光线从左侧斜向上进入,那么它会遇到的格子一定是它的右边与上边,这就解决了光线如何知道是否遇到了物体,但是麻烦,对于分布不均匀的物体不好搞定
后面又引入了8叉树,BSP—TREE,KD—Tree
KD-Tree很好的把一个包围盒按一定规则交替划分,如第一次是沿着x轴划分,第二次沿着y轴,第三次沿着z轴,最后会划分成一个二叉树样子的分布,并且物体都存在与我们的叶子节点上,那么当光线进入这个包围盒子时候,先会和碰到的区域划分空间里的所有物体求交点,然后又继续沿着这条光线继续下去,直到真的打到一个物体上时,返回最近真的打到的那个交点

物体划分(BVH)
KD—Tree是很好的划分了区域,但是我们的物体它也有可能被分到光线都无法影响的区域,这时候不好计算光照,所以引入以物体来划分的包围盒

这种的好处在于,我们不用去考虑物体是否出现在别的包围盒里,且容易划分,假设我们的物体全部排列在一条长轴上,我们只需要取中点即可(最大值为n,中点就是n/2)【也可以min+(max-min)/2】
最后规定一个包围盒里最多有多少个物体
和上面的树一样,叶子节点才有物体,而内部节点无物体
路径追踪(path tracing)
辐射度量学(Basic Radiometry)
关键的信息:

Radiant Energy and Flux
Radiant Energy:就是单位是焦耳的能量Q
Flux:是单位时间的能量,单位为瓦特的功率与单位为流明(光通量单位)的光通量,这个光通量定义了光源有多量,所以Flux也可以说是Power

Radiant Intensity:光源的任一光线方向对应的强度,这个数值是由每一个单位立体角上的Flux(power)所决定的

弧度是周长除以半径得到的,周期为2π

立体角是对一个三维空间中的球,球上的一块被锥体打到的面积除以半径平方而得到的,周期为4π
单位立体角的公式如下

最后可以得到任意方向上的对应的光的强度I,在这个视锥体内,能量不会发生变化

irradiance
每个单位面积所受的能量,能量会发生变化,且光线要垂直面积表面,若不垂直,则要进行投影


现实光都是以波长形式出现,那么在内圈假设能量为

随着面积的增大,能量也会随之减少

radiance
描述光线在传播中有什么属性,power(Flux)在单位立体角上的能量,且在单位面积接受的能量

从一个面上的单位面积辐射出去,以单位立体角发出的energy,radiance是一个既有辐射(intensity),也可以表示接收(iradiance),且只考虑某一方向进来的energy,如果把所有方向的radiannce加在一起,就会变成irradiance,一个单位面积上的能量,且经过转换又会变成反射的radiance到摄像机或者其他物体上,在这里的转换为反射的radiance除以入射的irradiance

这就引出了BRDF(双向反射分布函数)
它决定不同材质对光的吸收率等因素的影响,就是描述光线与物体间是如何作用,经过BRDF之后,其他能量的权重
在进一步引出渲染方程,一个点的出射的radiance,也是其他点的入射radiance,根据立体角,就可以的到其他点对本身的影响,和其他着色点着色



以上3个方程就可以解释,一个物体如何对其他物体的影响,也就是光线如何进过弹射之后去影响光栅化所着色不到的表面,也就是全局光照=直接光照+间接光照

对于一个物体表面,除开它自身所发散的自发光外,还会有光源或者其他物体对他的光线方向,那么我们引入概率,利用蒙特卡罗积分就能近似的求的这个点的正确的着色


其中N要等于1,因为N如果大于1了之后,在第一次照射到之后,物体表面必定会发散出无数的漫反射,那这些漫反射又去影响其他物体,就变成无穷无尽,这数据量足以使得计算机宕机了,那么此时就叫做路径追踪了。
其次,要规定一个足以停止追踪的概率,这个概率可以让我们的期望值最后还是我们想要的那个效果,只不过是得到与不得到的概率而已,这种概率就是Russian Roulette (RR)俄罗斯轮盘赌
但是,当我们的光源很小的时候,我们发散出去的光线可能得很多才能打到我们得光源,这不仅浪费我们的性能,还会使得我们物体颜色更加奇怪,因为我们采样的方向太多了
这时我就让光源自己做渲染方程


如果此时,光源与我们物体间处在遮挡物,就还得做一次距离判断。

浙公网安备 33010602011771号