计算机图形学十二光线追踪原理及实现细节

news2024/11/17 9:50:28

Whitted-style(递归式)光线追踪原理及实现细节

摘要

本篇文章主要分两个部分,第一部分会从为什么需要从光线追踪入手,一步步介绍Whitted-style光线追踪的原理,第二部分会具体介绍一些光线追踪的细节,包括光线的表示,光线与物体的求交,以及反射折射方向的计算。

Whitted-Style光线追踪

在进行原理讲解前,我们首先考虑一下为什么会需要光线追踪?因为Blinn-phong这种局部模型无法进行全局效果处理
举个例子:
在这里插入图片描述
如上图中房屋顶部的所接收到的光可不仅仅是Blinn-phong模型考虑的直接光源,还有可能是来自窗外的光源照射到地板上,再发生反射照射到了房屋顶部,而这部分光是局部光照模型没有考虑到的,而光线追踪正式为了解决这个问题所提出的一种考虑全局效果的光照模型。这是再说间接光照无法实现。
其次,软阴影也无法实现。

光线追踪的效果非常好,但是实时性比较差,开销高昂,所以一般是用于离线渲染。

1.1光线追踪原理

光线追踪听名字就知道,讨论的核心是光线,因此我们先对光线进行一些假设。
这些假设在物理学上不一定成立。

1.光线一定沿直线传播
2.光线之间无法碰撞
3.光线路径可逆,即从A发出到B的光线,一定也可以从B发出到A光线(中途可发生反射和折射)

根据第三条假设:光路可逆。
所有进入到人眼的光,都可以从人眼发出光按照原路反方向返回,那么利用这种模拟从人眼发射光线的方法就可以还原所有的光路,这就是光线追踪的核心思想,从光源出发难以模拟那就反着从摄像机发射光线。

第一步 RayCasting

从人眼或摄像机向近投影平面上的每一个像素点发射一条光线,判断与场景物体的交点,示意图如下:
在这里插入图片描述
当然一条光线自然可能会与不止一个物体相交,但是考虑到遮挡关系,只去找最近的交点。接着连接该节点和光源,只需要判断这条连线之间是否有物体存在就知道该交点是否在阴影之中(怎么样,是不是比shadow mapping那一套简单多了)
在这里插入图片描述
接着,自然可以利用Blinn-Phong模型对这个点进行局部光照模型计算,得到该像素的颜色,那么遍历所有近投影平面上的像素就能得到一张完整的图像。但如果光线追踪仅仅是在第一步Ray Casting就停止的话,那么他的效果和局部光照模型是一样的,因此我们需要第二部,真正的考虑全局效果。

第二步Recursive Ray Tracing

考虑第一步中所作的Ray Casting,该条光线第一个与圆球物体相交,假设该圆球是一个玻璃球,那么变回发生镜面反射,如图:
在这里插入图片描述
当然除了镜面反射之外,自然也会存在折射,同时反射与折射出去的光线会可能与场景中的物体再次碰撞,发生第二次折射与反射:
在这里插入图片描述
(为了图示清晰,图中仅以两次折射或反射的部分光线为例)从图中可以见到,不仅仅是与圆球相交的哪一点可以贡献光到眼睛,折射与反射之后在于物体相交的点也可以贡献光(光路可逆原理)。简言之,除了直接从光源照射到圆球交点再沿着eye rays(从眼睛发射的第一条光线)到眼睛中,也可能存在这样一种场景,有光照射到其他物体,再沿着eye rays的反射或者折射的光线防线传回人眼。

因此每一个交点的颜色贡献来自这样几种类型:直接光照,反射方向间接光,折射方向间接光(如果有折射的话)
下一步将这些所有交点与光源连接,称这些线为shadow rays(因为可以用来检测阴影),计算这些所有店的局部光照模型的结果,将其按照光线能量权重累加(该做法与递归过程等价,读者可以看看伪代码思考一下),最终得到近投影平面上该像素点的颜色!而这就是一个考虑全局效果的光照模型了,因为不仅仅考虑了直接光源的贡献,还考虑了各种反射和折射光线的贡献。

以上就是光线追踪的转增个过程了,还有额外绩点要注意的tips:
1.整体过程是依噶递归的过程,因此一定要有一定的递归终止条件,比如说允许的最大反射或折射次数为10.
2.光线在每次反射和折射之后都有能量损失,由系数来决定,因此越往后的折射和反射光的贡献能量越小,这也是为什么在上文中剃刀根据光线能量权重求和。
e.g.反射系数为0.7,那么第一次反射折损30%,第二次反射折损1-(70%*70%),依次类推。
3.如果反射或者折射光线没有碰撞到物体,一般直接返回一个背景色。
4.有一些关于光线的表述,以及如何求交点的实现细节在1.2中进行讨论。

