2016-04-21 9 views
3

Я нахожусь в середине рендеринга различных текстур на нескольких сетках модели, но у меня нет много подсказок о процедурах. Кто-то предложил для каждой сетки, создавать свои собственные наборы дескрипторов и вызвать vkCmdBindDescriptorSets() и vkCmdDrawIndexed() для рендеринга, как это:Выравнивание текстур Vulkan на нескольких сетках

// Pipeline with descriptor set layout that matches the shared descriptor sets 
vkCmdBindPipeline(...pipelines.mesh...); 
... 
// Mesh A 
vkCmdBindDescriptorSets(...&meshA.descriptorSet...); 
vkCmdDrawIndexed(...); 
// Mesh B 
vkCmdBindDescriptorSets(...&meshB.descriptorSet...); 
vkCmdDrawIndexed(...); 

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

Приветствия

+0

И какой метод используют эти образцы? –

ответ

3

Человек, который предложил выше фрагмент кода был мне я думаю;)

Это только один из способов сделать это. Вам необязательно создавать один набор дескрипторов для каждой сетки или для каждой текстуры. Если ваша сетка, например, использует 4 разных текстуры, вы можете сразу связать их всех с разными точками привязки и выбрать их в шейдере.

И если вы посмотрите на образец вертолета NVIDIA, они делают это почти так же, как и с более абстракцией.

В примере также устанавливает наборы дескрипторов для используемых текстур:

VkDescriptorSet *textureDescriptors = m_renderer->getTextureDescriptorSets(); 

связывает их через несколько строк:

VkDescriptorSet sets[3] = { sceneDescriptor, textureDescriptors[0], m_transform_descriptor_set }; 
vkCmdBindDescriptorSets(m_draw_command[inCommandIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 3, sets, 0, NULL); 

, а затем делает сетку со связанными наборами дескрипторов:

vkCmdDrawIndexedIndirect(m_draw_command[inCommandIndex], sceneIndirectBuffer, 0, inCount, sizeof(VkDrawIndexedIndirectCommand)); 
vkCmdDraw(m_draw_command[inCommandIndex], 1, 1, 0, 0); 

Если вы посмотрите на initDescriptorSets вы можете видеть, что они также создают отдельные наборы дескрипторов для куб-карты, местности и т. Д.

Примеры LunarG должны работать аналогично, хотя, если я не ошибаюсь, они никогда не используют более одной текстуры?

+0

Большое вам спасибо за ваш ответ. Предполагается, что m_texture_descriptor_sets являются наборами дескрипторов, обрабатывающих материалы/текстуры модели измельчителя, но его размер выглядит как доступный только для одного субмеша в виде m_texture_descriptor_sets = (VkDescriptorSet *) malloc (sizeof (VkDescriptorSet)). '. Мне интересно, правильно ли я это понимаю. –

+0

Я не слишком глубоко вникнул в образец чоппера, но если вы посмотрите на шейдер фрагмента, вы увидите, что он использует массив сэмплеров: 'layout (set = 1, binding = 0) равномерный sampler2D tex [ 16]; ' Итак, я думаю, что подмастеры просто используют другой индекс в этом массиве сэмплеров для выбора между текстурами. Это еще один способ достижения различных текстур в (sub) сетке. –

+0

Спасибо за подсказку. Теперь я работаю над проектом Mesh LunarG в отношении множества наборов дескрипторов. Я создал массив VkDescriptorSet для привязки текстур каждого меша и попытался выделить для них память как 'VkDescriptorSet * texDescriptorSets = (VkDescriptorSet *) malloc (sizeof (VkDescriptorSet) * g_MeshCount) ;, однако, похоже, что объект устройства имеет строгое ограничение для его размера и, следовательно, у меня есть утверждение о выходе из памяти при вызове функции vkAllocateDescriptorSets(). Было бы очень любезно сказать вам, правильно ли я поступаю. –

3

У вас есть концептуальный объект, который состоит из нескольких ячеек, которые имеют разные потребности в текстурировании. Общими способами для этого являются:

  1. Изменить наборы дескрипторов между частями объекта. Болезненно, но он работает на всех аппаратных средствах, совместимых с Vulkan.

  2. Используйте текстуры массива. Каждая отдельная сетка извлекает свои данные из определенного слоя в текстуре массива. Конечно, это ограничивает вас тем, что каждая подметка использует текстуры того же размера. Но он работает на всех аппаратных средствах, совместимых с Vulkan (до 128 элементов массива, минимум). Уровень массива для конкретной сетки может быть предоставлен как константа push или базовый экземпляр, если это доступно.

    Обратите внимание, что если вам удастся сделать это с помощью базового экземпляра, вы можете визуализировать весь объект с помощью косвенной команды с несколькими рисунками. Хотя не ясно, что короткое косвенное многократное рисование будет быстрее, чем просто выпекание короткой последовательности команд рисования в командный буфер.

  3. Использовать массивы сэмплеров, в качестве Sascha Willems. Предположительно, индекс массива для подмеширования представлен как константа-константа или базовый экземпляр.Проблема заключается в том, что независимо от того, как обеспечивается этот индекс массива, он должен быть динамически однородным выражением. И реализация Vulkan не требуется, чтобы вы могли индексировать массив сэмплеров с динамически однородным выражением. Базовое требование - это просто постоянное выражение.

    Это ограничивает аппаратное обеспечение, поддерживающее функцию shaderSampledImageArrayDynamicIndexing. Поэтому вы должны спросить об этом, и если он недоступен, вам придется работать с # 1 или # 2. Или просто не запускайте это оборудование. Но последнее означает, что вы не можете запускать какое-либо мобильное оборудование, начиная с most of them don't support this feature.

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

+0

Большое вам спасибо за совет, и это было бы очень полезно для меня. –