各种光线追踪原理详解

前言

全文采用通俗语言,不罗列数学知识和专业知识,仅分享自己的心得。

本文为什么说是“各种光线追踪”的原理呢?是因为我当时初识光线追踪的时候,从很多博客或者国内外论文上,都会看到光线追踪原理的介绍,但是经常会存在或多或少的差别,对于刚接触光线追踪渲染的人来说很容易被搞懵。经过研究生阶段我一直在接触学习光线追踪,所以对光线追踪不敢说有很深入的认识,但是也有一点小小的心得,因此想将光线追踪的原理分门别类地说清楚。


关于光线追踪原理的说明

光线追踪的实现原理,不是像我们平时课程学习时遇到TCP三次握手的原理那样有固定的样子,而是有点类似我们学习快速排序算法时那样有多种实现,快速排序算有很多种方法实现,核心都离不开找基准数然后遍历数组交换元素这一条(如果你不清楚TCP三次握手和快速排序是什么,可以完全不需要理会,仅仅只是帮助思考的比喻)。

开始正题,对于光线追踪,请首先放下你之前对其印象中的原理,看看下一段内容重新去认识光线追踪这个词(如果你有深入学习光线追踪并且自己已经有系统的认识,也可以参考下我的内容,如果有错漏还请提供您的宝贵意见)。

光线追踪: 是一个框架,是一个统称,没有统一的实现原理,根据不同的使用场景可以有各种具体的实现原理。但是万变不离其宗,都离不开“通过模拟光线的现实传播行为来追踪光线进行渲染”这一个核心,只要根据这个核心来实现的渲染方法,都可以归到光线追踪下,都可以说是光线追踪渲染方法。因此你在不同地方看到的光线追踪原理会有差异就是这个原因。


关于光线追踪的分类

光线追踪主要分为以下几种具体的实现原理,建议通过英文全称来区分:

光线投射(Ray Casting):严格意义上这种不算光线追踪,但也是不得不提到的。

经典光线追踪(Classic Ray Tracing或者Classical Ray Tracing):也会直接被简称 “光线追踪(Ray Tracing)” 这应该是我们直接百度时看到最多的那种。这种是基础、传统、古早一点的光线追踪。

递归式光线追踪(Recursive Ray Tracing或者Whitted-style Ray Tracing):也叫做Whitted光线追踪,指同一个东西,忘了的话容易以为是两种不同的光线追踪。这种目前更偏向主流的光线追踪,可以说当我们谈论到光线追踪时,实际上就是在谈论这种递归式光线追踪。

路径追踪(Path Tracing):你有接触的话,可能会见过一种说法是 “路径追踪=光线追踪+蒙特卡洛” ,其实远不止如此简单,这种方式我也是接触最少的一种,因为它的实时性约等于无,关于光线追踪的实时性这点后面我会详细介绍。在渲染画面效果上(或者玩游戏爱说的光影效果),路径追踪是以上几种光线追踪中最强的。

以上几种就是光线追踪这个框架下最主要的分类,不把光线投射算在内的话,就是一共三类。下文将用通俗语言详细介绍这几类光线追踪的原理和我自己的心得理解。


关于光线追踪的核心

上文提到各种光线追踪“都离不开“通过模拟光线的现实传播行为来追踪光线进行渲染”这一个核心”。那怎么去解释这个核心呢?

我们人眼能看到外面的世界,能看到物体,看到颜色,看到光,是因为我们的眼睛接收了光,来自光源直射的光,来自物体发射的光。而那部分没有进入到我们眼睛的光,或者说没有被我们眼睛接收的光,那错过就错过了,为我们人眼成像提供不了任何帮助。光线追踪就是基于以上阐述提出的一个想法,通过追踪进入我们人眼的那些光线,看看这些光线从光源到我们人眼的途中发生了什么传播行为,例如经过哪几次反射,甚至折射,计算这些光线对我们眼睛成像的贡献(例如这些光线有多亮,是什么颜色的)。而以上过程的核心就是光线是怎么传播的。

