大家好~这三个月以来,我一直在学习和实现“基于WebGPU的混合光线追踪实时渲染”的技术,使用了Ray Tracing管线(如.rgen、.rmiss等着色器)。

现在与大家分享和介绍我目前的学习成果,希望对大家有所帮助!谢谢!

通过国外的开源项目,可在WebGPU中使用Ray Tracing管线

这三个月我对Ray Tracing的研究有了质的突破,主要归功于我发现的WebGPU Node开源项目!

该作者首先在dawn-ray-tracing开源项目中对“dawn项目:Chrome对WebGPU的实现"进行了扩展,加入了光追的API;

然后在WebGPU Node开源项目中,底层封装了Vulkan SDK,上层使用了dawn-ray-tracing项目,提供了WebGPU API,实现了在Nodejs环境中使用WebGPU API和Ray Tracing管线来实现硬件加速的光线追踪(电脑需要使用nvdia的RTX显卡)!

相关介绍参见:

Real-Time Ray-Tracing in WebGPU

搭建运行环境

有两种方法来搭建运行环境:

1、给Chrome浏览器打补丁,使其与下载DXR驱动(DirectX Raytracing)关联,从而在该浏览器中运行

详见该作者最近写的开源项目:chromium-ray-tracing

(我没有测试过,不知道是否能使用)

2、编译dawn-ray-tracingWebGPU Node项目,从而在Nodejs环境中运行

我使用的是这个方法(不过我使用的WebGPU Node项目是今年3月份时的代码,最新的代码我还没有测试过)。

我的操作系统是win7,显卡是RTX 2060s,vulkan sdk是1.1.126.0版本

编译的步骤为(需要使用VPN翻墙):

# 编译dawn-ray-tracing项目

## Clone the repo as "dawn-ray-tracing"
git clone https://github.com/maierfelix/dawn-ray-tracing cd dawn-ray-tracing ## Bootstrap the gclient configuration
cp scripts/standalone.gclient .gclient ## Fetch external dependencies and toolchains with gclient
gclient sync set DEPOT_TOOLS_WIN_TOOLCHAIN=0 npm install --global --production windows-build-tools gn gen out/Shared --ide=vs --target_cpu="x64" --args="is_component_build=true is_debug=false is_clang=false" ninja -C out/Shared # 编译webgpu node项目 npm install webgpu 在webgpu node的根目录中创建名为“PATH_TO_DAWN”的文件,在其中指定dawn-ray-tracing项目的绝对路径,如:
D:/Github/dawn-ray-tracing 在webgpu node的根目录中执行:
npm run all --dawnversion=0.0.1

这里要注意的是,需要先安装Vulkan SDK和python; 可以通过“npm config set python C:\depot_tools\python.bat”来设置python路径,或者指定python路径:
npm run all --dawnversion=0.0.1 --python="C:\Users\Administrator\Downloads\depot_tools\bootstrap-3_8_0_chromium_8_bin\python\bin\python.exe"
) # 在nodejs中运行ray tracing示例,验证是否成功 进入webgpu node的根目录 cd examples & cd ..
node --experimental-modules examples/ray-tracing/index.mjs

应用场景

考虑到WebGPU还没有正式发布,并且可能在三年内浏览器都不会支持Ray Tracing管线,所以我把渲染放到云端,这样就可以在云端自行搭建环境(如使用WebGPU Node开源项目),然后通过网络传输将渲染结果传输到客户端,从而在客户端浏览器不支持的情况下仍能显示光追渲染的画面。

因此,我的应用场景为:

1、云渲染

2、云游戏

这两个应用场景有不同的需求:

“云渲染”属于离线渲染,我们关心的是:

  • 画质要好
  • 渲染时间可以长点

因此:

  • 每帧可采样多次,即n spp(n >= 30)
  • 支持多种渲染效果,如“焦射”(causicts)等
  • 全局光照可使用n次bounce(n >= 2)

“云游戏”属于实时渲染,我们关心的是:

  • 画质可以差点
  • 渲染时间要短(每帧30ms以内)

因此:

  • 每帧只采样一次,即1 spp
  • 全局光照只使用一次或两次bounce
  • 对“焦射”(causicts)等场景用性能好的方案达到接近的渲染效果,通过牺牲画质来减少渲染时间

