Unity Compute Shader介绍和用法

        compute shader是在GPU上运行的着色器程序,可用于大规模并行 GPGPU(General Purpose GPU)算法,或加速部分游戏渲染。

        shaderlab和Compute Shader都使用HLSL语言编写,但功能大不相同,这是一些比较:

        1. compute shader没有Material Property,意味着无法通过Material调整属性,只能依靠shader的设置值方法,但是用法相同,可以用来设置各种shader变量和贴图。

        2. compute shader没有subpass和pass,也没有renderqueue,这是因为它独立固定在GPU渲染流程开始时进行,不直接创建drawcall,而是其输出在后面的渲染阶段使用。

        3. compute shader没有顶点着色器和片元着色器,这是因为它是通过Kernel Function直接被C#调用,本质上可以当做C# script的一部分,只是这一部分计算放在GPU上计算。

        用法如下:

Compute Shader Instancing

        compute shader跟GPU instancing结合起来可以实现很强大的功能。这个技术在大世界生成非常重要。

        相关方法(定义有精简):

        可变mesh个数:DrawMeshInstancedIndirect,argsOffset指定了存储mesh个数的位置。

DrawMeshInstancedIndirect(
    Mesh mesh, 
    int submeshIndex, 
    Material material, 
    Bounds bounds, 
    ComputeBuffer bufferWithArgs, 
    int argsOffset = 0
)

        固定mesh个数:DrawMeshInstancedProcedural

DrawMeshInstancedProcedural(
    Mesh mesh, 
    int submeshIndex, 
    Material material, 
    Bounds bounds, 
    int count
);

        无mesh,可变次数:DrawProceduralIndirect

DrawProceduralIndirect(Material material, 
    Bounds bounds, 
    MeshTopology topology, 
    GraphicsBuffer bufferWithArgs, 
    int argsOffset
)

          无mesh,固定次数:DrawProcedural

DrawProcedural(
    Material material, 
    Bounds bounds, 
    MeshTopology topology, 
    int vertexCount, 
    int instanceCount
)

        前两个方法接口是CPU传入mesh,后两个是由GPU生成mesh。 

        用上面的方法,可以实现非常高效的Instancing,因为此时CPU向GPU传递的数据大大减少了,不再需要每帧为每个物体传递位置信息,甚至不用传递mesh(DrawProcedural的情况)。

        优点:减少了CPU到GPU的数据传输,不需要做每个物体的裁剪和深度排序。

        缺点:由于没有深度排序,导致overdraw。但由于性能提升很大这个缺点一般可以忽略,并且也有解决办法:

视锥剔除为什么要做视锥剔除在很多的开放性世界的游戏中,场景中往往会有大量的植被与建筑,然而由于视角有限,在屏幕上并不会显示出所有地图上的物体,只能显示出视锥体内的物体。如下图,场景中有很多的小树,但是最终显…https://zhuanlan.zhihu.com/p/376801370

【Unity】使用Compute Shader实现Hi-z遮挡剔除(Occlusion Culling) - 知乎前言在之前的文章里,分别介绍了一下Compute Shader的 基本概念,以及使用Compute Shader实现简单的视锥剔除:Unity中ComputeShader的基础介绍与使用Unity中使用ComputeShader做视锥剔除(View Frustum Culling)…https://zhuanlan.zhihu.com/p/396979267

贴图渲染

        可以用于各种程序化贴图的生成,比如各种Noise的生成,适用于需要动态变化的贴图,比如水面颜色或者法线。或者单纯是为了提高编辑器中实时显示的性能。例如:

基于ComputeShader生成Perlin Noise噪声图 - 知乎在游戏开发中我们通常希望通过引入随机数的方式增加游戏中的随机性,在这之上,我们通常有两种选择,使用离散的伪随机数或是使用连续的随机噪声(例如 Perlin Noise)。在实时渲染中,我们通常会使用噪声纹理来实…https://zhuanlan.zhihu.com/p/88518193

粒子

        在这篇文章中,还提到了粒子的使用:

【Unity】Compute Shader的基础介绍与使用 - 知乎Compute Shader概念当代GPU被设计成可以执行大规模的并行操作,这有益于图形应用,因为在渲染管线中,不论是顶点着色器还是像素着色器,它们都可以独立进行。然而对于一些非图形应用也可以受益于GPU并行架构所提供…https://zhuanlan.zhihu.com/p/368307575

        实际上是用DrawProcedural Point实现的模拟粒子,不是Particle System。虽然不如Particle System,但是性能好很多,适合超大规模的粒子特效渲染。

UAV

        UAV定义是Unordered Access View,介绍参考这里

        简单来说就是支持随机写入,这和传统渲染流程不一样。传统流程渲染贴图时必须按照固定的顺序,比如后处理时输入一张Quad,传统渲染每次绘制时一定是逐个像素点执行一次,执行完就输出。但有的时候我们不想这样,而是每次写入数据的位置是可变的,并且可能在一次绘制当中,覆盖之前写好的像素。正常来说这种处理只能在CPU侧,用一张输出贴图来支持这种写入。但是UAV解决了这个问题,可以在GPU侧实现这个功能。

        实现这一点就需要使用Compute Shader,最常见的应用是SSPR,应用可以参考:

Unity URP 移动平台的屏幕空间平面反射(SSPR)趟坑记 - 知乎为什么给自己挖这个坑?屏幕空间反射在知乎早被玩图形的大佬们嚼成了渣,问题是,移动平台跑不起来。。。噪声RayMatching体积光最简单了吧,但凡一个可接受的画面结果,手机10秒内就开始烫,屏幕空间反射的多次相…https://zhuanlan.zhihu.com/p/150890059

         

猜你喜欢

转载自blog.csdn.net/paserity/article/details/129982931