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

Отладка HBAO (Horizon Based Ambient Occlusion)

Страницы: 1 2 310 11 Следующая »
#0
2:20, 1 мая 2020

Всем доброго времени суток.
После реализации DS пытаюсь разобраться с HBAO.
Результат получается какой-то совсем некорректный.
В первой версии делаю без шума и без затухания.
Буду благодарен если кто посмотрит и подскажет где я ошибся.

+ Показать

Текущий результат выглядит вот так:

+ Показать

Заранее благодарю.

#1
6:50, 1 мая 2020

KaronatoR
базовый HBAO примерно так и выглядит.

#2
12:01, 1 мая 2020

Suslik
Вопрос немного не по теме. Как ты оптимизировал lsao? Я заметил, что от размера стека очень сильно зависит скорость. При размере стека 4к выдаёт примерно 50мс, а при 1к - 20мс. Я пробовал заменить его на общий для всех ssbo, но скорость так и осталась на 20-30мс. Параметры такие же, как на превьюхе статьи. Там без всяких репроекций и интерливинга выдаёт 5мс.

#3
12:06, 1 мая 2020

АкронимЛета
> Вопрос немного не по теме. Как ты оптимизировал lsao? Я заметил, что от размера
> стека очень сильно зависит скорость. При размере стека 4к выдаёт примерно 50мс,
> а при 1к - 20мс. Я пробовал заменить его на общий для всех ssbo, но скорость
> так и осталась на 20-30мс. Параметры такие же, как на превьюхе статьи. Там без
> всяких репроекций и интерливинга выдаёт 5мс.
если ты написал свой lsao и хочешь обсудить, создай отдельную тему

#4
12:38, 1 мая 2020

Suslik
Привет, спасибо за ответ.
Не мне с тобой спорить, но всё же спрошу.
Я почитал всё что мог про HBAO на форуме и там говорится, что есть несколько простых способов проверить корректность алгоритма:

1. Прямая плоскость должна быть абсолютно белой.
Это у меня выполняется.

2. Не должно быть резких, ломаных переходов.
У меня в углу творится какая-то жесть:

Изображение

3. Картинка очень яркая, а в советах, которые я нашел, говорится что в прямом углу значение должно быть 0.5 (или это я должен подобрать опытным путём?)

4. Что за мясо вокруг кубиков? Так точно должно быть?
Изображение

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

#5
12:43, 1 мая 2020

Если в конце шейдера усилить occlusion, возведя не во вторую, а в седьмую степень, то получится вот такое:

Изображение
#6
12:52, 1 мая 2020

KaronatoR
> 1. Прямая плоскость должна быть абсолютно белой.
> Это у меня выполняется.
учти, что плоскость должна быть абсолютно белой в смысле яркость = 1.0 (не больше и не меньше).

KaronatoR
> Не должно быть резких, ломаных переходов.
> У меня в углу творится какая-то жесть:
переходы вполне могут быть. например, если у тебя есть маленькое тонкое отверстие в геометрии, в нём будет околонулевая освещённость. переходы освещённости могут быть и на гранях, потому что хоть падающие лучи в них и меняются плавно, косинус при них меняется скачкообразно, поэтому на изломах может быть излом результирующей освещённости.

KaronatoR
> 3. Картинка очень яркая, а в советах, которые я нашел, говорится что в прямом
> углу значение должно быть 0.5 (или это я должен подобрать опытным путём?)
прямой двугранный угол должен иметь освещённость ровно 0.5, потому что в него попадают лучи из ровно половины полупространства. аналогично в углу куба освещённость должна быть равна в точности 0.25, так как туда попадает половина света двугранного угла.

> 4. Что за мясо вокруг кубиков? Так точно должно быть?
это не мясо, это false occlusion. на самом деле вокруг кубов горизонт должен проходить "под" ними, в скринспейсе об этом нет инфорации, поэтому значение горизонта переоценивается и получается слишком сильный окклюжен. отстой в том, что у этой проблемы нет идеального решения. есть много способов, но ни один из них не работает на 100% удовлетворительно всегда. я бы тебе рекомендовал почитать про GTAO (ground truth ao), пейпер был от близзард, кажется. это расширение HBAO на немного более общий случай с немного более правильным семплированием и они предоставляют похожий вариант разрешения false occlusion'а, к которому я в итоге пришёл.

> У меня ощущение что я где-то налажал
на самом деле основная проблема, которую я вижу у тебя — это просто мелкий радиус семплирования, поэтому AO выглядит очень локально. попробуй для верификации маршировать хотя бы через половину экрана. ясное дело, производительность HBAO при этом упадёт, но чтобы это посчитать за нормальное время, нужен уже LSAO, который реализуется на порядок сложнее.

я не могу сказать более конкретно, правильные у тебя синусы и арккосинусы, потому что не использую сам HBAO в чистом виде, он является промежуточным этапом между совсем фейковым crysis'овым SSAO и уже нормальным GTAO.