介绍我目前的实现方案

主要技术框架是“实时混合光线追踪”,主要包含下面的pass:

1、gbuffer pass

创建gbuffer

2、ray tracing pass

直接从gbuffer中获取world position、diffuse等数据,用来计算直接光照,从而减少了每个像素发射的光线数量;

每个像素发射1个shadow ray,用来计算直接光照的阴影;

如果只用1个bounce来计算全局光照的话,每个像素发射1个indirect ray+1个shadow ray,用来计算间接光照。

3、denoise pass

基于BMFR算法来实现降噪,具体可参考本文后面的“实现降噪Denoise”部分。

4、taa pass

使用taa来抗锯齿

相关代码可见我的开源项目:

WebGPU-RTX

介绍我学习的整个流程,分享相关资料

了解光线追踪的相关领域

我通过下面的文章进行了初步的了解:

一篇光线追踪的入门

光线追踪与实时渲染的未来

实时光线追踪技术:业界发展近况与未来挑战

Introduction to NVIDIA RTX and DirectX Ray Tracing

如何评价微软的 DXR(DirectX Raytracing)?

实现第一个光追的Demo

通过学习下面的资料:

Ray Tracing in One Weekend

Ray Tracing: The Next Week

Ray Tracing in One Weekend和Ray Tracing: The Next Week的详解

基于OpenGL的GPU光线追踪

我参考资料中的代码,用WebGL 2实现一个Demo:

该场景的红圈中是一个球,附近有一个球形光源和一个矩形光源

因为没有进行降噪,所以噪点太多了哈哈!

相关代码可见我的开源项目:

Wonder-RayTrace

学习和实现Ray Tracing管线

通过学习NVIDIA Vulkan Ray Tracing Tutorial教程,我用 js语言+WebGPU Node开源项目 基于Ray Tracing管线依次实现了阴影、反射等基础渲染效果。

该教程使用了VK_KHR_ray_tracing扩展,而WebGPU Node开源项目也使用了该扩展(Vulkan SDK),因此该教程的shader代码几乎可以直接用到该开源项目中。

教程代码

用Reason重写

我用Reason语言重写了示例代码,提炼了一个基础架构。

学习GBuffer+Ray Tracing混合管线

因为我希望优先减少渲染时间,所以我要通过混合管线来进行实时渲染。

我通过A Gentle Introduction To DirectX Raytracing教程来学习和实现。

教程代码下载

我学习了该教程的第一篇到第11篇,分别实现了创建GBuffer、使用Lambertian材质渲染、多光源的阴影等内容。

实现降噪Denoise

教程的第9篇通过每个像素对每个光源发射一个shadow ray,最后累加并计算平均值,实现了多光源的阴影。

教程的第11篇对第9篇进行了改进:为了减少每个像素发射的shadow ray的数量,每个像素只随机向一个光源发射一个shadow ray。

这样会导致噪点,如下图所示:

我们可以通过累计采样数来不断逼近无噪点的图片(如该教程的第6篇一样),但这样需要经过长时间后才会收敛,所以只适合“云渲染”这种离线渲染的应用场景。

累加一定帧数后,结果如下图所示:

实现taa

降噪算法通常需要先实现“帧间的数据复用”,而TAA抗锯齿也需要实现“帧间数据复用”的技术;而且降噪算法会使用TAA作为最后一个pass来抗锯齿。所以我决定先实现taa,将其作为实现降噪算法的铺垫。

我参考了下面的资料来实现taa:

DX12渲染管线(2) - 时间性抗锯齿(TAA)相关代码

Unity Temporal AA的改进与提高相关代码

unit Temporal Anti-Aliasing

实现BMFR降噪算法

为了能应用于“云游戏”这种实时渲染的应用场景,我们需要快速降噪。因此我实现了BMFR算法来降噪。

降噪前场景:

降噪后场景:

我参考了下面的资料:

BLOCKWISE MULTI-ORDER FEATURE REGRESSION FOR REAL-TIME PATH TRACING RECONSTRUCTION

参考代码

学习蒙特卡罗积分(monte carlo)的理论

教程的第11篇随机向一个光源发射一个shadow ray,这其实已经使用了蒙特卡罗积分的理论。

