13 Games101 - 笔记 - 光线追踪(Whitted-Style光线追踪原理详解及实现细节)

news2024/11/25 8:21:50

13 光线追踪(Whitted-Style光线追踪原理详解及实现细节)

引入光线追踪的原因

光栅化的缺点:不能很好的处理全局光照。(因为Blinn-Phong这种局部模型无法处理全局效果!)

  • 光栅化:快 real-time 质量低
  • 光线追踪:慢 offline 质量高

1 Whitted-Style 光线追踪

1.1 光线追踪原理解释

光线追踪听名字就知道,讨论的核心是光线,因此我们首先对光线做一些假设。

1 光线一定沿着直线传播

2 光线之间无法碰撞

3 光线路径可逆,即从A发出的到B的光线,一定也可以从B发出到A(中途可发生反射和折射)

明白了光线的一些假设之后,想一想人为什么能看到不同的物体?是因为从物体表面上有光进入了人眼。那么能不能逆向思考一下,是不是也可理解为人眼发出了很多感知光线碰撞到了物体,所以可以看见呢?在古代可还真就有不少人这么想:

image-20240327171939365

当然,现代物理知识已经告诉我们这种观点是错误的,但是并不妨碍从中获取一些灵感,考虑一下对光线的第三条假设:光路可逆,所有进入到人眼的光,都可从人眼发出光按照原路反方向返回,那么利用这种模拟从人眼发射光线的方法不就可以还原出所有的光路了呢?没错这就是光线追踪的核心想法,从光源出发难以模拟那就反着从摄像机发射光线!

第一步 Ray Casting

从人眼或摄像机向近投影平面上的每一个像素点发射一条光线,判断与场景物体的交点,示意图如下:

image-20240327172710930

当然一条光线自然可能会与不止一个物体相交,但是考虑遮挡关系,只去找最近的交点。接着连接该交点和光源,只要判断这条连线之间是否有物体存在就可以知道该交点是否在阴影之中(怎么样,是不是比shadow mapping那一套简单了许多):

image-20240327172855369

紧接着,自然可以利用Blinn-Phong模型对这个点进行局部光照模型计算,得到该像素的颜色,那么遍历所有近投影平面上的像素就能得到一张完整的图像。但如果光线追踪仅仅是在第一步Ray Casting就停止的话,那么它的效果与局部光照模型是一样的,因此我们需要第二步,真正的考虑全局效果。

第二步 Recursive (Whitted-Style) Ray Tracing

考虑第一步中所做的Ray Casting,该条光线第一个与圆球物体相交,假设该圆球是一个玻璃球,那么便会发生镜面反射,如图:

image-20240327173024707

当然除了镜面反射之外,自然也存在折射,同时反射与折射出去的光线会可能与场景中的物体再次碰撞,发生第二次折射与反射:

image-20240327173401614

(为了图示清晰,图中仅以两次折射或反射的部分光线为例) 从图中可以见到,不仅仅是与圆球相交的那一点可以贡献光到达眼睛,折射与反射之后再与物体相交的点也可以贡献光(光路可逆原理)。简而言之,除了直接从光源照射到圆球交点再沿着 eye rays(从眼睛发射的第一条光线)到眼睛中,也可能存在这样一种情形,有光照射到其他物体,再沿着eye rays的反射或折射的光线方向传回人眼!

因此每一个交点的颜色贡献来自这样种几类型 直接光照,反射方向间接光,折射方向间接光(如果有折射的话)

定义三种光线:

  • primary ray:眼睛直接发出的光线
  • secondary ray:间接发出的光线
  • shadow ray:物体交点间接发出到光源的光线

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

以上就是光线追踪的整个过程了,还有额外几点要注意的 tips:

  1. 整体过程是一个递归的过程,因此需要一定的递归终止条件,比如说允许的最大反射或折射次数为10。
  2. 光线在每次反射和折射之后都有能量损耗的,由系数决定,因此越往后的折射和反射光贡献的能量越小,这也是为什么在上文中提到根据光线能量权重求和。 e.g. 反射系数为0.7,那么第一次反射折损30%,第二次反射折损1-(70%x70%),依次类推。
  3. 如果反射或折射光线没有碰撞到物体,一般直接返回一个背景色。
  4. 有一些关于光线表示,及如何求交点的实现细节在1.2节里讨论。

参考伪代码如下:

img

2 光线的表示方法

我们可以将每一条光线想象成一条射线,那么每一条光线都会由起点及方向这两个属性所固定,如下图所示:

image-20240327173844365

除了起点 o, 以及方向 d之外,还额外定义了一个参数 t 来表示光线行进的长度。

3 光线与物体求交的方法

3.1 光线与隐式曲面求交的方法

首先介绍如何计算光线与隐式曲面的交点的方法,以一个球体为例,二者表示方程如下:

image-20240327174055522

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

当然是在一个点即满足光线方程,又满足球体方程的时候,所以可以计算如下,把 �=�+��代入球体方程,利用一元二次方程的解法即可得到参数 t 值:

image-20240327181904979

同样的根据 b^2与 4ac 的正负关系,即可判断光线与球是一个交点还是两个交点又或是没有交点。

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

image-20240327182022845

3.2 光线与显示曲面求交的方法

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

image-20240327182203647

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

首先给出如何计算光线与平面交点的过程:

image-20240327182256921

得到参数 t 之后,自然可以计算出交点,并且再去计算出重心坐标就能判断该交点是否在三角形内了,但是这种方法略显繁琐,能不能一步就得到结果呢?当然可以!

image-20240327182407667

直接将点的形式用重心坐标的形式表示,随后利用克莱姆法则求解线性方程组即可!(推导过程省略,但其实就是用了线代知识里面的克莱姆法则。)

4 反射与折射

4.1 反射方向的计算

反射方向计算相对容易,如下图所示,已知 l, n 想要求出反射方向 r

image-20240327182705301

4.2 折射方向的计算

image-20240327182822563

image-20240327182840039

4.3 菲涅耳反射(Fresnel Reflection)

image-20240327183150714

image-20240327183224419

image-20240327183241840

image-20240327183259722

Note:whited-style光线追踪该如何考虑漫反射?

在Blin-Phong模型中层提到过,漫反射是光线照射到粗糙物体表面从而发生向周围均匀反射光线的一种现象,反射的光线可以说是无数的!

那么对于这种反射,在光线追踪该怎么处理呢?借鉴**RayTracingInOneWeekend** 里的做法,对于漫反射表面每次进行反射的时候,随机的选取物体表面向外半圆内的一个方向作为该次反射的方向,对其再像镜面反射及折射一样进行递归的光线追踪计算。

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

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

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

更多的细节,读者可以自行的去连接里面看。

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

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

相关文章

LeetCode:718最长重复子数组 C语言