参考的伪代码如下:
在这里插入图片描述
如果读者是第一次接触光线追踪的话,理解起来会有很多的难度,但是只要自己去亲自实现一遍,就能很快的理解其中的原理,因此我们在这里推荐一个我看过的很不错的教程:https://raytracing.github.io/books/RayTracingInOneWeekend.html。
手把手的教你用C++实现一个光线追踪器出来,并且还有很多细节方面原理知识的讲解,写的通俗易懂。

1.2光线的表示方法

我们可以将每一条光线想象成一条射线,那么每一条光线都会由起点及方向这两个属性所固定,如下图:
在这里插入图片描述
除了起点o,以及方向d之外,还额外定义了一个参数t来表示光线行进的长度。

1.3光线与物体求交的方法

光线与隐式曲面求交的方法:
首先介绍如何计算光线与隐式曲面的交点的方法,以一个球体为例,两者表示方程如下:
在这里插入图片描述
光线的表示方法在商界已经介绍过,对于一个球体来说,其表面上所有点p,到圆心c的距离是固定为R的,也就得到了上述的球的隐式曲面方程、

那么对于一个光线会在什么时候与球相交呢?

在这里插入图片描述
当然是在一个点即满足光线方程,有满足球体方程的时候,所以可以计算如下,把p=o+td带入球体方程,利用一元二次方程的解法即可得到参数t值:
在这里插入图片描述
同样的根据b²-4ac的正负关系,即可判断光线与球是一个交点还是两个交点又或是没有交点。

虽然这里只举了对一个球的隐式曲面交点的计算,对于所有其他隐式曲面过程都是类似的,只要将光线方程代入求解t即可,如下图所示:

在这里插入图片描述
光线与显式曲面求交的方法:
当然,真正在图形学中大量运用的其实是显式曲面,更具体来说,就是许许多多个三角形,因此如何判断一条光线与显式曲面的交点,其实就是计算光线与三角形面的交点。对于任意一个平面,可以用如下图中的式子来表示:
在这里插入图片描述
用点法式来表示平面。

图中对于平面方程的讲解已经很清楚。那么到这里其实已经成功把对显示曲面的求交又转化为了类似隐式曲面求交的方法,对于任意一个三角形来说,他一定处于一个平面智商,只需要求出光线与平面的交点,在判断该交点是否在三角形内,就可以得到光线是否与三角形面相交的结果了。

首先给出如何计算光线与平面交点的过程:
在这里插入图片描述
得到参数t之后,自然可以计算出交点,并且再去计算重心坐标就能判断该交点是否在三角形内了,但是这种方法略显繁琐,能不能一步就得到结果呢?当然可以!

在这里插入图片描述
直接将点的形式用重心坐标的形式来表示,随后用克莱姆法则求解线性方程组即可!
(推导过程省略,其实就是使用了线性代数知识里面的克莱姆法则)。

1.4反射与折射

反射方向的计算相对容易,如下图所示,一直l,n想要求出反射方向r。
在这里插入图片描述
计算如下:r=2n(l*n)-l,几何含义便是入射光线l在法向上投影的两倍再减去入射光线l方向,即可得到r。

1.42 折射方向的计算

折射方向的推导其实是由斯奈尔定理(Snell’s Law)得到的:
在这里插入图片描述
其中n,nt分别代表反射平面两边的反射率,如下图所示左半部分为n,右半部分为nt。
在这里插入图片描述
根据sin²+cos²=1以及(1)式,可以推出cos如下:
在这里插入图片描述
但是,这仅仅是求得了反射角度,更希望得到的是向量形式的方向t,因此根据上图,可以得到如下关系(图中皆为单位向量):
在这里插入图片描述
其中b是未知的,但是可以根据入射光线d推出
在这里插入图片描述
如此所有变量都是已知的,计算得到折射方向t如下:
在这里插入图片描述
至此就已经成功得到了折射方向,但是有没有什么问题呢?这就要说到菲涅尔反射了。

1.43菲尼尔反射(Fresnel Reflection)

注意在计算折射方向时,用到了
在这里插入图片描述
显而易见,
一定要确保根号里面的是正数,那么有没有可能会是负数呢?我们说这是有可能的,如果从一个折射率大的空间折射入一个折射率小的空间,折射角度会增大,且会有n/nt 》1,只要入射角度足够大,1-cos²就接近1,那么此时根号里面的数便会小于0,而这也就意味着,才是没有折射项,光线全部反射。

