我正在实现粒子着色器,它意味着绘制许多矩形,每个矩形都有唯一的数据。现在,我看到了执行此操作的不同方法。
方式1:
struct Particle
{
//...
};
layout(binding = 0) uniform ParticleUniformBufferObject
{
Particle particles[MAX_PARTICLES_TO_DRAW];
} ubo;
vec3 particlePosition = ubo.particles[gl_InstanceID].position;
方式2:
方式3:
通过顶点输入来执行所有操作,并且没有任何按对象的制服。可能会有很多不必要的数据开销。在这种情况下,应在每帧更新顶点缓冲区。
我的问题-哪种方式在效果上更好?
或者您是否看到使用Vulkan API进行粒子渲染的另一种好方法?
另一种方法是使用间接绘图:vkCmdDrawIndirect
。如果您只能在GPU上修改粒子,则这种方法可能会有所回报。如果您需要动画/修改/等。将它们放在CPU上,那么间接绘图将无济于事。
就您的粒子数据而言,您将它们存储在vkCmdDrawIndirect
缓冲区中,在计算着色器遍历中对其进行修改,并使用间接绘制调用对其进行渲染。要访问粒子的数据,必须使用VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
的内置GLSL
。
通常,在性能方面,无法分辨出哪种方法比另一种方法更好。这取决于许多因素:取决于如何修改粒子,粒子所依赖的粒子,粒子的数量,使用的GPU等。如果您真的想知道,则必须实施所有方法并进行测量。
如果要进行后者,请分享您的结果并描述您的设置!这样的东西总是很有趣。