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

一、前言

这篇我们开始新的话题—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.mzph.cn/news/78667.shtml

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

相关文章

快速加入Health Kit,一文了解审核流程

HUAWEI Health Kit是为华为生态应用打造的基于华为帐号和用户授权的运动健康数据开放平台。 在获取用户授权后,开发者可以使用Health Kit提供的开放能力获取运动健康数据,基于多种类型数据构建运动健康领域应用与服务,为用户打造丰富、便捷、…

模方新建工程时,显示空三与模型坐标系不一致怎么解决

答:检查空三xml与模型的metadata.xml的坐标系是否一致,metadata文件是否有在data目录外面。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.0新增单体化建模模块,…

【C语言】每日一题(半月斩)——day2

目录 一.选择题 1、以下程序段的输出结果是( ) 2、若有以下程序,则运行后的输出结果是( ) 3、如下函数的 f(1) 的值为( ) 4、下面3段程序代码的效果一样吗( ) 5、对于下面的说法,正确的是&#xf…

Kotlin

函数命名 针对您目前为止学到的 Kotlin 知识,下面给出了一些相关样式指南: 函数名称应采用驼峰式大小写形式,并且应该是动词或动词短语。每个语句都应单独占一行。左花括号应出现在函数开始行的末尾。左花括号前应有一个空格。 变量声明 变…

千兆以太网硬件设计及链路层 MAC 协议格式

以太网系列文章: (1)千兆以太网硬件设计及链路层 MAC 协议格式 (2)千兆以太网网络层 ARP 协议的原理与 FPGA 实现 (3)CRC校验代码原理 文章目录 前言一、以太网 MAC 层接口介绍1.MII 接口2.GMII…

重建大师提交空三后引擎状态是等待,怎么开启?

答:图片中这是在自由网空三阶段,整个AT都是等待中,可以修改任务目录和监控目录看一下,先设置引擎,再提交空三。

可变参数JAVA

public class Main {public static void main(String[] args) {//方法形参的个数是可以变化的//格式:属性类型...名字System.out.println(getSum(1,2,3,4,5,6,7,8));}//通过键值对对象来遍历;public static int getSum(int a,int...args){//可变参数;int…

IDEA2023.2.1取消空包隐藏,切换包结构(Compact Middle Packages)

解决2023版idea的包结构 取消勾选即可。 取消勾选Compact Middle Packages选项后,再创建包时,即可自动创建树形结构。 仅供学习使用!

IP地址,子网掩码,默认网关,DNS讲解

IP地址:用来标识网络中一个个主机,IP有唯一性,即每台机器的IP在全世界是唯一的。 子网掩码:用来判断任意两台计算机的ip地址是否属于同一子网络的根据。最为简单的理解就是两台计算机各自的ip地址与子网掩码进行and运算后&#x…

黑马头条 热点文章实时计算、kafkaStream

热点文章-实时计算 1 今日内容 1.1 定时计算与实时计算 1.2 今日内容 kafkaStream 什么是流式计算kafkaStream概述kafkaStream入门案例Springboot集成kafkaStream 实时计算 用户行为发送消息kafkaStream聚合处理消息更新文章行为数量替换热点文章数据 2 实时流式计算 2…

医学访问学者申请四点规划建议

医学领域一直以来都是人类社会的重要组成部分,而作为一名有志于成为一名医学领域的访问学者,您需要明确自己的目标并做好充分准备。知识人网小编将为您提供四点规划建议,以帮助您成功申请医学访问学者的机会。 第一点:明确研究方向…

OOM分析实战

OOM分析&实战 OOM分析&实战引言:一、JVM内存结构二、JVM OOM错误情况三、实践案例一案例二案例三 四、总结五、分析工具推荐六、参考文献 OOM分析&实战 引言: 在Java开发中,随着应用程序变得越来越复杂,内存管理问题…

Debian11之稳定版本Jenkins安装

系统要求 机器要求 256 MB 内存,建议大于 512 MB 10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像)软件要求 Java 8 ( JRE 或者 JDK 都可以) Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载 Maven 用于构…

【循环冗余码检错示例】

接收方怎么看有错没有 余数为0就是无错!

低代码框架开发平台厂家:做好产品,实现流程化办公!

在新的发展时代,低代码技术平台拥有诸多优势特点,成为广大企业实现降本、增效办公效率的得力助手。什么样的低代码框架开发平台厂家值得信任与青睐?都有哪些主要产品?为了帮助大家了解这一讯息,一起来了解流辰信息低代…

记录一次使用网云穿实现内网穿透操作

记录一次使用网云穿实现内网穿透操作 摘要 这段时间也很少写博客了,一方面工作表较忙,一方面觉得有些东西在百度上都能找到,甚至比我自己记录的详细,有些笔记也就没打, 这次记录笔记主要是觉得这个 网云穿 很好用,分享给大家. 1 什么是内网穿透? 内网穿透也叫内网映射&#xf…

JetBrains设置inline hint的背景色、前景色

如题。修改IDE的hint前景色和背景色。 修改后结果:

2023/9/14 -- C++/QT

作业&#xff1a; 仿照Vector实现MyVector&#xff0c;最主要实现二倍扩容 #include <iostream>using namespace std;template <typename T> class MyVector { private:T *data;size_t size;size_t V_capacity; public://无参构造MyVector():data(nullptr),size(…

数据可视化大屏模板 | 保姆级使用教程

近来很多朋友私信咨询怎么下载使用数据可视化大屏模板&#xff0c;在这里就给大家做一个相对简单的教程总结。有需要的朋友记得先收藏保存&#xff0c;以便不时之需。 数据可视化大屏制作软件&#xff1a;奥威BI系统 数据可视化报表模板板块&#xff1a;模板秀 主要操作&…

Redis常用应用场景

Redis是一款开源的基于内存的键值存储系统&#xff0c;它提供了多种数据结构和丰富的功能&#xff0c;适用于各种不同的应用场景。以下是Redis常用的应用场景&#xff1a; 1.缓存&#xff1a;Redis最常见的用途就是作为缓存。由于Redis存储在内存中&#xff0c;读取速度非常快…