> Если в конце шейдера усилить occlusion, возведя не во вторую, а в седьмую степень, то получится вот такое:
так делать точно не надо

#7
13:05, 1 мая 2020

KaronatoR
> if (gamma > oldAngle) {
> float value = sin(gamma) - sin(oldAngle);
> occlusion += value;
> oldAngle = gamma;
> }
Заменяешь на oldAngle = max(gamma, oldAngle);

В конце первого цикла считаешь:
occlusion += sin(oldAngle);

KaronatoR
> occlusion = 1.0 - occlusion / float(directionsCount * stepsCount);
> occlusion = clamp(pow(occlusion, 2.2), 0.0, 1.0);
На:
occlusion = 1.0 - occlusion / float(directionsCount);

#8
13:07, 1 мая 2020

Огромное спасибо за ответ!

1. Про яркость 1.0 понял, сейчас в шейдере вставлю проверку и посмотрю что получится.
2. Ты абсолютно прав, уверен что дело в этом. Мой кубик это 5 отдельных плоскостей, вполне вероятно что между ними может быть микрощель.
3. Вот тут у меня беда. По идее, меняя параметры должно меняться только качество алгоритма, верно же? А у меня меняется (сильно) яркость итогового результата.
Вот пример:

    const float radiusSS = 512.0 / 1024.0;
    float radiusWS = 1.0;
    const int directionsCount = 32;
    const int stepsCount = 16;

    occlusion = clamp(pow(occlusion, 2.0), 0.0, 1.0);

Результат:
Изображение

Про остальное - понял, огромное спасибо за советы. Сейчас доведу до ума это (не могу оставить не разобравшись где ошибка) и буду двигаться в сторону GTAO.

#9
13:12, 1 мая 2020

KaronatoR
> Сейчас доведу до ума это (не могу оставить не разобравшись где ошибка) и буду
> двигаться в сторону GTAO.
это правильно

> Мой кубик это 5 отдельных плоскостей, вполне вероятно что между ними может быть микрощель.
микрощель сама может быть микротёмной, то она не может повлиять на освещённость объектов вокруг себя. вот если бы это была не щель, а торчащий треугольник, тогда да, мог бы. но это не твой случай.

> По идее, меняя параметры должно меняться только качество алгоритма, верно же?
от количества шагов и направлений яркость не должна меняться, это точно. скорее всего, баг как минимум здесь, где указал L (?):
> [b]АкронимЛета[/b]
> > occlusion = 1.0 - occlusion / float(directionsCount * stepsCount);
> > occlusion = clamp(pow(occlusion, 2.2), 0.0, 1.0);
> На:
> occlusion = 1.0 - occlusion / float(directionsCount);
ещё я бы тебе советовал не делать clamp(pow(occlusion, 2.2), 0.0, 1.0) при отладке, потому что неудобно верифицировать значения вроде 0.5, 0.25, итп. а когда отладишь, это делается через sRGB-рендертаргет, а не вручную в степень возводить.

#10
13:14, 1 мая 2020

АкронимЛета
Ох, сделал, но или сделал не то или я даже не знаю...
Код:

...
                        if (gamma > oldAngle) {
                            occlusion += sin(oldAngle);
                            oldAngle = max(gamma, oldAngle);
                        }
                        
                    }
                }
                occlusion = 1.0 - occlusion / float(directionsCount);
Изображение
#11
13:15, 1 мая 2020

KaronatoR
Я выделил какие куски заменить, а не строчки из этих кусков)

#12
13:16, 1 мая 2020

KaronatoR
> occlusion += sin(oldAngle);
суммирование надо сделать один раз после цикла:

АкронимЛета
> В конце первого цикла считаешь:
> occlusion += sin(oldAngle);

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


но вообще такие вещи отлаживать очень полезно учиться. я отлаживаю так:
- вместо цикла по куче направлений фиксирую одно направление
- вывожу цветом угол горизонта по этому направлению / (0.5 * pi) — там по контурам объектов эта величина должна быть ровно 1, на плоскостях, повёрнутых к камере, она должна быть ровно 0.
- как это работает правильно, убеждаюсь, что при использовании большого количества шагов по лучу результат становится только точнее
- перевожу угол горизонта в освещённость (через 1 - sin(angle))
- от одного луча перехожу к многим
- profit

#13
13:21, 1 мая 2020

Учёл все советы, написал вот так:

...
                        if (gamma > oldAngle) {
                            oldAngle = max(gamma, oldAngle);
                        }
                    }
                    occlusion += sin(oldAngle);
                }

             occlusion = 1.0 - occlusion / float(directionsCount);
             return float4(occlusion, occlusion, occlusion, 1.0);
            }

Получилось вот так:

Изображение

UPD: правку учесть не успел, сейчас сделаю.

#14
13:23, 1 мая 2020

KaronatoR
> Получилось вот так:
такое чувство, что ты за экраном семплишь (где глубина 0)? попробуй поотлаживай сам, как я описал выше

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

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