718. 最长重复子数组 提示 给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1: 输入:nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出:3 解释:长度最长的公共子数组是 [3,…

【产品经理】华为IPD需求管理全思路分享!

作为一名产品经理,会在日常工作中接收到各种需求,而解决需求要提供对应的解决方案。本篇文章以华为的IPD需求管理流程为例,探讨其需求管理思路,帮助产品岗位的你快速做好需求管理并解决方案。 一、理清什么是产品需求 说到这个话…

【软考中级】网络工程师:9.网络操作系统与服务器

9.1 本地用户和组 Windows Server 2008R2 本地用户与组 用户:包含用户名、密码、权限以及说明。 用户组:具有相同性质的用户归结在一起,统一授权,组成用户组。 创建用户和组:我的电脑-右键-管理-计算机管理-本地用…

BaseDao封装增删改查

文章目录 什么是BaseDao操作代码增删改查询单个数据查询多个数据 总结 什么是BaseDao BaseDao是: 数据库里负责增加,删除,修改,查询 具体来说是一种接口代码,公共方法的接口类。 在dao层新建basedao,其他dao层接口继承basedao 相…

【AIGC】如何在Windows/Linux上部署stable diffusion

文章目录 整体安装步骤windows10安装stable diffusion环境要求安装步骤注意事项参考博客其他事项安装显卡驱动安装cuda卸载cuda安装对应版本pytorch安装git上的python包Q&A linux安装stable diffusion安装anaconda安装cudagit 加速配置虚拟环境挂载oss(optional…

Transformers —— 以通俗易懂的方式解释-Part 1

公众号:Halo咯咯,欢迎关注~ 本系列主要介绍了为ChatGPT以及许多其他大型语言模型(LLM)提供支持的Transformer神经网络。我们将从基础的Transformer概念开始介绍,尽量避免使用数学和技术细节,使得更多人能够理解这一强大的技术。 Transformers —— 以通俗易懂的方式解释…

5、axios请求、动画、组件、路由重定向、UI组件

一、axios请求 Axios是一个基于Promise的HTTP状态库&#xff0c;封装ajax。ajax包含axios安装 npm install axios 引入 import axios form “axios” 1、get请求 <script> // 1.本页面引入 import axios from "axios";data() {return {imgSrc: ""…

Polar靶场web(三)

期待得到某一件事物的时候&#xff0c;才是最美好的。 签到 发现不能提交&#xff0c;看一下f12 发现提交按钮被禁用了&#xff0c;且最大输入9个字符&#xff0c;我们可以改一下。 现随便提交一个发现要提交ilovejijcxy session文件包含 发现有文件包含&#xff0c;那先包含…

Yolo 自制数据集dect训练改进

上一文请看 Yolo自制detect训练-CSDN博客 简介 如下图&#xff1a; 首先看一下每个图的含义 loss loss分为cls_loss, box_loss, obj_loss三部分。 cls_loss用于监督类别分类&#xff0c;计算锚框与对应的标定分类是否正确。 box_loss用于监督检测框的回归&#xff0c;预测框…

深入理解Java接口:定义、使用与重要性(day13)

导语&#xff1a;Java接口是Java编程语言中的一个核心概念&#xff0c;它提供了一种定义方法但不包含方法实现的方式。接口在Java编程中扮演着重要角色&#xff0c;能够帮助我们实现代码的高内聚、低耦合&#xff0c;提高代码的复用性和可维护性。本文将详细介绍Java接口的定义…

蓝桥杯刷题第四天

思路&#xff1a; 这道题很容易即可发现就是简单的暴力即可完成题目&#xff0c;我们只需满足所有数的和为偶数即可保证有满足条件的分法&#xff0c;同时也不需要存下每个输入的数据&#xff0c;只需要知道他是偶数还是奇数即可&#xff0c;因为我们只需要偶数个奇数搭配在一块…

PLC通讯时如何判断选用MODBUS方式还是现场总线方式?

在工业自动化领域&#xff0c;PLC扮演着至关重要的角色。然而&#xff0c;许多人在初次接触PLC通讯时&#xff0c;常因其复杂性而感到困扰。事实上&#xff0c;PLC的通讯并不如人们想象中的那么神秘&#xff0c;它主要只有两种类型&#xff1a;一种是需要编写代码的通讯方式&am…

深度学习(四)笔记1

0.前提 往后我会以我的笔记形式来发布我的文章&#xff08;每3次笔记为一篇文章&#xff09;&#xff0c;有爱的人可以自取学习&#xff0c;当然如果可以的话我会把我的文章翻出来变成文章。 1.数据操作 本期4.1数据操作的链接在这。 链接&#xff1a;https://pan.baidu.com/s…

Spring Cloud+Spring Alibaba笔记

Spring CloudSpring Alibaba 文章目录 Spring CloudSpring AlibabaNacos服务发现配置中心 OpenFeign超时机制开启httpclient5重试机制开启日志 SeataSentinel流量控制熔断降级热点控制规则持久化集成 OpenFeign集成 Gateway MicrometerZipKinGateway路由断言过滤器 Nacos 服务…

01_安装VMwareWorkstation虚拟机

环境&#xff1a;Win10 19045 软件版本&#xff1a;VMware-workstation-17.5.1 一、下载链接 Download VMware Workstation Pro 二、安装&#xff08;无脑下一步&#xff09; 安装位置自选&#xff0c;最好非系统盘。 增强型键盘驱动自选。 更新自选。 快捷方式自选。 三、…

CListCtrl中高亮插入行,条目上移下移

1. 样式修改 2. 关键代码 BOOL CMFCApplication3Dlg::OnInitDialog() {CDialogEx::OnInitDialog();// // 代码省略......//// 设置此对话框的图标。 当应用程序主窗口不是对话框时&#xff0c;框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIc…

linux 系统安装php 8.0.2

1. 安装包准备 https://www.php.net/distributions/php-8.0.22.tar.gz 我下载到 /usr/local/src 这个目录了 cd /usr/local/srcwget https://www.php.net/distributions/php-8.0.22.tar.gz 2. tar 解压 然后进到解压的文件夹 tar -zxvf php-8.0.22.tar.gz cd php-8.0.2…

【前端面试3+1】05v-if和v-show的区别、v-if和v-for能同时使用吗、Vuex是什么?【合并两个有序链表】

一、v-if和v-show的区别 v-if 和 v-show 是 Vue.js 中用来控制元素显示与隐藏的指令。 1.v-if&#xff1a; v-if 是根据表达式的真假值来决定是否渲染元素。当表达式为真时&#xff0c;元素会被渲染到 DOM 中&#xff1b;当表达式为假时&#xff0c;元素不会被渲染到 DOM 中。每…

【论文通读】UFO:A UI-Focused Agent for Windows OS Interaction

UFO&#xff1a;A UI-Focused Agent for Windows OS Interaction 前言AbstractMotivationMethodsExperimentConclusion 前言 Windows客户端第一个JARVIS&#xff0c;利用GPT4 Vision识别截图信息辅助智能体自动化执行操作&#xff0c;作为微软大肆宣传的一篇工作&#xff0c;其…

Ubuntu20.04下PCL安装,查看,卸载等操作

Ubuntu20.04下PCL安装&#xff0c;查看&#xff0c;卸载等操作 项目来源 https://github.com/PointCloudLibrary/pclhttps://pointclouds.org/documentation/modules.htmlhttps://pcl.readthedocs.io/projects/tutorials/en/master/ 点云学习&#xff1a; https://github.c…