Задумал я травку нарисовать. Чтоб много-много травки было, ну скажем густо засеянное поле. Каждый кустик - 4 полигона, угол между полигонами - 45 градусов.
Итого 40 байт на один вертекс (относительный центр куста вместо вершины, нормаль, длина нормали, координаты текстуры и 4 байта на амбиент-освещение).
Ну я подумал, во первых не степень двойки, а во вторых, зачем хранить текстурные координаты, если для всех кустов они могут быть описаны 4-мя повторяющимися значениями. Проще их сгенерировать в вертексном шейдере. Так и сделал.
vec2 texcoords[4]; // setup texcoord table texcoords[0] = vec2( 0.0, 1.0 ); texcoords[1] = vec2( 0.0, 0.0 ); texcoords[2] = vec2( 1.0, 0.0 ); texcoords[3] = vec2( 1.0, 1.0 ); var_TexCoord = texcoords[gl_VertexID & 3];
Всё работает, всё замечательно. Потом думаю, дай-ка проверю классический вариант, с обычным хранением текстурных координат. Проверил. Прирост в производительности процентов 35-40. Карточка 9800GT.
Вот теперь сижу думаю - хотел сэкономить, а в результате только потерял. И что в этом куске такого тяжелого? Тем более это вершинный шейдер.
g-cont
static const vec2[4]?
g-cont
Почему &?
Зависимая выборка же. Ой, невнимательно прочитал. Из мыслей только (возможно) дорогая интерполяция зависимых значений.
Executor
> Почему &?
Это он так пытается не выйти за диапазон. & 3 это & 0b0000011, от есть от 0 до 3.
>>static const vec2[4]?
А в GLSL эти модификаторы работают? Я бы мог вообще эту табличку в униформ затолкать, если это так принципиально.
>>Почему &?
Потому что остаток от деления поидее выйдет дороже.
>>Это он так пытается не выйти за диапазон
Почему пытаюсь? Я реально за него не выхожу. Ну можно написать gl_VertexID % 4. Все другие способы намного сложнее, ИМХО.
Что-то я вообще ни разу не уверен, что операции & или % поддерживаются в наборе инструкций вершинных шейдеров.
По крайней мере, в vs_3_0 их нет. Возможно, это разворачивается в набор if-else условий, отсюда и падение производительности.
> Вот теперь сижу думаю - хотел сэкономить, а в результате только потерял.
Сэкономил на передаче данных, потерял на арифметике.
Если травка рисуется из статичного VBO - то лучше брать готовые текстурные координаты, чем считать в шейдере.
> Потому что остаток от деления поидее выйдет дороже.
Остаток от деления на степень двойки абсолютно то же самое, что и битовая операция, во всех более-менее современных компиляторах.
Это уже давным-давно не оптимизация, а так.. вредная привычка. У меня она тоже осталась. :)
Моласар
> вредная привычка. У меня она тоже осталась. :)
У всех осталась.
g-cont
предлагаю проверить
1)const vec2 texcoords[4] = {}; вне main
2) texcoords[gl_VertexID - 4 * floor(gl_VertexID*0.25)]
g-cont
Ну дак что там с вариантом const vec2 ?
> Я бы мог вообще эту табличку в униформ затолкать, если это так принципиально.
Кстати тоже проверь и отпишись.
AndryBlack
> 1)const vec2 texcoords[4] = {}; вне main
думаешь есть разница вне main?
>2) texcoords[gl_VertexID - 4 * floor(gl_VertexID*0.25)]
будет медленнее
g-cont
> И что в этом куске такого тяжелого?
Битовые не везде шустро работают
Andrey
> думаешь есть разница вне main?
если оно написано именно в таком виде как привел ТС то вполне возможно что на каждую вершину заполняется массив, компиляторы шейдеров могут быть довольно примитивны
Andrey
> будет медленнее
Как реализовано нахождение остатка от деления в вершинных программах?
innuendo
> Битовые не везде шустро работают
За что я ненавижу GLSL - так это за то, что нельзя просто так взять и посмотреть сгенерированный асм.
То ли дело Cg. Он, увы, дисконтинуед, но и то, что нвидия успела реализовать - более чем неплохо.
> компиляторы шейдеров могут быть довольно примитивны
Ага, и вот за эту неопределённость гейзенберга ненавижу.
Моласар
> За что я ненавижу GLSL - так это за то, что нельзя просто так взять и
> посмотреть сгенерированный асм.
> То ли дело Cg. Он, увы, дисконтинуед, но и то, что нвидия успела реализовать -
> более чем неплохо.
Cg тоже не давал, если glsl режим. А что дало бы вслучае ТК ? Ну узнал бы что там битовая и ?
innuendo
> Cg тоже не давал, если glsl режим
Глсл это обёртка над асмом в любом случае - компилит в наилучшую поддерживаемую шейдерную модель. В сг можно было скомпилить под какой-нибудь fp40 и посмотреть.
> Ну узнал бы что там битовая и ?
И фальсифицировал бы гипотезу о том, что битовые операции не поддерживаются на данном железе, разворачиваются в более сложную арифметику и именно за счёт этого дают падение фпс.
Глсл позволяет не задумываться об андерлайинг хардваре, и сюрпризы начнутся на всяких интелах, если там тот же шейдер скомпилится под другой профиль с другим набором инструкций.
В сг можно явно выбрать профиль и посмотреть генерируемый асм для него (ессно кроме профилей glslv/glslf).
Тема в архиве.