欢迎光临散文网 会员登陆 & 注册

04. The-Forge 入门教程 - Raytracing

2020-11-15 17:41 作者:AICDG  | 我要投稿

要说nVidia 20系显卡最大的特征,那自然是加了硬件光线追踪。NVIDIA 20系显卡其实加入了非常多的新特性,但是在媒体宣传上,一直以光追和DLSS为主,可能也是因为其他特性AI两家加入并不难吧。如果看nVidia的白皮书,其实能发现,图灵是进步极大的一代,安培在架构上反而是继续吃老本,进步不大。

如果是入门DXR,最好的参考就行微软的官方demo

https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12Raytracing/readme.md

本节,就尝试将微软DXR官方demo的D3D12RaytracingHelloWorld,移植到The-Forge中。光追的代码非常冗长,我可能就跳过代码的讲解,在文末会给我自己的代码repo。

硬件实时光追简介

对于光栅算法,就是把场景转换到视锥在投影到相机的过程。光线追踪则可以算作是该算法的逆算法,就是从相机出发,反向将射线从每个像素射向场景,并看最终能找到什么物体。在不透明物体上,可以直接用BRDF,通过光源的信息计算该点颜色。如果碰到镜面,就沿发现对称再射出一条光线。如果射到透明物体,折射角度发射光线。如果没有击中任何物体,假设击中的天空。

简化后的状态机如上图所示。

该状态机中,硬件负责帮忙实现光线求交的相关部分,而用户要自己负责RaygenMissHit的部分。

在Raygen shader中,自己可以定义一个数据结构RayPayload。在Raygen shader中,每个像素射出一条光线,每个光线传入一个RayPayload。之后硬件负责与整个场景求交。在最后,如果找到了交点,就会执行closesthit shader,在closesthit shader修改RayPayload的值;反之,就会执行miss shader,在miss shader中修改RayPayload的值。

TraceRay的实际结构如上图

光线求交如果光源直接遍历所有物体所有三角形,运算量将是天文数字。因为需要一些特殊的加速结构,现代主流加速结构是BVH


D3D12RaytracingHelloWorld功能解析

场景中存在一个三角形,三角形的三个点坐标分别为(0, 0.75,0)(-0.75,-0.75,0)(0.75,-0.75,0)

在场景中,每个像素的位置,沿着(0,0,1)发射一条射线。因此,在(0, 0.75,0)(-0.75,-0.75,0)(0.75,-0.75,0)范围内的射线会击中三角形,执行chit shader,进行颜色插值。三角外部的点执行miss shader,直接返回颜色float4(0.1f, 0.1f, 0.1f, 1.0f)

shader代码

miss shader

首先是最简单的miss shader,直接返回一个固定颜色

closesthit shader

closesthit shader的参数,除了RayPayload之外,还有一个IntersectionAttributes

IntersectionAttributes有一个float2类型的参数,

通过(1 - IntersectionAttributes.baryCrd.x - IntersectionAttributes.baryCrd.y, IntersectionAttributes.baryCrd.x, IntersectionAttributes.baryCrd.y)可以得到光线击中的点,在被击中的三角形的重心坐标,依靠重心坐标和其他三个顶点数据,就可以进行插值了。在光栅中该步骤是硬件完成的,如果写过软光栅或者软光线追踪的同学应该对重心坐标不会陌生,而光线追踪中插值就要自己来了。

如果重心坐标为(bx,by,bz)(bx + by + bz = 1)

那么该点的数据为V = bx * V0 + by * V1 + bz * V2

position,uv,color等数据都要通过重心插值得到

在本shader中,直接将重心坐标作为颜色返回。重心坐标颜色直接显示也是光线追踪渲染调试的重要依据。

raygeneration shader

在Raygen shader中,运行TraceRay函数,执行结果会写回payload中,然后再作为结果写到Tex0(UAV)中即可。

c++

在03-compute的基础上继续开发,c++部分的主要工作,就是生成AccelerationStructure和RaytracingShaderTable

完整代码不再解释,就提几嘴我个人觉得需要很注意的点。

在pRenderer初始化时,需要把target设置到sm6.3.

shader model 6.3是dxr1.0要求的版本,dxr1.1则需要shader model 6.5

AccelerationStructure也要加到descriptorSet中

全部的源码可以参考我的repo https://github.com/THISISAGOODNAME/leanring-The-Forge

接下来该干什么

在这个教程之后,如果还对硬件光线追踪本身感兴趣,推荐尝试将raytracing in one weekend中实现的demo移植到The-Forge中。

这一系列教程可能到此就要暂停了。接下来的部分要等我抢到RTX3080或者RX6800XT以后了。可以提前预告一下,我后面想写一些关于dx12u,sm6.5相关的内容。

最后再一次给The-Forge 交流群打个广告,950656923,欢迎对 The-Forge/bgfx/panda3D/horde 之类图形中间件感兴趣,或者对现代renderer pipeline感兴趣,对mesh shader/real time raytracing/VRS/VRR等新特性感兴趣的朋友加入

参考

https://github.com/microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing/src/D3D12RaytracingHelloWorld

https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html

https://developer.nvidia.com/rtx/raytracing/dxr/DX12-Raytracing-tutorial-Part-2

https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/technologies/turing-architecture/NVIDIA-Turing-Architecture-Whitepaper.pdf

https://www.nvidia.com/content/dam/en-zz/Solutions/geforce/ampere/pdf/NVIDIA-ampere-GA102-GPU-Architecture-Whitepaper-V1.pdf

04. The-Forge 入门教程 - Raytracing的评论 (共 条)

分享到微博请遵守国家法律