Metal. Передача в шейдер массива текстур
От: Homunculus Удмуртия  
Дата: 29.09.20 12:40
Оценка:
Форум этот скорее мертв, чем жив, так что вряд ли получу ответ. Но... мало ли.

Надо передать в Metal шейдер массив текстур. Заранее неизвестно сколько их там. Как делать?
Нашел array<texture2d> — но там как я понял надо знать размер заранее и указывать этот размер в описании этого массива в шейдере?
Нашел еще texture2d_array — я вообще не понял что это

Конечно, есть мысля все текстуры в одну слить, но уж больно неохота? криво как-то.

Знает кто как надо?
Re: Metal. Передача в шейдер массива текстур
От: Muxa  
Дата: 29.09.20 13:17
Оценка: 6 (1)
H>Надо передать в Metal шейдер массив текстур. Заранее неизвестно сколько их там. Как делать?
H>Нашел array<texture2d> — но там как я понял надо знать размер заранее и указывать этот размер в описании этого массива в шейдере?
Можно сделать так:
array<texture2d, SIZE> tex;

И передать SIZE как опцию компиляции, но тогда на каждый SIZE будет свой кернел.

H>Нашел еще texture2d_array — я вообще не понял что это

Насколько я понял это для текстур с mipmap, но могу ошибаться.

Ещё пишут что tier 2 железо поддерживает следующее:
kernel void kern(constant texture2d<float> *textures [[buffer(0)]]);

https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
Re[2]: Metal. Передача в шейдер массива текстур
От: Homunculus Удмуртия  
Дата: 29.09.20 13:24
Оценка:
Здравствуйте, Muxa, Вы писали:

Спасибо!

M>И передать SIZE как опцию компиляции, но тогда на каждый SIZE будет свой кернел.


Хммм, на каждый SIZE в смысле на каждое значение SIZE или на каждый тип SIZE? Что-то типа шаблона?
Если на каждое значение свой кернел, то не подходит. Текстур может быть одна, а может быть сто, заранее неизвестно.

H>>Нашел еще texture2d_array — я вообще не понял что это

M>Насколько я понял это для текстур с mipmap, но могу ошибаться.

Да, не то что нужно.

M>Ещё пишут что tier 2 железо поддерживает следующее:

M>
kernel void kern(constant texture2d<float> *textures [[buffer(0)]]);
M>


А вот это было бы идеально. Спасибо. Гляну
Re[2]: Metal. Передача в шейдер массива текстур
От: Muxa  
Дата: 29.09.20 13:25
Оценка:
H>>Надо передать в Metal шейдер массив текстур. Заранее неизвестно сколько их там. Как делать?
H>>Нашел array<texture2d> — но там как я понял надо знать размер заранее и указывать этот размер в описании этого массива в шейдере?
M>Можно сделать так:
M>
M>array<texture2d, SIZE> tex;

M>И передать SIZE как опцию компиляции, но тогда на каждый SIZE будет свой кернел.

Или, если есть возможность, можно ограничить SIZE каким-нибудь максимальным значением, а через параметры передавать фактическое количество используемых текстур, но возможно придётся добивать массив какими-нибудь текстурами пустышками по максимуму.
Re[3]: Metal. Передача в шейдер массива текстур
От: Muxa  
Дата: 29.09.20 13:28
Оценка: 6 (1)
M>>И передать SIZE как опцию компиляции, но тогда на каждый SIZE будет свой кернел.

H>Хммм, на каждый SIZE в смысле на каждое значение SIZE или на каждый тип SIZE? Что-то типа шаблона?

H>Если на каждое значение свой кернел, то не подходит. Текстур может быть одна, а может быть сто, заранее неизвестно.

На каждое значение. Итого пока два кернела: на одну текстуру и на сто текстур.
Re[3]: Metal. Передача в шейдер массива текстур
От: Homunculus Удмуртия  
Дата: 29.09.20 13:34
Оценка:
Здравствуйте, Muxa, Вы писали:


M>Или, если есть возможность, можно ограничить SIZE каким-нибудь максимальным значением, а через параметры передавать фактическое количество используемых текстур, но возможно придётся добивать массив какими-нибудь текстурами пустышками по максимуму.


Да, это понятно. Но криво. Кривее, чем моя мысль о сливании всех тексутр в одну полоску и пересчета UV налету. Блин, так не хотелось с этим заморачиваться, но видимо придется.
Re[4]: Metal. Передача в шейдер массива текстур
От: LuciferSaratov Россия  
Дата: 29.09.20 14:53
Оценка: 6 (1)
Здравствуйте, Homunculus, Вы писали:

H>Да, это понятно. Но криво. Кривее, чем моя мысль о сливании всех тексутр в одну полоску и пересчета UV налету. Блин, так не хотелось с этим заморачиваться, но видимо придется.


полоску не надо, лучше во что-нибудь более квадратное упаковать (есть специальные программы-упаковщики для текстурных атласов, например, TexturePacker).
я такое делал, причем разметку, т.е. что и где расположено в атласе, тоже упаковывал в текстуру (точнее, две текстуры), закодировав в цветовые компоненты.
таким образом, для указания нужной текстуры мне было достаточно её индекса в атласе, а шейдер уже мог всё вычислить сам (правда, ценой двух дополнительных выборок из текстур).
в итоге во всей игре получилась ровно одна текстура размером 16384х16384.

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

H>Знает кто как надо?


в современных графических API надо использовать bindless resources.
уверен, в Metal это тоже поддерживается.
Re: Metal. Передача в шейдер массива текстур
От: Homunculus Удмуртия  
Дата: 30.09.20 07:18
Оценка: 7 (2)
Здравствуйте, Homunculus, Вы писали:

Ееее
Сделал
Все работает!

Если у кого-то появится такой же вопрос, то вот пример от Эплов — https://developer.apple.com/documentation/metal/buffers/using_argument_buffers_with_resource_heaps?language=objc

Качаем, разбираемся.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.