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

Корректный HBAO (2 стр)

Страницы: 1 2 3 410 Следующая »
#15
12:36, 26 мар. 2019

Suslik
Индайрект считает через SSAO? Он бох?


#16
15:46, 26 мар. 2019

lookid
> Индайрект считает через SSAO? Он бох?
А чего необычного? О том, как в скринспейсе считать простейший GI в один отскок ещё лет десять назад статьи писали. А если считать в два-три прохода можно даже мультибаунс симулировать. Например первые два прохода считать в 1/8 и 1/4 от разрешения и потом в каждой следующей итерации учитывать информацию из предыдущей. Такая метода отлично подходит, например, для топдаун стратегий, где камера всегда примерно на одном расстоянии от "земли". Позволяет не париться с запекаемым светом или другими хитровыделанными решениями. Раньше, лет так десять назад, видеокарты такое бы не потянули, но где-то начиная с 7хх линейки вполне себе сожрут и не поперхнутся. Никто просто особо заморачиваться не хочет - всё равно игроки не оценят.

#17
17:08, 26 мар. 2019

lookid
Это исключительно скринспейс. При этом тормозит адово (пока что).

#18
17:28, 26 мар. 2019

Соберу подводные камни, с которыми столкнулся, может кому-то пригодится.

1. Очень важно правильно рассчитать касательную.
Наивная проекция луча на плоскость нормали не даст нужный результат. У меня было аж две функции для проецирования. Обе давали одинаковый результат и обе фейлили. Что и являлось главным затыком.
Первый вариант - классическая проекция точки на плоскость: P - N * dot(P, N), где P = vec3(Ray, 0)
Второй - брутфорсные перпендикуляры:

vec3 T = vec3(Ray, 0);
vec3 B = normalize(cross(N, T));
T = normalize(cross(B, N));
При расчете касательной из производных (dFdx/dFdy) все получается правильно и с учетом перспективы. Но попиксельные нормали в этом случае, очевидно, учитываться не будут. Как их учесть пока не придумал )

2. Вклад в интеграл по лучу должен рассчитываться строго между начальным углом и максимальным. Можно накапливать дельты, можно рассчитать разницу после цикла. Никакой нормализации здесь не нужно.

3. Проверять вычисления на каждом шаге алгоритма с самого начала, на одном луче.

4. Не спешить и не пороть отсебятину, пытаясь подогнать результат под ожидания методом тыка. Хотя иногда очень хочется.

#19
18:02, 26 мар. 2019

San
ты ещё, конечно, до самого интересного не дошёл — сделать, чтобы оно в реалтайме работало.

#20
18:15, 26 мар. 2019

Suslik
Ну тут уже дело повеселее пойдет. Уже виден простор для оптимизаций. И алгоритмических и низкоуровневых.
Но сначала надо с нормалью разобраться и с view вектором, чтобы был референс.

#21
19:16, 26 мар. 2019

Suslik
> сделать, чтобы оно в реалтайме работало
скринспейс ? В 4K ? В реалтайме ? Может ну его? ))

#22
4:15, 27 мар. 2019

Misanthrope
> скринспейс ? В 4K ? В реалтайме ? Может ну его?
разумеется, влобный алгоритм это не потянет. в этом и интерес — как сделать, чтоб потянул.

#23
(Правка: 6:51) 6:47, 27 мар. 2019

Не получается рассчитать тангент из попиксельной нормали.
Нормаль в screen space. Для плоской стены, например, она имеет одно значение для всех фрагментов.
А если рассчитать тангенты из производных, то видно, что их значение зависит от view вектора. C такими тангентами все работает, что не удивительно, т.к. вектор горизонта рассчитывается в том же пространстве (H=P-S).
Проекция луча сэмплирования на плоскость нормали дает также одно и то же значение для всех фрагментов. Вдобавок, в случае, когда нормаль параллельна экрану, получается факап.
Как быть?

В доке от NV есть странная строчка:
> For finding the horizon angle in direction θ, we start by computing the tangent angle t(θ)
> and intersect a view ray with the tangent plane defined by P and the surface normal n.
Насколько я понял, "tangent plane" - это плоскость, перпендикулярная нормали. Ок, пересекли "view ray" и плоскость нормали, получили точку, и эта точка - P. WTF?

#24
6:49, 27 мар. 2019

Буду следить за темой)

#25
6:53, 27 мар. 2019

vindast
Я твой тред раза 3 перечитывал )

#26
6:55, 27 мар. 2019

San, я намыливаюсь вернутся и сделать трассировку по quad tree, фар Филд как говорил суслик.

#27
(Правка: 6:58) 6:58, 27 мар. 2019

Да и у меня в треде нет ничего полезного)

#28
(Правка: 7:08) 7:05, 27 мар. 2019

San
в общем случае для вычислений операций с горизонтами в скринспейсе тебе понадобится два направления — нормальное и тангенциальное. тогда угол горизонта всегда будет рассчитываться как арктангенс проекции любой точки на эти два направления. в принципе, эти два вектора можно выбрать вообще произвольным образом и формулы интегрирования должны сходиться к одному и тому же результату. однако, простые формулы просто через разность синусов, на которых строится hbao, не учитывают, например, член [cht]\cos^+(\vec n \cdot \vec l)[/cht], поэтому не стоит надеяться получить корректное диффузное освещение с их помощью. но на самом деле и интеграл с косинусом можно рассчитать аналитически.

однако, существует лишь один базис, в котором интегрирование по второму углу (то есть интегрирование между разными лучами) выполняется проще всего — это базис, построенный на векторе view, так как в нём веса всех лучей равны [cht]\frac{1}{N}[/cht]. поэтому я базис строю так:

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

единственный вырожденный случай, когда эти две плоскости не пересекаются — это если они параллельны. это возможно, только если плоскость нормали параллельна вектору view, что в случае gbuffer'а невозможно при корректных входных данных.

#29
7:31, 27 мар. 2019

Suslik
Спасибо!
Был у меня такой вариант, немного в другой мысленной интерпретации:

  vec3 D = vec3(Direction, 0);
  vec3 B = normalize(cross(V, D));
  T = normalize(cross(B, N));
Но по сути это оно и есть. А не работало оно из-за замыленности мозга и неверного порядка в одном из векторных умножений.
Страницы: 1 2 3 410 Следующая »
ПрограммированиеФорумГрафика