前言
本篇将介绍什么是光线追踪,为什么需要光线追踪,实现光线追踪的细节,看完本篇即可跟着教程ray tracing in one weekend用c++实现一个简单的光线追踪器,关于该教程笔者也写了总结rayTracingInOneWeekend - 爱莉希雅 - 博客园 (cnblogs.com)
什么是光线追踪?
光线追踪(Ray tracing)是三维计算机图形学中的特殊渲染算法,跟踪从眼睛发出的光线而不是光源发出的光线,通过这样一项技术生成编排好的场景的数学模型显现出来。这样得到的 结果类似于光线投射与扫描线渲染方法的结果,但是这种方法有更好的光学效果,例如对于 反射与折射有更准确的模拟效果,并且效率非常高,所以当追求高质量的效果时经常使用这种方法
Whitted 于 1979 年提出了使用光线跟踪来在计算机上生成图像的方法,这一方法后来也被称为经典光线跟踪方法、递归式光线追踪方法,或 Whitted-style 光线跟踪方法。其主要思想是从视点向成像平面上的像素发射光线,找到与该光线相交的最近物体的交点,如果该点处的表面是散射面,则计算光源直接照射该点产生的颜色;如果该点处表面是镜面或折射面,则继续向反射或折射方向跟踪另一条光线,如此递归下去,直到光线逃逸出场景或达到设定的最大递归深度
效果图
-
图形学中的光线的性质
- 沿直线传播
- 光线和光纤间无法碰撞
- 光线路径可逆
-
光线追踪主要遵循第三条性质光线可逆。现实生活中是光线不断散射后进入人眼,而在光线追踪是人眼发出光线
根据上图所示,光线追踪过程如下:
- Ray Casting:从相机向投影的
近平面
上的每个像素发射一条光线,判断和场景中的物体的交点(最近的交点).再连接交点和光源,判断该连线间是否有物体,若有说明该交点在阴影中.利用Blinn-Phong模型对该点进行局部光照模型计算,得到该像素的颜色,该颜色就是目前像素点的颜色 - Whitted-Style Ray Tracing:可以看出目前和局部光照模型差不多,我们还需考虑全局效果。考虑第一步Ray Casting,该线和物体相交会发生散射,散射的光线和其他物体相交继续散射,将这些交点和光线相连,对这些点都计算颜色,最后将这些颜色全部按照
权重
累加,最终得到近平面该像素点的颜色
注意:
- 光线追踪是一个递归过程,需要终止条件,如最大散射次数
- 光线每次散射都有能量损耗,该损耗由系数因子决定
- 若散射后没有与物体相交,则返回背景色
- Ray Casting:从相机向投影的
-
光线追踪伪代码
for each pixel of the screen { Final color = 0; Ray = { starting point, direction }; Repeat { for each object in the scene { determine closest ray object/intersection; } if intersection exists { for each light inthe scene { if the light is not in shadow of anotherobject { addthis light contribution to computed color; } } } Final color = Final color + computed color * previous reflectionfactor; reflection factor = reflection factor * surface reflectionproperty; increment depth; } until reflection factor is 0 or maximumdepth is reached }
为什么需要光线追踪?
可以看出光线追踪是一种全局光照,而光栅化只能实现局部光照,很明显光线追踪得到的效果图更加明亮,质量更高!
光线的表示
将光线看成一条射线,由起点和方向两个属性构成:$r(t) = o + td, 0 \leqslant t \leqslant ∞ \(,其中\)o\(为起点,\)d$为方向
物体和光线求交
光线和隐式曲面求交
在此,我们选球体作为隐式曲面,那么有:
- 光线:$r(t) = o + td, 0 \leqslant t \leqslant ∞ $
- 球体:\((p - c)^2 - R^2 = 0\),其中p是光线和球体的交点,c为圆心,R为半径
当这两个方程有实数解时即可解出交点:\((o + td - c)^2 - R^2 = 0\),只有c未知,可以看出这是一个一元二次方程\(a = d·d \\ b = 2(o-c)·d \\ c = (o-c)^2 - R^2\),\(t = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)
- 若是两个不同的正实数解,说明射线和球体有两个交点
- 若是两个负实数解,说明射线的反向延长线上和球体有两个交点
- 若都包含虚部,说明没有相交
- 若是两个相同的实数解,说明射线和球体相切
- 若是一正一负两个解,说明射线起点在球体内,其中一个交点是射线的反向延长线
光线和显式曲面求交
该处的显式曲面具体指的是平面,如三角形面,可以用以下式子表示:
此处虽然不是一个三角形面,但三角形面也处于该平面内,我们只需求出光线和平面的交点,然后判断交点是否在三角形面内即可
过程:
- 用点法式定义平面
- 将光线带入平面方程,求解交点,再判断是否在三角形内
但对于该过程可以将将其合为一步——克莱姆法则。如下图所示,求解\(t, b_1, b_2\)后还需判断是否合理——t是否有意义,\(b_1,b_2,b_3\)为负
计算散射方向
反射
假设,目前知道光线\(l\)和物体相交发生反射,如何求反射向量\(r\)
过程如下:
- \(r = 2p + l\)
- \(p = s + (-l)\)
- \(s = N(l·N)\)
- \(p = N(l·N) - l\)
- \(r = 2N(l·N) - l\)
折射
由折射法则\(\eta · sin \theta = \eta' · sin \theta'\)(\(\theta\)和\(\theta'\)分别为入射光线\(R\) 和 折射光线\(R'\) 和法线的夹角)可得折射光线\(R' = sin \theta' = \frac{\eta}{\eta'} · sin \theta\)
目前,有未知的折射光线\(R'\)、未知的法向量\(N'\),为了求\(R'\),我们将\(R'\)拆分后的垂直\(N'\)和平行\(N'\)的向量:
- \(R'_{\|} = \frac{\eta}{\eta'}(R + (-R · N) N) = \frac{\eta}{\eta'}(R + cos \theta N) = \frac{\eta}{\eta'}(R + (-R·N) N)\)
- \(R'_{\perp} = -\sqrt{1 - |R'_{\|}|^2 }N\)
reference
GAMES101:现代计算机图形学入门 – 计算机图形学与混合现实在线平台 (games-cn.org)
[Game-Programmer-Study-Notes/README.md at master · QianMo/Game-Programmer-Study-Notes · GitHub](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/《Real-Time Rendering 3rd》读书笔记/README.md)
标签:Style,光线,Whitted,散射,eta,交点,theta,追踪 From: https://www.cnblogs.com/chenglixue/p/17261677.html