大家好~这三个月以来,我一直在学习和实现“基于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翻墙):

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

  19. 这里要注意的是,需要先安装Vulkan SDKpython
  20. 可以通过“npm config set python C:\depot_tools\python.bat”来设置python路径,或者指定python路径:
  21. 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"
  22. # 在nodejs中运行ray tracing示例,验证是否成功
  23. 进入webgpu node的根目录
  24. cd examples & cd ..
  25. 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。因此可考虑:

WebGPU+光线追踪Ray Tracing 开发三个月总结的更多相关文章

  1. 《Ray Tracing in One Weekend》、《Ray Tracing from the Ground Up》读后感以及光线追踪学习推荐

    <Ray Tracing in One Weekend> 优点: 相对简单易懂 渲染效果相当好 代码简短,只看书上的代码就可以写出完整的程序,而且Github上的代码是将基类与之类写在一起 ...

  2. 【Ray Tracing The Next Week 超详解】 光线追踪2-7 任意长方体 && 场景案例

    上一篇比较简单,很久才发是因为做了一些好玩的场景,后来发现这一章是专门写场景例子的,所以就安排到了这一篇 Preface 这一篇要介绍的内容有: 1. 自己做的光照例子 2. Cornell box画 ...

  3. 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-7 混合概率密度

     Preface 注:鉴于很多网站随意爬取数据,可能导致内容残缺以及引用失效等问题,影响阅读,请认准原创网址: https://www.cnblogs.com/lv-anchoret/category ...

  4. 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-5 random direction & ONB

     Preface 往后看了几章,对这本书有了新的理解 上一篇,我们第一次尝试把MC积分运用到了Lambertian材质中,当然,第一次尝试是失败的,作者发现它的渲染效果和现实有些出入,所以结尾处声明要 ...

  5. 【Ray Tracing The Next Week 超详解】 光线追踪2-9

    我们来整理一下项目的代码 目录 ----include --hit --texture --material ----RTdef.hpp ----ray.hpp ----camera.hpp ---- ...

  6. 【Ray Tracing The Next Week 超详解】 光线追踪2-8 Volume

     Preface 今天有两个东东,一个是体积烟雾,一个是封面图 下一篇我们总结项目代码 Chapter 8:Volumes 我们需要为我们的光线追踪器添加新的物体——烟.雾,也称为participat ...

  7. 【Ray Tracing The Next Week 超详解】 光线追踪2-5

    Chapter 5:Image Texture Mapping 先看效果: 我们之前的纹理是利用的是撞击点p处的位置信息,比如大理石纹理 而我们今天的图片映射纹理采用2D(u,v)纹理坐标来进行. 在 ...

  8. 【Ray Tracing in One Weekend 超详解】 光线追踪1-4

    我们上一篇写了Chapter5 的第一个部分表面法线,那么我们来学剩下的部分,以及Chapter6. Chapter5:Surface normals and multiple objects. 我们 ...

  9. 【Ray Tracing The Next Week 超详解】 光线追踪2-4 Perlin noise

     Preface 为了得到更好的纹理,很多人采用各种形式的柏林噪声(该命名来自于发明人 Ken Perlin) 柏林噪声是一种比较模糊的白噪声的东西:(引用书中一张图) 柏林噪声是用来生成一些看似杂乱 ...

随机推荐

  1. cocos2dx 入门 环境配置

    本人立志走游戏开发这条路,很早之前就准备学习cocos2dx,今天终于忙里偷闲入了一下门,把环境配置好了,创建了自己的第一个cocos项目! 一.环境配置 1.下载cocos https://coco ...

  2. 自制基于python的DoU log分析脚本

    工作中测试DoU的log需要分析,原先是使用excel,去ctrl c,ctrl v截取数据,整理格式等等.一来,这工作虽然很简单,但是非常耗时,不熟练的人(比如我)一搞搞个半天:二来,不小心还会出现 ...

  3. Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数

    问题描述 不超过19000的正整数中,与19000互质的数的个数是多少? 答案提交 这是一道结果填空的题,你只需要算出结果后提交即可.本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将 ...

  4. Java实现 蓝桥杯VIP 算法训练 蜜蜂飞舞

    时间限制:1.0s 内存限制:512.0MB 问题描述 "两只小蜜蜂呀,飞在花丛中呀--" 话说这天天上飞舞着两只蜜蜂,它们在跳一种奇怪的舞蹈.用一个空间直角坐标系来描述这个世界, ...

  5. Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴

    算法提高 贪吃的大嘴 时间限制:1.0s 内存限制:256.0MB 问题描述 有一只特别贪吃的大嘴,她很喜欢吃一种小蛋糕,而每一个小蛋糕有一个美味度,而大嘴是很傲娇的,一定要吃美味度和刚好为m的小蛋糕 ...

  6. java实现滑动解锁

    滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上都一致 ...

  7. 05.Django-form表单与请求的生命周期

    Django中请求的生命周期 HTTP请求及服务端响应中传输的所有数据都是字符串 步骤 用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务器 url经过wsgi和中间件,到达路由映射表,在 ...

  8. RabbitMQ(2)---高级使用

    1.ack和限流 ack也就是消息确认签收,分为自动签收和手动签收.之前的交换机demo中:channel.basicConsume(queueName,true, consumer);  第二个参数 ...

  9. 分布式锁没那么难,手把手教你实现 Redis 分布锁!|保姆级教程

    书接上文 上篇文章「MySQL 可重复读,差点就让我背上了一个 P0 事故!」发布之后,收到很多小伙伴们的留言,从中又学习到很多,总结一下. 上篇文章可能举得例子有点不恰当,导致有些小伙伴没看懂为什么 ...

  10. MySQL 8.0 yum安装和配置

    MySQL 8.0 centos7.5 x86_64 一.yum安装 1.先卸载机器和mysql有关的东西,有的安装了mariab-lib,会对安装有干扰,卸载了它. [root@localhost ...