【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.rhkb.cn/news/133170.html

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

相关文章

状态管理艺术——借助Spring StateMachine驭服复杂应用逻辑

文章目录 1. 什么是状态2. 有限状态机概述3. Spring StateMachine4. Spring StateMachine 入门小案例4.1 接口测试 5. 总结 1. 什么是状态 在开发中,无时无刻离不开状态的一个概念,任何一条数据都有属于它的状态。 比如一个电商平台,一个订…

第31章_瑞萨MCU零基础入门系列教程之WIFI蓝牙模块驱动实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…

(LeetCode)两数相加深入分析Java版

两数相加(题目如下) 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数…

【深度学习】Pytorch 系列教程(二):PyTorch数据结构:1、Tensor(张量): GPU加速(GPU Acceleration)

目录 一、前言 二、实验环境 三、PyTorch数据结构 0、分类 1、张量(Tensor) 1. 维度(Dimensions) 2. 数据类型(Data Types) 3. GPU加速(GPU Acceleration) 一、前言 ChatGP…

【Linux环境】基础开发工具的使用:yum软件安装、vim编辑器的使用

​👻内容专栏: Linux操作系统基础 🐨本文概括: yum软件包管理、vim编辑器的使用。 🐼本文作者: 阿四啊 🐸发布时间:2023.9.12 Linux软件包管理 yum 什么是软件包 在Linux下安装软件…

【LeetCode-简单题】剑指 Offer 58 - II. 左旋转字符串

文章目录 题目方法一:连续双指针翻转 题目 方法一:连续双指针翻转 class Solution {public String reverseLeftWords(String s, int n) {StringBuffer sb new StringBuffer(s);reverseWord(sb,0,n-1);reverseWord(sb,n,sb.length()-1);return sb.revers…

WebServer 解析HTTP 响应报文

一、基础API部分&#xff0c;介绍stat、mmap、iovec、writev、va_list 1.1 stat​ 作用&#xff1a;获取文件信息 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>// 获取文件属性&#xff0c;存储在statbuf中 int stat(const char *…

CH06_第一组重构(上)

提取函数&#xff08;Extract Function |106&#xff09; 曾用名&#xff1a;提炼函数&#xff08;Extract Function&#xff09; 反向重构&#xff1a;内联函数&#xff08;115&#xff09; 示例代码 function printOwing(invoice) {printBanner();let outstanding calcul…

SpringBoot表现层数据一致性

1.定义Restful类 说明&#xff1a;使用Data注解是Lombok库提供的一个注解&#xff0c;用于自动生成类的getter、setter、equals、hashcode和toString方法。 package com.forever.controller.utils;import lombok.Data;Data public class Restful {private Boolean flag;//dat…

Redis 常用命令

目录 全局命令 1&#xff09;keys 2&#xff09;exists 3) del(delete) 4&#xff09;expire 5&#xff09;type SET命令 GET命令 MSET 和 MGET命令 其他SET命令 计数命令 redis-cli&#xff0c;进入redis 最核心的命令&#xff1a;我们这里只是先介绍 set 和 get 最简单的操作…

Java集合(Collection、Iterator、Map、Collections)概述——Java第十三讲

前言 本讲我们将继续来讲解Java的其他重要知识点——Java集合。Java集合框架是Java编程语言中一个重要的部分,它提供了一套预定义的类和接口,供程序员使用数据结构来存储和操作一组对象。Java集合框架主要包括两种类型:一种是集合(Collection),存储一个元素列表,…

MySQL入门指南:数据库操作的基础知识

当谈到关系型数据库管理系统(RDBMS)时&#xff0c;MySQL无疑是最常见和广泛使用的一个。它是一个强大的工具&#xff0c;用于存储、管理和检索数据。在这篇博客中&#xff0c;我们将介绍MySQL的基本知识&#xff0c;包括数据库的操作、数据表的操作以及数据的增删改查~~ 目录 …

嵌入式学习笔记(27)uart stdio的移植

什么是stdio&#xff1f; &#xff08;1&#xff09;#include <stdio.h> &#xff08;2&#xff09;stdio:standard input output &#xff08;3&#xff09;stdio是os定义的默认的输入和输出通道。一般在PC机的情况下&#xff0c;标准输入指的是键盘&#xff0c;标准…

VIOOVI干货分享:企业车间动作作业分析如何改善?

企业车间动作作业分析是将操作动作分解为最小的分析单位&#xff0c;我们通常称之为动素。通过对动素的定性研究&#xff0c;找出合理有效的动作&#xff0c;缩短操作时间&#xff0c;实现标准化操作。在实际应用中&#xff0c;应分析和研究操作员的各种动作&#xff0c;去除没…

深入探讨Kubernetes(K8s)在云原生架构中的关键作用和应用

文章目录 1. 容器化的应用程序管理2. 自动化扩展和负载均衡3. 容器编排和调度4. 存储管理5. 自动化滚动更新6. 多云和混合云部署7. 监控和日志8. 安全9. 社区支持和生态系统10. 未来展望案例 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1…

Nginx部署前后端分离项目(Linux)

Nginx代理前端页面、后端接口 一、前端打包二、后端打包三、Linux部署Nginx启动、暂停、重启服务器部署文件地址&#xff1a; 一、前端打包 npm run build二、后端打包 通过Maven 使用package打包 三、Linux部署 安装Nginx 安装环境 yum -y install gcc pcre pcre-devel z…

SpringMVC系列(七)之自定义注解

目录 一. Java注解简介 1.1 Java注解分类 1.2 JDK基本注解 Override Deprecated SuppressWarnings 1.3 JDK元注解 从 Java 7 开始&#xff0c;额外添加了 3 个注解: 1.4 自定义注解 如何自定义注解&#xff1f; 二. 自定义注解示例 枚举类&#xff1a; 示例一&…

【JUC】Java并发编程从挖坑到入土全解(一)

目录 线程基础知识 作者&#xff08;拜个神&#xff09; 什么是JUC 为什么会出现多线程 硬件方面 摩尔定律失效 软件方面 弊端 & 问题 从线程启动开始 Java线程理解以及openJDK的实现 更加底层的的C源码 线程基础知识 作者&#xff08;拜个神&#xff09; Dou…

A Mathematical Framework for Transformer Circuits—(三)

A Mathematical Framework for Transformer Circuits Two-Layer Attention-Only TransformersThree Kinds of CompositionPath Expansion of LogitsPath Expansion of Attention Scores QK CircuitAnalyzing a Two-Layer ModelInduction HeadsInduction heads的功能Induction h…

CVE-2023-1454:Jeecg-Boot SQL注入漏洞复现

文章目录 Jeecg-Boot SQL注入漏洞(CVE-2023-1454)复现0x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 Jeecg-Boot SQL注入漏洞(CVE-2023-1454)复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事…