Какой подход лучше всего реализовать для шейдера частиц с помощью Vulkan API? - PullRequest
0 голосов
/ 03 мая 2020

Я реализую шейдер частиц, и это подразумевает рисование множества прямоугольников с уникальными данными для каждого. Теперь я вижу разные способы сделать это.


Способ 1:

  1. использовать один единый буфер для всех частиц
  2. сделать один vkCmdBindDescriptorSets в начале рисования
  3. вызвать один vkCmdDraw с количеством экземпляров, равным количеству частиц
  4. , в вершинном шейдере используется единообразная структура, состоящая только из одного массива:
struct Particle
{
    //...
};

layout(binding = 0) uniform ParticleUniformBufferObject
{
    Particle particles[MAX_PARTICLES_TO_DRAW];
} ubo;
Затем при рисовании используйте переменные glsl для доступа к унифицированным данным
vec3 particlePosition = ubo.particles[gl_InstanceID].position;

Способ 2:

  1. используйте одну униформу буфер для всех частиц
  2. do vkCmdBindDescriptorSets для каждой частицы с использованием Dynami c offset
  3. do vkCmdDraw для каждой частицы с числом экземпляров 1
  4. доступ к данным буфера в вершинном шейдере в обычный способ без массивов

Способ 3:

Делать все через ввод вершин и без униформ для каждого объекта. Вероятно, будет много ненужных данных. В этом случае буфер вершин должен обновляться каждый кадр.


Мой вопрос - какой путь лучше с точки зрения производительности?

Или вы видите другой хороший подход для рендеринга частиц с помощью Vulkan API?

1 Ответ

0 голосов
/ 04 мая 2020

Другой подход заключается в использовании косвенного рисования: vkCmdDrawIndirect. Такой подход может окупиться, если вы сможете модифицировать свои частицы только на графическом процессоре. Если вам нужно анимировать / изменить / et c. их на процессоре, тогда стороннее рисование не поможет.

Что касается ваших данных частиц, вы должны сохранить их в буфере VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, изменить их в проходе вычислительного шейдера и отобразить их с помощью косвенного вызова отрисовки. Чтобы получить доступ к данным частицы, вам нужно будет использовать встроенную GLSL gl_DrawID.


В общем, нельзя сказать, какой способ лучше, чем другой, с точки зрения производительности. , Это зависит от многих факторов: от того, как вы собираетесь модифицировать частицы, от чего они зависят, от количества частиц, используемого графического процессора и т. Д. c. Если вы действительно хотите знать, вам нужно реализовать все подходы и измерить.

Если вы собираетесь сделать последнее, пожалуйста, поделитесь своими результатами и опишите ваши настройки! Такие вещи всегда интересны.

...