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

Обёртки над GL-ными шейдерами - какие могут быть подходы? (2 стр)

Страницы: 1 2 3 4 Следующая »
#15
(Правка: 15:26) 13:39, 22 авг. 2019

=A=L=X=
> не ковырялся еще в этом.

приятного тебе времяпровождения с alignment


#16
16:04, 22 авг. 2019

innuendo
> приятного тебе времяпровождения с alignment

Мнение Suslikа весомо, но для меня это пока дикий архитектурный оверкилл. У меня пока всё простенько, мобильно и modelless так сказать.

#17
16:27, 22 авг. 2019

=A=L=X=
> Мнение Suslikа весомо

так я же не утверждал, что он пургу гонит - только всё не так однозначно

#18
(Правка: 16:53) 16:34, 22 авг. 2019

=A=L=X=
ну Суслик всё верно написал, лучше как можно сильнее отходить от ручной настройки и максимально использовать предварительный парсинг шейдеров во время их загрузки (командами gl ессно, исходник самостоятельно парсить не надо). Далее тебе лишь нужно будет указать структурку под нужный тип "вершины", автоматом ее валидировать и собственно всё. В таком случае придется писать минимум при написании нового шейдера и если даже ошибешься где то, то всегда сможешь выловить ошибку еще на этапе установки атрибутов.
В Ubo ничего сложного, единственное следить за выравниванием нужно. Но в документации всё это есть.

У меня примерно так выглядит:

auto attribs_desc = std::make_unique<InterleavingAttribsDesc>();
shader_program->getInterleavingAttribsDesc(attribs_desc.get());
attribs_desc->setAttribute(1, GL_SHORT, false);         // xywh
attribs_desc->setAttribute(2, GL_UNSIGNED_SHORT, true); // uuuu
attribs_desc->setAttribute(3, GL_UNSIGNED_SHORT, true); // vvvv
attribs_desc->setAttribute(4, GL_SHORT, false);         // pivotla
attribs_desc->setAttribute(5, GL_UNSIGNED_BYTE, true);  // color_tl
attribs_desc->setAttribute(6, GL_UNSIGNED_BYTE, true);  // color_tr
attribs_desc->setAttribute(7, GL_UNSIGNED_BYTE, true);  // color_bl
attribs_desc->setAttribute(8, GL_UNSIGNED_BYTE, true);  // color_br, как только последний атрибут указан, 
// структура валидируется и готова к использованию, если использовать до этой стадии будет инфа об ошибке.
// Если будет указан атрибут для layout'a которого нет также будет соответствущая запись в лог.
// В идеале от указания типа входных данных для атрибута можно было бы отказаться, но только для случаев когда типы полностью совпадают и не нужно нормализовывать. На этом этапе также можно внутри создать и заполнить vao и пользователю об этом не нужно даже знать.

auto attribs_buffer = std::make_unique<DataBuffer>
        (GL_ARRAY_BUFFER, GL_UNSIGNED_BYTE, attribs_desc->getAttribsSize(), max_vertices, GL_DYNAMIC_DRAW, nullptr);

// рендер
vbo->resetBuffer();
vbo->setBufferSubData(0, cur_elements_count * attribs_desc->getAttribsSize(), data);
    
shader_program->useShaderProgram();
shader_program->setAttributes(vbo, attribs_desc); // если уже были забиндены ранее, то повторно ничего не делается.
    
glDraw...

#19
18:17, 22 авг. 2019

=A=L=X=
> архитектурный оверкилл
суть наоборот в том, чтобы уменьшить количество сущностей, с которыми работает рендер. например, единственный тип "ubo buffer" покрывает сразу все возможные типы юниформ-констант во всех возможных сочетаниях и комбинациях. кусок кода, который я привёл, может показаться громоздким, но суть в том, что в нём находится всё — от установки рендертаргетов до шейдеров, блендинга, буфера глубины, констант, ssbo, текстур, семплеров, и всех остальных дроколлов. в нём на самом деле меньше сущностей, чем в типичном рендере opengl, но они более ёмкие.

можно пойти дальше и отказаться ещё от кучи сущностей, например, от вершинных атрибутов. пока это мало кто делает, но если целью стоит — создать минималистичную оболочку, то гораздо компактнее будет положить все вертексы в один ssbo и читать из него по gl_VertexId как из массива, распаковывая вершины так, как захочется в шейдере. то есть хоть через SoA, хоть через AoS, хоть через инстансинг, хоть вообще их процедурно генери — если проект учебный/демонстрационный, то такой код гораздо проще поддерживать и разбираться.

#20
18:20, 22 авг. 2019

Suslik
> суть наоборот в том, чтобы уменьшить количество сущностей

мда... во многих движках как раз и есть типа своих эффектов аля юниформы
вся эта мутота с смещениями скрывается на высоком уровне

#21
(Правка: 18:26) 18:25, 22 авг. 2019

innuendo
> мда... во многих движках как раз и есть типа своих эффектов аля юниформы
отдельные юниформы вроде слайдеров в редакторе шейдеров — это как раз для пользовательской логики. рендеру о них ничего знать не нужно. о пересылке констант на gpu имеет смысл думать как о пересылке данных по сети. никто по сети не отправляет отдельные float'ы на уровне сетевого драйвера. если пользователь отправляет 3 float'а, то они становятся частью одного пакета, которые одним блоком пересылается, потом на принимающей стороне он снова разбирается на составляющие. вот и с константами так же — рендеру об отдельных юниформах знать ничего не полагается.

