Comments 16
Поэтому если у нас буфер цвета и нормалей имеют формат RGB8, то и буфер глубины придется делать того же формата, а значения упаковывать (разделять) по трем компонентам.


Не совсем верное утверждение. Необходимо условие: «одинаковая разрядность» всех RT в MRT. К примеру: RGBA8 — 32 бита на пиксель и Single — float-формат, один канал: 32 бита.
Вообще, при размытии SSAO-буффера необходимо учитывать глубину неоднородностей, просто так размывать нельзя.
Верно, но дополнительное чтение из буфера глубины во время размытия — это уже слишком для мобильного gpu, фпс и так не высок. Немного спасает то, что плотность пикселей на смартфонах и планшетах обычно довольно высокая, и косяки на границах объектов не так заметны.
Круто! Хорошая картинка!
Математика (особенно в шейдерах) всегда пригодится
Здорово.
А под какой лицензией Вы опубликовали это? Как Вы относитесь к Creative Commons?
Да как то не особо заморачивался на этот счет, весь мой код используйте как хотите.
Отличная статья! Позвольте немного критики:
Отдельно стоит сказать про z-буфер. Для использования в SSAO его нужно сначала сделать линейным, в противном случае на среднем и дальнем плане сильно теряется точность. Обычно для этого значения глубины пишут в отдельный буфер, часто вместе с нормалями. Однако дополнительный буфер не сулит ничего хорошего в плане производительности, поэтому линеаризовывать значения и записывать их мы будем не в отдельный буфер, а прямо в действующий, стандартный буфер глубины (gl_FragDepth). Это может вызвать артефакты на переднем плане (очень близком, практически вблизи передней плоскости отсечения), однако в основном такой буфер ведет себя вполне нормально.

Вот уж сэкономили…
1) Заслуженно получили артефакты (не только в SSAO, а во всей геометрии, особенно ближней к камере).
2) Лишились Early-Z при рисовании всей геометрии(!). В Вашей сцене перерисовки пикселов почти нет, так что это не сказывается, но в общем случае — это катастрофа.

Да и сам способ вычисления линейной глубины вызывает сомнения:
vec4 p = matrixProj*matrixView*vec4(vPos, 1.0);
gl_Position = p;
zPos = p.z;

Что по-Вашему есть «p.z»? Несомненно, это z-координата, но в каком пространстве? В проективном… а Вам нужно линейное. Правильно было бы так:
vec4 p = matrixView*vec4(vPos, 1.0);
zPos = p.z;
gl_Position = matrixProj*p;
Спасибо, учту в следующем проекте. Хочу попробовать сделать MSSAO, несколько эффектов и небольшой велосипедик.
Никогда не понимал смысла SSAO, выглядит ведь совсем не натурально: вместо теней получаются какие-то страшные черные контуры вокруг предметов. Рекомендую к прочтению: nothings.org/gamedev/ssao/
Only those users with full accounts are able to leave comments. Log in, please.