【GAMES202】Real-Time Ray Tracing 1—实时光线追踪1

news2025/1/16 16:09:55

一、前言

这篇我们开始新的话题—Real-Time Ray Tracing简称RTRT,也就是实时光线追踪,关于光线追踪,我们已经不止一次提到过它的优点,无论是软阴影还是全局光照,光线追踪都很容易做,唯一的缺点就是速度太慢了,所以如何把光线追踪做到实时人们进行了大量的研究。

二、Basic idea

1.sample per pixel

提到RTX显卡大家肯定都不陌生,那么RTX干了什么呢,它其实就是增加了一种硬件架构(RT core)能够让我们能够去进行光线追踪而已。 也就是说它属于人们在硬件上的突破。它每秒能追踪10G根光线,看起来虽然很多,但是实际上还要除以分辨率和帧数,并且在1s内还要留时间进行后处理,所以实际上并不多。最后的结果相当于每秒一个像素只用了一个样本的采样。另外我们还要提到一个概念,sample per pixel,以下简称spp,它代表一个光路的样本。

首先最基础的光路spp就需要四条光线构成,如上图所示,首先是primary ray和它的shadow ray,这构成了直接光照,其次就是secondary ray和它的shadow ray,这构成了一次反射的间接光照。当然后续还会有其它更多次反射的间接光照,但以上提到的4条光路是最基本的构成全局光照的光路,我们把这4个光路当成1个spp的样本。

这里可以看到primary ray的前面写了个rasterization,很容易想到,因为本来primary ray实现的效果和光栅化就是相同的,并且光栅化速度更快,这样我们1个spp就可以只用3条光线了。

2.Denoising

那么我们上面提到了1spp,现代的硬件已经允许我们去做1spp的路径追踪了,但是我们之前介绍过路径追踪,如果spp只有1的话,那么得出的结果是有严重的噪声的。所以RTRT的关键技术其实就是降噪

降噪前后的对比图

如上图为spp=1的噪声极为严重的图和降噪后的对比图。

所以综上,我们的目标可以概况为去降噪一个1spp实现的有噪声的画面,不能过于模糊丢失细节,也不能出现渲染的错误,同时要保证降噪时间小于2ms。显然上图提到的已有方法都不可能实现这个目标。

三、Temporal accumulation / filtering

1.Motion vector

而事实上,RTRT降噪的关键就是Temporal。首先我们是假设画面变化是连续的而没有突变,帧和帧之间有一定的连续性,其次我们认为当前帧的前一帧是已经被滤波好了的,也就是一个递归的思想,这是Temporal filtering的一个基本思路。

并且我们引入一个新概念Motion vector,它的作用就是去对应上一帧和当前帧任意一个点的对应位置,也就是它可以告诉我们物体在画面上是怎么运动的。简单地说就是可以知道世界空间下相同物体在不同帧的时候在屏幕上的不同位置。这样也就有一个好处,我们上面说过我们假设画面是连续的,那么Shading一定程度自然也是连续的,也就是说上一帧已经滤波好了的画面可以拿到当前帧复用,并且由于我们的Motion vector已经帮我们对应了同一个物体的在两帧上的不同位置,所以我们很容易知道当前帧的某个像素的颜色应该参考上一帧的哪一个像素。而这也就是时间上的复用的思路,它间接的增加了spp,并且不是简单的从1增加到2,因为我们前面提到它是一个递归,用来降噪的上一帧一定程度上来源于上上帧,所以每一帧对下面所有帧的贡献是一个指数衰减。

2.G-Buffer 

这里我们再引入一个叫做G-Buffer的概念,中文就是几何缓冲区,熟悉延迟渲染的朋友对它一定不会陌生。简单地说其实就是在渲染一幅图的过程中,得到的屏幕空间上储存的一系列信息,如深度图,法线图,世界坐标,基础色(kd)等等。也就是我们渲染的过程中可以免费得到的一些信息,也就是生成储存它们不需要太大的开销。当然,由于它是屏幕空间上的信息自然也会有一些问题。

3.Back Projection

我们前面说的过程中最关键的操作就是找对应,也就是第 i 帧和第 i-1 帧相同世界坐标物体对应的不同像素。也就是当前帧的像素它在上一帧的哪呢?