大家不妨在家实验一下,如果你垂直观察玻璃,你很容易看清玻璃外的东西(折射而来),如果你视线与玻璃近乎平行,此时你看到的大部分会是你自己(反射得到的),且实现越与玻璃平行,即与法线夹角越大,你的人像越加清晰,这种现象,就可以用菲涅尔反射来进行解释。

在这里插入图片描述
简单来说,便是物体的反射率其实与你的观察角度有关,对于绝缘物体来说观察角度与法线夹角越大,反射的程度就越大,如下图:
在这里插入图片描述
(其中光线极化什么的那两条线不用太去管,只要知道对于绝缘体角度越大反射越多即可),而导体则与绝缘体不同,他的反射率与夹角呈如下关系。
在这里插入图片描述
想想金属确实反射率一直很大,所以很有光泽。符合上图的规律。

那么对于任意一个物体该去怎么计算出它的精确的反射率呢?计算公式如下:
在这里插入图片描述
当然这里考虑了两个极化,然后再求平均,我们不需要知道为什么这样算,只要知道,物体的反射率和入射角度,和入射空间的折射率,和物体的折射率有关就可以了。然后套公式算就能得出正确的反射率了!那么对于精确的算法来说,可以看到计算量是非常大的,因此就有大佬提出了个简单的算法,近似得到结果,但计算量大大减小,如下:
在这里插入图片描述
Note:whitted-style光线追踪该如何考虑漫反射?
在blinn-phong模型中曾提到过,漫反射是光线照射到粗糙物体表面从而发生向周围均匀反射光线的一种现象,反射的光线可以说是无数的!!!
在这里插入图片描述
那么对于这种反射,在光线追踪该怎么处理呢?借鉴RayTracingInOneWeekend里的做法,对于漫反射表面每次进行反射的时候,随机的选取物体表面向外半圆内的一个方向作为该次反射的方向,对齐再像镜面反射及折射一样进行递归的光线追踪计算。

但对每一个像素不仅仅只发出一条感知光线,利用多条光线RayTracing的结果求均值,最终作为该像素的颜色值。

比如说我每个像素sample 1000条光线,如果撞到漫反射表面那就是1000条随机方向的RayTracing结果的均值,这样便能较为准确的模拟了漫反射表面的特性了。(对一个像素进行多次sample,其实也就把抗锯齿给做了)。

(tips:该方法其实更多算是path tracing,经典的whited-style光线追踪遇到漫反射表面会直接利用blinn-phong模型计算颜色值返回,而不再递归下去)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/800335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谷粒商城第六天-实现功能的前序工作(网关的配置 跨域配置)

目录 一、为什么要做这项工作 1.1 为什么要配置网关 1.2 为什么要使用网关统一配置跨域 二、网关配置 三、统一跨域配置 四、总结 一、为什么要做这项工作 1.1 为什么要配置网关 我们知道网关的作用其实主要就是进行路由的,也就是根据前端发送到网关的请求&…

无涯教程-jQuery - unbind()方法函数

unbind([type],[fn])方法的作用与bind相反,它从每个匹配的元素中删除绑定事件。 unbind( [type], [fn] ) - 语法 selector.unbind( [type], [fn] ) 这是此方法使用的所有参数的描述- type - 一种或多种事件类型,以空格分隔。 fn …

【机器学习】基础知识点的汇总与总结!更新中

文章目录 一、监督学习1.1、单模型1.1.1、线性回归1.1.2、逻辑回归(Logistic Regression)1.1.3、K近邻算法(KNN)1.1.4、决策树1.1.5、支持向量机(SVM)1.1.6、朴素贝叶斯 1.2、集成学习1.2.1、Boosting1&…

本地文件夹上传到Github

本地文件夹上传到Github 步骤1. 下载git步骤2. 在github中新建一个库(Repository)步骤3. 设置SSH key步骤4. 添加SSH keys步骤5. 本地文件上传到github参考 步骤1. 下载git 下载git客户端,并在本地安装完成。 步骤2. 在github中新建一个库&a…

解决 Windows 11 原生输入法卡顿问题

文章目录 词库损坏问题方法1. 删除个人词库方法2. 删除中文词库 网络延迟问题方法3:关闭云服务 资源调度问题方法4:调整优先级 升级兼容问题方法5:关闭兼容性(针对 Win10 升级 Win11 的部分用户) 终极大招 不知道有没有…

