-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
optimize lighting: check shadow ray after brdf shading #756
base: vulkan
Are you sure you want to change the base?
Conversation
Это интересное изменение, и результаты интересные. Я про это как-то не думал вообще, спасибо.
А вот это некорректное изменение. Дело в том, что Для прямого освещения, увы, придётся оставить А ещё можно попробовать finish your derivations применить, наверняка по красоте многое схлопнется ещё, как обычно.
Это интересно, и может быть валидным изменением, надо смотреть, не появляются ли какие когерентные артефакты. |
Если PROJECTED сэмплинг станет более легким, будет отлично. Остальные два изменения помогут выиграть дополнительные ресурсы. То, что SIMPLE_SOLID все облегчает, говорит о том, что если сэмплинг будет более легким, то производительность повысится. Я даже пробовал заменять их на spotlight, чтобы было еще меньше расчетов. И производительность повышалась еще сильнее. Что касается объединения рандомных значений всех источников света, артефактов просто не может быть. Причина в том, что рандомное распределение значений влияет на light direction. Например, луч тени будет указывать на левый-верхний угол полигона для всех источников света в одном текселе. В соседнем тексле лучи будут указывать уже на в правый-нижний у угол всех источников света. И так далее. Ровное рандомное распределение важно для создания мягкой тени источника света. И важно именно то, чтобы значения в соседних текселях были ровно распределены для одного источника света. Результат этого источника света не зависит от того, что получилось в других источниках света. Все ведь друг с другом складывается, а от перемены слагаемых сумма не меняется. Поскольку источники света друг от друга не зависят, то нам не важно, совпадают ли их рандомные значения или не совпадают |
Еще один плюс объединения рандомных значений источников света - возможность использовать синий шум. Но я бы не стал пока это делать, потому что его, возможно, стоит применить для чего-то более важного, чем шейдинг. Например, в выборе направлений для баунсов или в рандоме источников света. То есть для чего-то сильно шумного, что хотелось бы более ровно распределить. А если в цепочке вычислений будет два раза использован синий шум, получится, что во всех пущенных вправо лучах отражения будет один источник света, а в пущенных влево - другой. И это уже действительно приведет к артефактам. Поэтому синий шум лучше использовать только один раз, а для менее важного использовать обычный рандом |
Вот, кстати, почему SIMPLE_SOLID не алё: #361 |
Но если удастся убрать мусорную нарезку bsp (а это вроде как было в планах чтобы жижу исправить #654) то вероятно проблема уйдёт и SIMPLE_SOLID будет пригоден, нет? Там ещё был случай с нормалями насколько помню, но это в игре едва ли заметно. |
@@ -10,9 +10,9 @@ | |||
#define DO_ALL_IN_CLUSTER 1 | |||
|
|||
#ifndef RAY_BOUNCE | |||
#define PROJECTED | |||
//#define PROJECTED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это в любом случае пока рановато, много где будет выглядеть некорректно без решения #654.
Это можно было бы принять как улучшение SIMPLE_SOLID на будущее, но без форса его как основного сейчас. |
Огромные полигоны типа лавы или больших ламп можно было бы через gi освещать естественным попаданием в них отскакивающих лучей. Спекуляр тоже естественно возникнет у них через отражения. И это будет гораздо естественнее даже Projected сэмплинга, потому что он - тоже всего-лишь аппроксимация, пусть и точная. Тогда можно будет сделать особый сэмплинг для квадратных лампочек, которых очень много в игре. Таких сэмплингов полон шейдертой на любой вкус и цвет. Выбрать самый быстрый и радоваться |
Мне очень не нравится, что в projected туда-сюда передаются массивы точек, их в структуре несколько штук. И какая-то стена кода непонятная. Из семплинга можно убрать спекуляр вообще, потому что плоскости видны в отражениях (сейчас не видны, я выключил, надо бы включить). Отражение плоскости и есть спекуляр. Более того, когда мы аппроксимируем спекуляр, у нас там видны квадраты, залитые цветом. Таким образом даже такая стена кода, как Projected, оказывается просто аппроксимацией ненужной, лишней и очень неточной. Тени, которые используют light direction, можно рандомить с помощью барицентрик координаты на квадратике. там даже матрицы не нужны, просто 2 стороны куба умножаем на 2 рандома, складываем. Получается кончик для тени. Из всего семплинга нужна только яркость диффуза без учета шейдинга (w-составляющая, приходящая из функций сэмплинга полигонов). Есть много примеров, где можно ее получить |
То, как сделано сейчас, вызывает дублирование спекуляра на отражении и в функции прямого освещения. Спекуляр получается в два раза ярче. Но лучом и отражением считать легче и правильнее в любом случае. Также в большинстве реализаций полигональных источников света огромную часть кода занимает обрезка полигонов плоскостью нормали. Можно не делать эту обрезку, а просто рандомить луч тени по всей поверхности источника света. Если плоскость рассечена, то часть лучей не дойдет до источника света. Мы в любом случае считаем мягкую тень, и если она будет выполнять еще и эту функцию, можно будет избавиться от отсечений и дублирования массивов с вертексами. Они тратят не так много ресурсов, но, возможно, именно потому что регистры уже переполнены отчасти благодаря им. |
Резюмирую:
|
Спекуляр, рассчитанный через прямой свет, конечно, выглядит лучше при большом roughness, чем отражение (лучи слишком рандомно летают и скорее всего в маленький источник света не попадут). Но дублирование эмиссив кусочков в прямом и непрямом пассе (отражение и спекуляр, прямой диффуз и gi) это проблема. Возможно, надо добавить параметр, через какой пасс какой эмиссив кусочек обрабатывать. Может быть даже как-то автоматом это детектить. Если плоскость источника света не соответствует квадрату, то обрабатывать через баунсы. А если соответствует, то через прямой свет |
Увы. SIMPLE_SOLID это вообще хак тренировочный, чтобы понять, что в принципе происходит. Именно барицентрически случайная точка (а не спроецированно, PROJECTED, случайная) даёт основные артефакты. Даже на исправленной BSP нарезке (что само по себе уже не очень просто) оно будет артефачить, особенно там, где мы считаем "примыкающий свет", т.е. там, где лампочка перпендикулярно касается стены. То есть там, где свет даёт самые пространственно-высокочастотно заметные эффекты. Где это будет наиболее бить в глаза.
Про нормали не помню, напомни. |
Плохо, да. Мы ездили мыслью по этому уже, выключая вклад всякого в шейдерах, чтобы не было двойного. Но я не помню детали -- оно может быть и не доделано до более-менее корректного. С моей стороны оно ждёт очередного прохода по устаканиванию -- у нас до сих пор не выписана, емнип, нигде полная схема того, как мы считаем освещение-отражения-отскоки. В основном потому, что мы до сих пор экспериментируем и находим всякое новое для себя и души.
Это интересная мысль, надо ставить эксперименты. Но есть заметная сложность в том, что в коде крайне тяжело понять, какие лапшинки из этой bsp-нарезанной лапши являются частью огромных поверхностей. Руками их тоже не проставишь -- их там сотни, если не тысячи.
Циклы там и передача массивов потому, что писали математики (и оно компилятором как-то оптимизируется, но фундаментально с таким количеством working set данных оно ничего не может сделать, конечно, поэтому жрёт регистры, как не в себя). Мы об это всё уже разбивали лоб ранее. |
Тут во всём это проклёвывается другая мысль ещё: Даже если оно не заработает достаточно хорошо, было бы всё равно полезно иметь рядом лежаший unbiased ground-truth рендер, который можно по команде позвать отрисовываться на несколько секунд, чтобы сравнивать со всеми нашими сложными семплирующими утехами. |
В маленькие источники света маловероятно попадать лучом случайно, поэтому приходится сэмплить их как источники света. Вряд ли получится от этого уйти. Но есть еще пара мыслей.
|
То есть я хочу попробовать сохранить position_t, нормали и material_rmxx всех пикселей клетки 8х8 в shared_memory, чтобы можно было прочитать их один раз (так оптимизируются блюры) А потом в одном потоке (pix) брать один источник света и с ним ходить по всем этим пикселям. можно сделать несколько рандомных сэмплов, и если они есть, осветить еще и остальные пиксели. или посчитать сэмплинг эмиссив кусочка в половинном разрешении (w компонента дает мягкие переходы). А соседние потоки (pix) будут считать другие источники света. Это изменение порядка позволит прочитать в одном текселе всего-лишь 1 источник света на всю плитку 8х8 и, возможно, сэкономить на промежуточных значениях. А не читать сотни этих источников света в каждом потоке. |
Сравни на test_material где "синтетический" тест нормалей с разными сэмплерами, по идее на PROJECTED оно там выглядит визуально корректнее чем на SIMPLE_SOLID. |
Есть еще такая мысль: выбирать разные сэмплинги в зависимости от расстояния. К примеру, вблизи нам очень важно сэмплить весово, потому что источник света сильно искажен в проекции на полусферу. Но если он далеко или если он маленький (небольшой угловой размер), его можно сэмплить менее точным сэмплингом или вообще схлопнуть в точку. Самое сложное здесь - подогнать все сэмплинги по яркости друг к другу в местах перехода один в другой. У меня не получалось это сделать раньше. Возможно, надо просто более аккуратно это посчитать. К сожалению, это не решит проблемой с комнатой ученых. Там очень много плоскостных источников света в одном очень маленьком месте |
В комнате не много, хотя там есть лишние 5 источников из-за сраной bsp нарезки, там проблема отсечения видимости из-за неудачных кластеров (попадает парадная комната с её лампами) и кривого BSP-отсечения (попадает коридор с лампочками по бокам, но парадной не видно, но это не мешает кластерам как-то заафектить если подойти к стене). |
Когда я добавлял в старых ветках рандом источников света, рядом со стенками очень сильно шумело как раз там, где было много лишних источников света. Но и в самой комнате тоже шум был выше нормы, потому что в ней стоит несколько шкафов, на каждом из которых по 4 плоскостных лампочки. И еще на потолке источники света. В сумме их получается очень много Насчет упрощенного сэмплинга: я правильно понимаю, что проблемы в основном при контакте с источником света или там, где он занимает большой угловой размер для текселя? Если да, то при удалении от источника света на пару его диаметров менять сэмплинг на упрощеный |
18 всего логических + 5 паразитных из-за нарезки, итого 23, это очень много? Например в раздевалке 15 источников полигональных + 3 спотлайта |
Тогда странно, что такая маленькая разница в числе источников света и такая большая во времени кадра UPD: у нас ведь не BSP видимость. У нас кубические кластеры, в которые собраны источники света соседних BSP участков. Надо сделать вывод разного количества источников света разными цветами и узнать фактическое число у нас. У меня наибольшую проблему вызывает стенка, контачащая с синим холлом, в который ты заходишь от вагончика. |
Почему-то число источников не обновляется, показывает что их дохера, только в одном месте у меня обновилось число поинтов и всё, в других ничего. |
Это на vulkan ветке, или на моих поделках свежих? |
Кстати в раздевалке тоже есть какой-то динамический полигональный источник, но не ясно что это. |
Увеличило производительность полигональных источников света
В комнате ученых пасс light_direct_poly занимал 19 миллисекунд. После изменений занимает 13 миллисекунд. Общая длительность кадра уменьшилась с 42-45 миллисекунд до 32-35 миллисекунд.
Главным изменением стала проверка яркости brdf затенения перед пусканием луча (до этого сначала пускался луч и только потом считался шейдинг). В результате лишние лучи пускались даже тогда, когда свет не падал на плоскость (этот расчет и происходит в brdf)
Порядок проверки не играл роли при PROJECTED варианте сэмплинга. Но при выборе SIMPLE_SOLID производительность выросла.
Точно так же без изменения порядка проверок SIMPLE_SOLID не увеличивала производительность относительно PROJECTED. Но вместе с изменением порядка проверок сэмплинг SIMPLE_SOLID увеличивает производительность.
UPDATE: Второй (небольшой) оптимизацией стало вынесение вычисления рандома вне функции сэмплинга источников света. Теперь для всех источников света в текселе считается один набор значений vec3 rnd. Это никак не влияет на визуал, т.к. эти значения варьируются в соседних текселях, что важнее
P.S.: в названии одного из коммитов указана ишью, но он к ней отношения не имеет
До изменения порядка и выбора SIMPLE_SOLID:
После изменения порядка и выбора SIMPLE_SOLID:
После оптимизации рандомных значений для источников света:
Комната ученых (после изменений):