这里我们设当前帧的屏幕坐标为x,世界坐标为s,那么如果我们有G-Buffer的话我们是可以直接得到x的世界坐标的,当然,没有G-Buffer也没关系,我们知道顶点是通过MVP+视口变换到屏幕坐标的,那么我们知道屏幕坐标x,只需要逆变换就可以了(这里上图写了MVPE四个逆变换,个人觉得大概是闫令琪老师写错了,如果只是回到世界坐标是不需要乘以M矩阵的逆的),同时如果顶点在世界空间移动也没有关系,我们是知道它的变换的,假设它的变换是T矩阵,那么上一帧的世界空间位置s'自然就是s去乘以T的逆,当然如果没有移动那么s=s'。我们如果知道了上一帧的世界空间的位置s',自然就可以通过MVP+视口变换得到上一帧的屏幕空间位置x'(同样的上图最后一行应该是E'P'V',闫令琪老师少写了个E'多写了个M'),这样对应的像素就找到了。

4.Temporal Accum./Denoising

那么找到了对应,如何把两帧结合呢?最简单的操作,把两帧做一个线性的blending。我们设~为没有滤波的有噪声的内容,代表滤波后降噪后的内容。如上图所示\bar{C}^{(i)} = Filter[\tilde{C}^{(i)}]代表我们先对当前帧做一个空间上的滤波,当然我们并不能只依赖于这个Filter,因为我们提过1spp的图像的噪声无论怎么做这个滤波都是无法恢复的。接下来我们用上一帧已经滤波好了的和当前简单滤波过的帧做一个线性blending— \bar{C}^{(i)} = \alpha \bar{C}^{(i)}+(1-\alpha )\bar{C}^{(i-1)},通常α被取0.1~0.2,也就是上一帧占的贡献通常在80%~90%

可以看到1spp再降噪和光线追踪了足够长时间的效果已经非常非常接近了,唯一的瑕疵可能就是在一些AO的地方,因为降噪滤波会导致AO缺失,但是总体来看,效果已经非常不错了。 

四、Failure cases

1.switching scenes

说了这么多时间上的复用,我们接着说它会出现问题的情况,首先第一种情况,画面的突变,比如,镜头的切换,场景光照的突然改变,画面的切换,这种两帧之间没有连续性的情况自然会导致时间上的复用出现问题,通常这种情况下要经过一个burn-in period才会恢复正常,也就是一个预热的时间,我们之前时间上累加的复用效果才会逐渐消失。

2.walking backwards in a hallway

第二种情况是倒退着走,如上图的走廊的例子,在以图中视角倒退的时候我们会发现,屏幕上会不断出现上一帧没有的新的信息,而由于是新的信息,我们找不到对应,也就没法进行复用了,我们把这个归结为屏幕空间的问题,因为屏幕空间的信息有限。

3.suddenly appearing background (disocclusion) 

第三种情况,也就是突然出现的背景,如上图所示,因为某些物体的运动导致原本被这些物体遮挡的东西在第二帧暴露了出来,但是第一帧里并没有相关的信息,在找对应的时候由于是在图像空间上,所以查询到对应的信息是错误的,这种问题实质上也是屏幕空间的缺陷造成的。

而如果这时我们强行用上一帧的信息,就会产生拖尾,残影的效果。

4.Adjustments to Temp. Failure

那么如何避免上面提到的那些问题呢?出现的问题本身是由于无脑使用上一帧的信息导致的,我们只需要有取舍的使用上一帧信息即可。

Clamping

第一种方法自然是调整α的值,使得当前帧的贡献更大一些,当然噪声自然就会增加。

Detection

另一种方法则是我们进行检测,上一帧的信息到底可不可用。工业界上的一种办法,我们会用一个叫Object ID的东西对不同物体标号,我们会渲染一幅图,不同的物体有不同的颜色,这时候假设我们Motion vector找对应物体的ID不同,我们就不去采用上一帧的信息。而如果检测不能用,我们就需要调整blending中α的值了,让本帧的贡献更高一些,当然,噪声也会更多,我们当然可以对本帧的空间滤波增强,不过换来的自然是更模糊的图像,这依然是一种取舍。

5.More Temporal Failure

事实上,时间复用还有更多问题,这里再简单介绍两种,事实上我们前面提到的都是几何上出现的问题,但是其实在着色上也会出现问题。如上图所示,假如场景中的Camera和柱子以及平面都不动,而我们只移动光源的情况下,我们的Motion vector永远都是0,那么它就会永远复用上一帧的信息,这样就会导致阴影的拖尾现象,工业界人们常常叫做detached shadows。

再有就是Glossy反射的问题,如图中的椅子,假设平面不动,那么由于motion vector为0,平面的着色会永远复用上一帧,这样当我们移动影子的时候,平面上的反射效果也会有拖尾,或者说滞后,延迟的效果,反射效果的变化永远慢于实际椅子的变化。

以上两种情况都是Shading的变化造成的问题,这种问题传统的Motion vector并不能解决。

五、Some Side Notes

本篇Temporal方法和TAA也就是时间上的抗锯齿非常相似,它们本质上都是复用上一帧的信息提高一个像素内的采样数。一切利用Temporal的方法如DLSS都是相似的。简单地说,尽管temporal有诸多问题,但是相对来说还是比较好用的。

 


 

参考

GAMES202_Lecture_12 (ucsb.edu)

Lecture 12 Real-Time Ray-Tracing 1_哔哩哔哩_bilibili

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

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

相关文章

时空预测 | 线性时空预测模型、图时空预测

目录 线性时空预测图时空预测 线性时空预测 这篇文章在时空预测领域,搭建了一个简单高效的线性模型,且使用了channel-independence的方式进行建模。 模型的整体结构如下图所示,是一个级联的结构。输入分为三个部分:temporal embed…

java的动态代理如何实现

一. JdkProxy jdkproxy动态代理必须基于接口(interface)实现 接口UserInterface.java public interface UserService {String getUserName(String userCde); }原始实现类:UseServiceImpl.java public class UserServiceImpl implements UserSerice {Overridepub…

布局过程的完全解析

前言 那么为什么要分为两个流程呢 因为测量流程是一个复杂的流程,有时候不一定一遍就能得出测量结果,可能需要 2 - 3 次甚至更多 自定义布局的几种类型,也是自定义布局的两个方法 实战,第一种类型:改写已有View 的步骤…

day34 Map Properties

Map<String,Integer> map new HashMap<>(); map.put("a",1);map.put("b",2);map.put("c",3);map.put("d",4);Integer a map.put("a", 2);System.out.println(a);Integer chinese map.put("语文",1…

新一代G7系列浪潮云海超融合EC纠删功能设计

浪潮云海在2023年5月正式发布新一代InCloud Rail G7系列超融合一体机&#xff0c;其内置的InCloud dSAN超融合存储组件&#xff0c;基于新一代的硬件平台设计&#xff0c;支持全栈RDMA协议&#xff0c;同时在EC纠删功能上也带来全新体验&#xff0c;为新时代用户提供更丰富的产…

PYTHON(一)——认识python、基础知识

一、为什么要学习python&#xff1f; Python 被认为是人工智能、机器学习的首选语言&#xff0c;可以说是全世界最流行通用范围最广的语言&#xff0c;几乎可以完成所有的任务&#xff0c;像设计游戏、建网站、造机器人甚至人工智能等都广泛使用Python。 二、输出&#xff08;…

注解-宋红康

目录 一、注解&#xff08;Annotation&#xff09;概述二、常见的注解实例三、如何自定义注解四、JDK中的四个元注解五、Java8注解的新特性1、可重复注解2、类型注解 一、注解&#xff08;Annotation&#xff09;概述 二、常见的注解实例 三、如何自定义注解 自定义注解必须配…

查询硬盘序列号、物理地址及对应批处理命令

首先说明&#xff1a; 通过winR -> cmd -> diskpart -> list disk -> select disk 0 -> detail disk -> 然后显示磁盘ID等&#xff0c;这不是序列号&#xff0c;只是磁盘ID而已。 查询序列号命令很简单&#xff1a; wmic diskdrive get serialnumber或者 w…

权限、认证与授权

权限、认证与授权 1、权限概述 &#xff08;1&#xff09;什么是权限 权限管理&#xff0c;一般指根据系统设置的安全策略或者安全规则&#xff0c;用户可以访问而且只能访问自己被授权的资源&#xff0c;不多不少。权限管理几乎出现在任何系统里面&#xff0c;只要有用户和…

webstorm HbuilderX工具未配置

问题&#xff1a;调试动迁uni app h5项目&#xff0c;报错 webstorm是换了电脑新安装&#xff0c; HBuilerx是从旧电脑拷贝过来的解压的文件 解决&#xff1a; 把uniapp插件&#xff0c;卸载 再重启webstorm,重装安装uniapp Tool&#xff0c; 安装第一个&#xff0c;免费。…

拓展外部SRAM

外部拓展芯片 IS62WV51216A 芯片手册 支持高速时钟通道时间为45、55ns 芯片引脚定义 通道时序 读定义表 一个纵列表示当前使用的高速通道的时间&#xff0c;选一个纵列作为参数标准。 地址控制读时序 如图&#xff0c;大概需要三个参数 写时序定义表 还是选择55ns参数 写…

数据接口工程对接BI可视化大屏(五)数据接口发布

文章目录 第5章 数据接口发布5.1 编写Service5.2 从MySQL中返回数据5.2.*1 封装Bean5.2.*2 编写Mapper5.2.3 编写ServiceImpl5.2.4 编写Controller5.2.5 测试 5.3 从Redis中返回数据5.3.1 封装Bean5.3.2 编写Mapper5.3.3 编写ServiceImpl5.3.4 编写Controller5.3.5 测试 5.4 从…

day34 Set

概述 Set也是集合Collection接口的子接口 Set也是集合Collection接口的子接口 特点&#xff1a;不保证元素有顺序&#xff0c;数组元素不可以重复 HashSet: 底层是基于HashMap的。元素是无序的。元素不可重复&#xff0c;去重机制是依据hashCode()和equals()方法 LinkedHas…

数据结构-堆的实现及应用(堆排序和TOP-K问题)

数据结构-堆的实现及应用[堆排序和TOP-K问题] 一.堆的基本知识点1.知识点 二.堆的实现1.堆的结构2.向上调整算法与堆的插入2.向下调整算法与堆的删除 三.整体代码四.利用回调函数避免对向上和向下调整算法的修改1.向上调整算法的修改2.向下调整算法的修改3.插入元素和删除元素函…

vue学习之列表渲染

列表渲染 创建 demo8.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…

LeetCode算法心得——判断能否在给定时间到达单元格(动态模拟)

大家好&#xff0c;我是晴天学长&#xff0c;这是一个动态模拟题&#xff0c;跟大佬相比&#xff0c;我的有点繁琐了&#xff0c;但是也算是锻炼到自己的一些细节问题&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。 1) .判断能否在给定时间到达单元…

Pytorch面试题整理(2023.09.10)

1、pytorch如何微调fine tuning&#xff1f; 在加载了预训练模型参数之后&#xff0c;需要finetuning 模型&#xff0c;可以使用不同方式finetune。 局部微调&#xff1a;加载了模型参数后&#xff0c;只想调节最后几层&#xff0c;其他层不训练&#xff0c;也就是不进行梯度…

【Endnote】如何出现“作者(年份) found that ....”的格式?

如何出现“作者&#xff08;年份&#xff09; found that ....”的格式&#xff1f; 非常简单&#xff01;先用endnote插入文献后&#xff0c;默认显示&#xff1a; 然后&#xff0c;重点来了&#xff0c;点开这个&#xff1a; 然后&#xff0c;将此处的default改成Display as…

unique_ptr的大小探讨

unique_ptr大小和删除器有很大关系&#xff0c;具体区别看如下代码的分析。不要让unique_ptr占用的空间太大&#xff0c;否则不会达到裸指针同样的效果。 #include <iostream> #include <memory> using namespace std;class Widget {int m_x;int m_y;int m_z;publ…

国产化改造之Mysql迁移方案:Mysql Galera Cluster

一、背景 因某业务系统OS国产化改造&#xff0c;现需将生成环境Mysql 主从迁移到新部署的BCLinux OS主机上&#xff1b;如果保障业务不断&#xff0c;平滑迁移并成功割接将是本次方案的重要方向&#xff0c;现场环境涉及需迁移数据780G左右&#xff0c;目标主机OS版本&#xff…