Gointerface接口声明实现及作用详解
956
2022-06-07
大家好,本文整理了现代图形API的技术要点,重点研究了并行和GPU Driven Render Pipeline相关的知识点,调查了WebGPU的相关支持情况。
另外,本文对实时光线追踪也进行了简要的分析。这是我非常感兴趣的技术方向,也是图形学的发展方向之一。本系列后续文章会围绕这个方向进行更多的研究和实现相关的Demo。
上一篇博文:
WebGPU学习(四):Alpha To Coverage
现代图形API包括哪些API?
包括DX12、Vulkan、Metal
MVP是什么?
是WebGPU的最小可用版本。
在1.0版本发布前,先发布MVP版本。
下面依次进行分析:
为了提高多核CPU和GPU的利用率,现代图形API充分支持了并行。
并行包含下面的技术要点:
为了提高GPU利用率,可以将不同种类的任务对应的command buffer提交到3种队列中:
graphics queue
copy queue
compute queue
不同队列的任务能够在GPU中并行执行,从而实现Async Compute,提高利用率。
参考资料
Multi-engine synchronization
根据Multiple Queues skeleton proposal,MVP只支持单队列:
what single queue is exposed in the MVP
有3个技术可以实现CPU与GPU之间以及GPU内部的同步:
我不了解它,它应该是用来同步队列的
它用来避免GPU因为资源依赖关系造成等待,以及避免CPU和GPU之间发生Race Condition。
现代图形API更加底层,以前GPU做的同步工作也交给了图形程序员,更加灵活的同时也加重了程序员的负担。
参考资料
Breaking Down Barriers
它用来在CPU和GPU之间同步。
因为目前只支持单队列,所以不需要它
大家都表示memory barrier不容易实现,所以barriers由WebGPU帮我们做了(参考Memory barriers investigations、Memory Barriers portability、The case for passes -> Synchronization and validation),我们只需要给WebGPU一些提示(如指定buffer的usage)
支持以计数的方式实现fence。
参考资料
TimelineFences
可以在线程中执行现代图形API相关的渲染任务:
在线程中更新资源
如更新buffer
并行地编译shader
并行地创建pipeline state
在线程中创建command buffer
有两种方法实现多线程:
根据Rendering to OffscreenCanvas on non-yielding workers:
WebGPU支持OffScreenCanvas API,但是目前Chrome不能使用它。
Create a proposal for multi-worker中提出了WebGPU如何在worker中执行渲染任务:
1.Asynchronous texture & buffer uploads
2.Asynchronous shader compilation
3.Asynchronous pipeline state creation
4.Using MTLParallelRenderEncoder
5.Each thread in a thread pool records into its own command buffer
根据Minutes for GPU Web meeting 2019-08-05 -> Multi threading:
其中的1,2,3正在实现中;
4, 5会最终实现(没有说好久实现);
根据我目前的调查:
1.shader编译和创建pipeline state目前是同步的,还不是异步的。
2.在WebGPU 规范中,GPUTexture,GPUBuffer,GPUDevice,GPUComputePipeline,GPURenderPipeline,GPUShaderModule是Serializable的,意味着可以传给worker。
那是不是现在已经可以在worker中使用它们,从而实现1,2,3呢?需要进一步验证!
引擎对于多线程的封装:
Parallelizing the Naughty Dog Engine using Fibers
Destiny’s Multi-threaded Renderer Architecture
与memory barriers类似,现代图形API需要程序员自己管理GPU的资源。
参考资料
Memory Management in Vulkan™ and DX12
根据WebGPU as low level graphics API:
WebGPU compares closest to Metal (probably since Apple is the one that originally proposed it)--both don't require manual memory management while DX12 and Vulkan do
不需要手动管理memory,WebGPU会帮我们管理
包括两个步骤:
第一个pass遍历gameObjects,创建gbuffer;
第二个pass遍历lights,使用gbuffer计算光照。
相对于前向渲染,它的优点是只在屏幕上出现的像素中计算SHADING,从而使复杂度由O(M * N)将为O(M) + O(N)
因为支持MRT(多渲染目标),所以支持延迟渲染。
值得一提的是两个优化的方向:
在Investigation: Managing on-chip memory中提到:
第一个pass创建gbuffer后,gbuffer的数据会从on-chip内存移到主内存中;
第二个pass读取gbuffer时,将gbuffer的数据从主内存移到on-chip内存。
gbuffer的数据来回移动,造成了性能损失。
因此在Add render sub-passes中,建议增加render的子pass,在子pass中读取gbuffer,从而实现在创建和读取gbuffer期间,gbuffer的数据一直在on-chip内存中。
Minutes for GPU Web meeting 2019-10-28也讨论了这一点。
WebGPU可能会在extension中支持这个优化。
正如DirectX 11 Rendering in Battlefield 3所说:
Hybrid Graphics/Compute shading pipeline:
› Graphics pipeline rasterizes gbuffers for opaque surfaces
› Compute pipeline uses gbuffers, culls lights, computes lighting &
combines with shading
› Graphics pipeline renders transparent surfaces on top
延迟着色法
Optimizing tile-based light culling
DirectX 11 Rendering in Battlefield 3
在defer shading的第一个pass中,我们将gameObject的几何数据(如Position, Normal等)和材质贴图数据(如从diffuse map中获得的diffuse)存到gbuffer中。
有了bindless texture的支持,我们可以对此进行优化:
这样做的优点是:
1.减少了gbuffer的大小
2.只在可见的像素中,采样texture的数据,减少了采样次数
这样做也存在一些问题,不过都是可以解决的:
具体可以参考什么是deferred material shading?是否会在未来流行开来?:
1.多材质如何做deferred shading?总不能每个像素做动态分支,一个一个判断吧。有人提出了做tile把像素区块合并,然后一次性dispatch,性能会高很多。至于vgpr,sgpr,lds占用率之类需要通盘考虑,偏向一边都会影响性能。
2.结果SSAO,SSR之类的post effect还是需要用到normal,roughness之类的g-bufffer信息。应用上还是需要权衡利弊。
以及参考Deferred Texturing:
What about mip levels, or derivatives?
具体可以参考Deferred Texturing -> Defer All The Things:
It stores only primitive IDs in its G-buffer; then in a later pass, it fetches vertex data, re-runs the vertex shader per pixel (!), finds the barycentric coordinates of each fragment within its triangle, interpolates the vertex attributes, then finally samples all the textures and does the shading work.
根据本文后面bindless texture的分析,目前WebGPU不支持bindless texture
或许可用texture 2d array代替bindless texture,从而使用WebGPU实现textureless defer render
Deferred Texturing
什么是deferred material shading?是否会在未来流行开来?
BINDLESS TEXTURING FOR DEFERRED RENDERING AND DECALS
Modern textureless deferred rendering techniques
这个技术应该是在[Siggraph15] GPU-Driven Rendering Pipelines中提出来的。它的思想是把渲染任务从CPU端移到GPU端,减少CPU与GPU的同步和数据传输,实现1个draw call就渲染整个场景,从而提高GPU的利用率。
GPU更细粒度的Visibility
不需要在CPU和GPU之间来回传递数据
绘制大量的静态物体
绘制人群
绘制模块化半自动生成内容
离线处理
1.分解gameObject的mesh为多个cluster
参考GPU Driven Pipeline — 工具链与进阶渲染
CPU
1.对gameObject进行粗粒度的frustum cull
2.使用persistent map buffer,准备GPU的数据
可以按照数据的类型,创建多个mapped buffer(如一个buffer存储人群的数据,另一个buffer存储所有静态物体的数据)
3.使用virtual texture处理texture
所有的texture数据一次性全部准备好,只绑定一次texture
4.用indirect draw发起multi draw call,提交mapped buffer
WebGPU目前不支持multi draw,因此需要发起多个draw call,每个draw call使用indirect draw提交对应的mapped buffer
GPU
1.对gameObject进行frustum cull和occlusion cull
2.对gameObject的cluster进行frustum cull和occlusion cull
3.修改index buffer,生成新的indices数据
根据Proposal: Run all index buffers through a compute shader validator:
I'm inclined to propose that WebGPU MVP doesn't support index buffers changed on the GPU, since this is quite a bit of headache, but eventually we can do that.
...
In an actual 1.0 release we'll absolutely need to support GPU-generated indices, there is no question here.
WebGPU MVP不会支持在GPU端修改index buffer,1.0版本会支持。
4.multi draw call
根据ExecuteIndirect investigation:
In order to issue draw calls on the CPU, there must be a synchronization point where the CPU waits for the GPU update to complete. This is particularly devastating for WebGPU, where if the CPU has to wait for the GPU, you miss your implicit present and now you're a frame late. Being able to issue these commands on the GPU directly means the rendering and update steps can be in sync.
在GPU端发起draw call可以去掉“CPU和GPU同步”的开销。
However, making it an extension seems valuable.
可能会在WebGPU extension中支持该特性。
GPU Driven Render Pipeline可以一次性取得所有mesh data,通过virtual texture可以取得所有texture,意味着整个场景只需要一次drawcall
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~