我们可以通过下面的资料深入学习该理论,了解概率密度函数(pdf)、重要性采样等相关概念,为我们后面实现全局光照打下理论基础:

【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-1 蒙特卡罗 (一)【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-7 混合概率密

光线追踪器Ray Tracer:进阶篇

实现全局光照

通过学习教程的第12篇,我实现了one bounce的全局光照。

更多参考资料:

Global Illumination and Path Tracing

Global Illumination and Monte Carlo

这里我遇到的问题主要是处理indirect specular noise:噪点不稳定,导致降噪后不稳定(高光周围有明显波动)。

我首先以为是pdf写错了,结果修改了pdf后还是没有改进;

然后希望通过clamp等方法移除这些高光的fireflies噪点,结果影响到了画质;

最后采用了“采样indirect specular/diffuse多次”来稳定噪点。这适用于“云渲染”的离线渲染,但不适用于“云游戏”的实时渲染。

基于GGX模型,实现disney BRDF

通过学习教程的第14篇,我引入了pbr材质,实现了GGX模型,加入了多bounce的全局光照。

我对教程代码进行了改进:

在.rgen着色器中使用for循环而不是递归来实现的多bounce;

实现了disney BRDF,在pbr材质中有diffuse、roughness、metallic、specular这几个参数。

更多参考资料:

基于物理着色(二)- Microfacet材质和多层材质

基于物理着色(三)- Disney和UE4的实现

基于物理的渲染(PBR)白皮书 | 迪士尼原则的BRDF与BSDF相关总结

WebGPU-Path-Tracer 实现了disney BRDF

目前的渲染效果

我目前的实现需要改进的地方

在Ray Tracing pass中支持纹理

使用bindless texture或者virtual texture来实现

扩展disney BRDF,实现BSDF,支持透明、折射效果

增加后处理

如gamma矫正等

在云端环境下多线程渲染

云端天然具有并行的优势,因此可将渲染任务分配到多个显卡/服务器中执行。

改进降噪效果

BMFR对高光specular处理得不好。

为了应用在“云渲染”中,需要提高画质。因此可考虑:

  • 改进BMFR对specular的处理

    BMFR论文中已有相关的讨论
  • 使用专门对多个spp采样进行降噪的降噪器来替代BMFR

    因为BMFR主要是针对1 spp采样,所以需要使用针对蒙托卡罗积分路径追踪的降噪器来替代

改进indirect specular/diffuse noise

现在我通过增加spp来增加噪点的稳定性,这在“云游戏”中行不通,因为只能有1 spp。因此可考虑:

最新文章

  1. 利用免费cdn加速webpack单页应用
  2. Android NDK开发Hello Word!
  3. Redis学习笔记(4) Redis事务、生存时间及排序
  4. .net中使用ODP.net访问Oracle数据库(无客户端部署方法)
  5. 一文读懂UGC:互联网上的生态秘密
  6. 网页js,DIV全屏布局
  7. Java for LeetCode 220 Contains Duplicate III
  8. IE下Checkbox标签的onchange事件兼容
  9. 修改首页的main里面的内容
  10. bzoj 1189
  11. android启动activity文本框不获得焦点
  12. Java虚拟机的锁优化
  13. LAV Filter 源代码分析 3: LAV Video (1)
  14. Java 环境下载设置
  15. Carthage入门篇-安装和使用
  16. java里getter和setter的作用(转载)
  17. PhpStorm和WAMP配置调试参数,问题描述Error. Interpreter is not specified or invalid. Press “Fix” to edit your project configuration.
  18. vue的条件渲染和列表渲染介绍
  19. eclipse jee使用
  20. 094实战 关于js SDK的程序,java SDK的程序

热门文章

  1. AUTOSAR-标准文档索引
  2. Shell 脚本(五) Shell 工具 及 企业面试题
  3. Java实现 LeetCode 443 压缩字符串
  4. Java实现 LeetCode 208 实现 Trie (前缀树)
  5. Java实现 LeetCode 123 买卖股票的最佳时机 III(三)
  6. Java实现 LeetCode 50 Pow(x,n)
  7. java实现 洛谷 P1018 乘积最大
  8. Java实现第八届蓝桥杯迷宫
  9. java代码(6) ---guava之multimap
  10. iOS -App主流框架UINavigationController && UITabBarController的简单使用