嵌入式数据库之SQLite

1.SQLite简介 轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据 库用于管理多端设备,更加复杂。 SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库&#x…

项目2 | 负载均衡式在线OJ

啊我摔倒了..有没有人扶我起来学习.... 👱个人主页: 《 C G o d 的个人主页》 \color{Darkorange}{《CGod的个人主页》} 《CGod的个人主页》交个朋友叭~ 💒个人社区: 《编程成神技术交流社区》 \color{Darkorange}{《编程成神技术…

【Vue3】父子组件传参

1. 父组件给子组件传值 父组件App.vue <template><div>父级</div><waterFallVue :title"name"></waterFallVue> </template><script setup lang"ts"> import waterFallVue from ./components/waterFall.vue …

基于Autoencoder自编码的64QAM星座图整形调制解调通信系统性能matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1星座图整形 4.2自编码器 4.3基于Autoencoder的星座图整形调制解调模型 4.4 实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .…

Vue--》打造个性化医疗服务的医院预约系统(四)

今天开始使用 vue3 + ts 搭建一个医院预约系统的前台页面,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关…

ubuntu ssh

前置 需要知道自己的ip 如果没有ifconfig sudo apt-get install net-tools然后 ifconfig中文用户 winr,输入 intl.cpl在git里&#xff0c;选zh_cn和UTF-8 安装 sudo apt-get install -y openssh-client openssh-server设置开机启动 sudo systemctl enable sshsudo nano…

政策加持智能家居市场,涂鸦赋能客户打造“以人为本”智能生活新方式

7月18日&#xff0c;商务部等13部门联合发布了《关于促进家居消费若干措施的通知》&#xff08;以下简称《通知》&#xff09;&#xff0c;《通知》指出&#xff0c;创新培育智能消费&#xff0c;支持企业运用物联网、云计算、人工智能等技术&#xff0c;着重加快智能家电、智能…

Sharding-JDBC强制路由案例实战

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…

【QT】Day 2

1> 继续完善登录框&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;跳转到新的界面中 second.h #ifndef SECOND_H #define SECOND_H#include <QWidget>namespace Ui { class second; }class second : public QWidget {Q_OBJECTpublic:explicit second…

安装Exchange 2010 中在准备情况检查时始终要求重启系统解决方法

1、重新启动系统并重新运行安装程序”&#xff0c;重启后再进行安装故障依旧&#xff0c;故障如下&#xff0c;图为引用&#xff1a; 2、解决方法如下&#xff1a; 运行regedit打开注册表。 查找到以下键值PendingFileRenameOperations&#xff0c;&#xff08;位置&#xff1…

Golang速成

目录 Golang 语言特性Golang的优势Golang 的应用场景Golang 的不足 基础语法变量的声明常量与 iotastring字符串遍历strings 包bytes 包strconv 包unicode 包 循环语句range 函数多返回值init 函数闭包import 导包匿名函数 指针defer切片 slice数组sliceslice 操作… mapmap 的…

shopee,lazada,etsy店群如何高效安全的管理

对于电商卖家来说&#xff0c;要经营多个店铺&#xff0c;管理多个账号是非常常见的操作。为了避免账号关联被平台识别出来&#xff0c;需要使用防关联的浏览器来进行操作 ​1、支持多平台 支持同时管理多个电商平台店铺&#xff0c;Shopee、Lazada、etsy、poshmark、vinted等&…

vue element ui web端引入百度地图,并获取经纬度

最近接到一个新需要&#xff0c;要求如下&#xff1a; 当我点击选择地址时&#xff0c;弹出百度地图&#xff0c; 效果如下图&#xff1a; 实现方法&#xff1a; 1、首先要在百度地图开放平台去申请一个账号和key 2、申请好之后&#xff0c;在项目的index.html中引入 3、…

windows安装npm, 命令简介

安装步骤 要在Windows上安装npm&#xff0c;按照以下步骤操作&#xff1a; 首先&#xff0c;确保您已经在计算机上安装了Node.js。可以从Node.js官方网站&#xff08;Node.js&#xff09;下载并安装Node.js。完成Node.js的安装后&#xff0c;打开命令提示符&#xff08;Command…

springboot第32集:redis系统-android系统-Nacos Server

Error parsing HTTP request header HTTP method names must be tokens 检查发送HTTP请求的客户端代码&#xff0c;确保方法名中不包含非法字符。通常情况下&#xff0c;HTTP请求的方法名应该是简单的标识符&#xff0c;例如"GET"、"POST"、"PUT"…