那这个核心从算法实现上怎么去完成呢?

光路是可逆的,一条光线从光源发射进入我们的眼睛,这条光路反过来看就是从我们的眼睛发射到碰撞光源,虽然光路逆转了,但是路子是一样的,所以这条光路对我们成像而言没有受到变动影响。从算法上看,如果将眼睛作为光线的发射点的话,那意味着我们追踪的所有光线都是上面说的“能进入我们人眼的”那部分提供成像贡献的光线,从而不需要考虑那大部分没有进入我们人眼的光线,因此对算法而言可以避免更大的计算量。因此光线追踪都是指从我们人眼发射光线,追踪这些光线寻找光源的过程。

而我们人眼在计算机三维空间中可以视作一个坐标点,我们的视网膜可以看作是分辨率800x600的一个网,比喻我们看到的内容由800x600个像素点组成,我们在代码中用缓存来保存起来,例如使用二维数组,另外我们也要记录这个网的三维空间位置。我们将人眼坐标点作为起点,将这个网的其中一个像素的坐标点作为方向,连接起来的一个三维向量就视作一条光线,这条光线进入到场景中便可以说是发射光线,这条光线的贡献值最终计算为它一开始所经过像素点的颜色值,颜色值存入像素缓存区中,当缓存中所有像素点都处理结束,意味着成像结束。可以发现,计算机中实现光线追踪,就是一个三维几何计算的过程,处理的都是三维向量的计算。


光线追踪分类

光线投射(Ray Casting)

有的文章会说光线投射是早期的光线追踪技术,属于光线追踪的一种,或者也有说光线追踪是由光线投射发展而来。我没有刻意去追本溯源,但是在我看来,两者有很大的相似性,也有很明显的区别。先介绍光线投射是怎样的:

先说光线投射用来做什么的,光线投射已经应用了很多年,也有很成熟的实现方法,最主要的用处在“体渲染”(volume rendering)上,体渲染也叫体积渲染,我们常听说的科学可视化中,利用CT图像进行三维重建的这项任务,就是借助体渲染完成的。

光线投射的做法:从人眼(或者摄像机)穿过分辨率网中的像素点,发射光线进入三维场景中,这条光线将一直延伸到给定的终点,光线中途会穿透一切东西,所以光路是直的。然后对这条光路以固定步长来逐个选取采样点,看看采样点有没有穿过体数据,有的话就根据对周围的体数据采样结果来计算贡献值(例如该采样点处的颜色和透明度等,通过插值计算),接着将所有采样点的贡献值汇总叠加在一起作为这条光路的结果值,也就是对应像素的颜色值。每个像素都这么处理完就意味着渲染完毕。

上面的过程中,只有最初时投射出光线进入场景,而没有光线在场景中反射,也就是更像我们做X光那样只有光线的直线穿透,没有模拟光线的物理传播行为,因此严格地也说不上是光线追踪渲染。

经典光线追踪(Classic Ray Tracing)

前文也说过,我们直接百度搜索光线追踪的话,最经常见到的介绍或者原理图,就是这种光线追踪,而经典光线追踪和递归光线追踪这两种也是最容易让刚学习的人搞乱原理,所以要搞清楚光线追踪,很重要的一点就是要清晰地分清楚这两种。

先说经典光线追踪会用来做什么的,用得最多的地方在科学可视化工具领域中,我比较熟悉的是分子可视化工具,工具中用到的光线追踪渲染几乎就是经典光线追踪,而且很早就开始支持光线追踪渲染,并非近几年才开始支持,当然其他领域的可视化工具也是大多使用经典光线追踪。另外在科学可视化领域中如果要渲染出高质量的出版物图像的话,也会使用到经典光线追踪。


版权声明:本文为CSDN博主「864306337」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37366618/article/details/123504877

最新文章