#22
18:47, 22 авг. 2019

Suslik
> тдельные юниформы вроде слайдеров в редакторе шейдеров — это как раз для
> пользовательской логики. рендеру о них ничего знать не нужно.

как раз рендер и переводит эти отдельные параметры в low-level api реализацию

#23
(Правка: 19:10) 19:07, 22 авг. 2019

Suslik
> суть наоборот в том, чтобы уменьшить количество сущностей, с которыми работает
> рендер.

Да я верю что для сложного рендера это будет самый практичный вариант.
У меня пока просто околоспрайтовые вещи и кучи сущностей классического 3D API рендера отсутствуют.
Самый часто используемый VBO это 4 точки с координатами 0.0-1.0 и тому подобное. Для меня и модели и материалы это пока оверкилл, а шейдеры это буквально основа того вокруг чего пляшет рендер - даже вершинных атрибутов толком нет - через gl_InstanceID и четыре точки прекрасно рендерить можно целые тайловые карты и спрайтовые поля за 1 draw call и этого хватает за глаза.

#24
19:28, 22 авг. 2019

Suslik
> можно пойти дальше и отказаться ещё от кучи сущностей, например, от вершинных
> атрибутов. пока это мало кто делает
Собственно на горизонте уже мешлеты, если AMD реализует нечто подобное, то это уже станет маст хэв.

#25
19:56, 22 авг. 2019

=A=L=X=
> У меня пока просто околоспрайтовые вещи и кучи сущностей классического 3D API
> рендера отсутствуют.
Прелесть описанных техник в том, что там без разницы, выводишь ты один спрайт или миллион, выводишь ты спрайт из 4-х точек или сцену из 10к объектов на 10М вершин. Суть подхода от этого не меняется.

Вся сцена описывается в виде UBO/SSBO буферов. Для простых случаев - все может быть помещено в один буфер, типа:
SpriteInfo {
  vec4 position;
  vec4 texRect;
  vec4 color;
}
layout(std430, binding = 1) buffer SpriteBuffer { sprites SpriteInfo[] })

Дальше у тебя есть InstanceID или VertexID или DrawID, по которому ты вытаскиваешь нужные тебе данные из этого буфера.
Сам буфер создаешь  как персистентный SSBO (GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT), получив указатель на данные через glMapBufferRange можешь в любое время менять любое свойство любого объекта, о передаче этих даннх в шейдер и пакетировании их уже позаботится драйвер. Тоесть все что нужно сделать:

Единожды:
SpriteInfo *data = glMapBufferRange(...);

где-то в коде:
data[objectId].position = ...;

Тоесть ты работаешь с передаваемыми данным как с полями объекта (если с выравниванием все ок), никаких юниформ, никаких биндингов, все можно отрисовать за один раз.
Если нужны доп параметры - аналогично, просто создаешь еще один UBO/SSBO с нужными тебе данными, и биндишь к шейдеру сразу весь буфер, вместо передачи отдельных параметров.
Нужны слайдеры и прочая фигня - ничего не меняется, у тебя прямой доступ к этим параметрам, берешь и меняешь нужный параметр в нужное время.

Юниформы это уже пережиток прошлого.

#26
20:01, 22 авг. 2019

Fantom09
> Юниформы это уже пережиток прошлого

пушконстанты ?

#27
(Правка: 20:04) 20:01, 22 авг. 2019

Fantom09
> Юниформы это уже пережиток прошлого.

Ну они пока еще гораздо проще всех сущностей которые вырастают вокруг UBO - я у Борескова немног читанул - опять начало мельтешить в глазах от новых пачек glGen/glBaseIndex разномастных. Просто нет выгоды пока лично мне чтобы над этим вообще думать даже - идея ясна, мне пока не надо, в GL ES 3.0 юниформы не являются deprecated.

#28
20:17, 22 авг. 2019

Fantom09
> (если с выравниванием все ок)

как сказал Суслик нужен reflection чтобы всё было тип-топ иначе возможна попоболь

> Нужны слайдеры и прочая фигня - ничего не меняется

и тут всё не так просто - значения из слайдеров могут паковаться для записи в cbuffer

#29
(Правка: 21:11) 20:59, 22 авг. 2019

innuendo
> как сказал Суслик нужен reflection чтобы всё было тип-топ иначе возможна
> попоболь
и в чем проблема? glGetActiveUniformsiv+GL_UNIFORM_OFFSET, получил офсеты всех полей UBO на этом вся попаболь закончилась. Да, будет небольшой оверхед на CPU, но если это уже стало критичным, то стоит задуматься все правильно было сделано до этого :)

innuendo
> пушконстанты ?
Кстати, классная штука, без шуток) Жаль в ОГЛ это только в режиме spir-v работает.
...Виноват, спутал с Specialization Constants. Но в целом ответ тот же:
Единственное - нужно понимать что это не заменяет UBO/SSBO, но как замена дефайнов, дефолтных значений юниформ и ... констант - самое оно.

Передача уникальных данных для каждого объекта, пусть даже очень быстро, всеравно будет не эффективна, так как потеря времени на вывод отдельного объекта будет >>>>> времени, затраченного на обновление буфера UBO

Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумГрафика