Войти
ПрограммированиеФорумГрафика

Запаковка матриц в sampler1D (GLSL)

#0
16:00, 1 мар. 2016

Давно "осматривал" как работает скелетная анимация и столкнулся с таким вопросом "А как передать матрицы анимаций в шеидер", за тем появился вопрос "сколько ячеек массива матриц с анимацией нужно сделать", а дальше интиресовал вопрос "повлияет ли на шейдер массив mat4[1000]" и решил поспрашивать на форумах и тогда кто-то посоветовал что можно сохранить анимацию в одномерную текстуру и таким образом получить подобие динамического массива в glsl (а ещё не нужно будет каждый раз загружать анимацию для следующего объекта, просто включить текстуру).
Вчера попробовал сохранить матрицу в 1d текстуру, но получилось ничего, указал формат RGBA, ширину в 4, тип данных FLOAT.
(в шейдере извлекал так "mat4 test=mat4(texture(sampler1D,0),texture(sampler1D,1),.....)")

п.с. Вообще стоит использовать одномерную текстуру для подобных целей? Или есть более "правильный" способ?
Кстать какой максимальный размер 1d текстуры в 4.5?


#1
16:22, 1 мар. 2016

блиин. Я забыл что координаты самлеров записываются числом от 0 до 1.....
Но всёравно хотелось бы унать про "легальные" способы

#2
16:25, 1 мар. 2016

Malkawian407
> п.с. Вообще стоит использовать одномерную текстуру для подобных целей? Или есть
> более "правильный" способ?
Способов много. Самый близкий к тому, что ты написал - это текстурный буфер (который в шейдере samplerBuffer). Его размер то ли неограничен, то ли ограничен, но каким-то большим числом (типа 16 МБ). Но по идее и в одномерную текстуру все кости должны уместиться.
Другой способ - это использование uniform buffer object. Это вроде бы самый распространённый способ и обычно самый быстрый, так как выборки из текстуры медленнее, чем чтение из буфера. Но в буфер может влезть около 256-1024 матриц 4x4, а значит, всю анимацию в одном буфере не уместишь. А для кадра нормально, не думаю, что где-нибудь будет больше 200 костей. И кстати, матрицы 4x4 не нужны. Достаточно матрицы 3x4 или кватернион+смещение.

А если хочется запихнуть анимацию целиком в шейдер, чтобы оттуда можно было прочитать любой кадр, то можно сделать 2D текстуру. Ширина её - число костей, высота - число кадров в анимации (или всех анимаций, если их несколько). Читая между текселей можно получить бесплатную линейную интерполяцию между кадрами.

Ещё в GL 4.3 есть shader storage buffer object (SSBO). Он похож на UBO, но позволяет создавать большие буферы (вроде до 16 МБ). Но скорее всего он будет медленнее UBO.

Malkawian407
> Кстать какой максимальный размер 1d текстуры в 4.5?
Наверное 16384, как и у 2D. По этой причине я вообще не вижу смысла в 1D текстурах.

Malkawian407
> блиин. Я забыл что координаты самлеров записываются числом от 0 до 1.....
Делить 1 на ширину и умножать на номер пикселя. Или использовать texelFetch, который сразу в текселях аргументы принимает. Его, кстати, как раз используют с texture buffer.

#3
18:46, 1 мар. 2016

gammaker
А в UBO мне за ранее нужно будет указывать размер массива или там механика такая что он "как динамический"? (ещё не связывался, но сегодня начну)

#4
19:17, 1 мар. 2016

А как в этом случае будет работать контроль костей, типа locomotion, когда вся анимация в текстуре?

#5
20:11, 1 мар. 2016

robotcity
Я не понял что именно ты имеешь в виду

#6
20:18, 1 мар. 2016

Malkawian407
Если я хочу контролировать анимацию, на какую высоту ставить ногу, то есть во время заготовленной анимации контролировать ее аспекты, я так понял что ты хочешь все кадры анимации перенести в текстуру, вот меня и  заинтересовал вопрос как менять параметры в этом случае?

#7
21:13, 1 мар. 2016

robotcity
Переписать текстуру. И "высота ноги" может быть выстовлена недовоспроизведённой анимации (хотя не сталкивался ещё)

#8
1:03, 2 мар. 2016

gammaker
О! Сделал (осталось только понять как это работает). Ответил на вопрос выше (в 18:46 #3)

#9
8:25, 2 мар. 2016

Malkawian407
> А в UBO мне за ранее нужно будет указывать размер массива или там механика
> такая что он "как динамический"?
Ты укажи в шейдере заведомо большой размер массива, например 1024 матрицы. Правда теоретически, возможны видеокарты, которые поддерживают UBO размером 16 КБ, то есть только 256 матриц, но я таких не видел.
И бинди через glBindBufferBase буфер такого размера, какой есть.

#10
11:06, 2 мар. 2016

gammaker
> так как выборки из текстуры медленнее, чем чтение из буфера.

Это смотря какая стратегия

#11
13:07, 2 мар. 2016

innuendo
> Это смотря какая стратегия
Вроде тут на форуме кто-то тестил скелетку и оказалось, что через UBO быстрее, чем TBO\текстура.

#12
17:57, 2 мар. 2016

gammaker
> Ты укажи в шейдере заведомо большой размер массива
Может не так как надо сделал, но в блоке указал массив без размера и всё ок.

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

Остаётся ssbo в место ubo

#13
20:46, 2 мар. 2016

SSBO вроде не 16 мегабайт а в разы больше...
Связано это в связи с тем, что SSBO привязана к общей памяти GPU.
UBO это константная память, поэтому быстрее.

ПрограммированиеФорумГрафика

Тема в архиве.