#graphics #vulkan
Вопрос:
Я хочу иметь формат ввода вершин, такой как:
layout (location = 0) in vec3 position; // Format VK_FORMAT_R8G8B8_SFLOAT layout (location = 1) in vec3 normal; // Format VK_FORMAT_R8G8B8_UNORM layout (location = 2) in vec3 tangent; // Format VK_FORMAT_R8G8B8_UNORM
Позиция в буфере вершин будет составлять 3 поплавка, поэтому занимает 12 байт. Обычный атрибут будет состоять из трех символов, от -127 до 127, и glsl будет считывать их как нормализованные поплавки (от -1 до 1). Так же будет и с касательной. Насколько я понимаю, «vec3» в glsl не говорит о том, что тип считывается, если 3 плавает, а скорее зависит от формата, заданного при создании описания входного макета и заданного конвейеру шейдеров. Это, по сути, означает, что нормаль занимает три байта, а затем касательная vec3 начинается на границе байтов, не выровненной по 4 байтам. Я не хотел использовать vec4, потому что тогда это было бы пустой тратой места.
Для того, чтобы использовать vec4s, я могу сделать:
layout (location = 1) in vec4 normal; // Format VK_FORMAT_R8G8B8A8_UNORM layout (location = 2) in vec4 tangent; // Format VK_FORMAT_R8G8B8A8_UNORM
Тогда компонент w нормального может иметь компонент x касательной, а компоненты x и y касательной могут иметь компоненты y и z касательной, оставляя мне два дополнительных байта для использования для других вещей, но тогда у меня возникает проблема с возможностью хранения, например, 16-разрядного числа в последних двух байтах, поскольку шейдер считывает байты в виде нормализованного поплавка.
Есть ли снижение производительности, чтобы упаковать нормальную и касательную более тесно вместе, как это, в виде двух vec3, каждый из которых занимает по 3 байта?
Ответ №1:
Прежде всего, зависит от реализации.
Во-вторых, наказание, вероятно, было бы незначительным для большинства случаев.
В-третьих, предположение, я бы сказал, что ГВ будет загружать весь кэш содержит необходимые данные, и если данные не выровнены должным образом его готов быть трансформированы (например, если поток может работать только на 4 выровненным данным и неприсоединившихся бы порезать его на кусочки) его бы просто сделать некоторые bitshifting и уплотнительное кольцо, добавив некоторые вычисления над головой.
Так что, вероятно, это компромисс между памятью(пространством, пропускной способностью) и вычислениями(fl/iops).