@sim0nsays: GDC Report – Practical Implementation of Light Scattering – Egor Yusov (Intel)

И вот последний доклад с GDC – о том, как можно делать красивые light shafts.
Чтобы сразу показать картинки, главный линк – http://software.intel.com/en-us/blogs/2013/03/18/gtd-light-scattering-sample-updated.

В целом, мне кажется, про доклад можно почитать ради идей и оптимизаций в процессе, а не ради финального результата. Результат все же тяжеловесный и важности эффекта для большинства игр не соответствует. Но, конечно, игры важные нужны, игры важные важны, может у кого-то это ключевой эффект.

А вот для вдохновения и забавных техник ознакомиться вполне полезно. Epipolar space вообще колбаса – как обычно оказывается, что есть куча интересного неиспользуемого матаппарата.


People in this conversation:
Simon Kozlov Add
Engineer at ROBLOX (www.roblox.com), previously at Microsoft. And ClosedCircles was my idea.
Boris Batkin Add
i press buttons for living. u can call me god
Artem Brizitskiy (art321) Add
хуятор в uber команде Naughty Dog
Santa Monica
Roman Galashov (RomBinDaHouse) Add
Il-2 Sturmovik: Birds of Prey (Art Director);
Skyforge (TA)
Yury Degtyarev Add
Graphics programmer at Transas New Technologies

Simon Kozlov:
Кстати, пока не забыл. Напоследок я ходил на GDC на доклад некого Егора Юсова из Интела про light scattering
http://software.intel.com/en-us/blogs/2013/03/18/gtd-light-scattering-sample-updated
Вот тут есть скриншоты
Такая забористая полуакадемическая трава, я прямо представил себе себя 7 лет назад на Графиконе
Впрочем, мои облачка были зубодробительно простыми “палка-палка-веревка”, а тут академия без хороших артистов

Я попробую воспроизвести часть рассуждений и оптимизаций
(кстати, очень хорошая презентация, там хоть и дохера интегралов и прочего матана, очень классно и последовательно появлялись формулы и шаги в рассуждениях – буду у докладчика учиться)
У него где-то слайды кстати должны были быть…

Ну в общем, он начинает с рассмотрения интеграла для light scattering
Там, понятно, есть вклад от отраженного света объекта + вклад от всех частичек на луче до объекта
Каждая частичка отражает часть света источника в направлении камеры
От плотности частиц, распределения отраженного света и расстояния до частиц (потому что свет рассеивается) складывается финальный цвет
Одни частички – Rayleigh, другие частички – Mie
Этот интеграл решается в аналитической форме для направленного источника и не считается для точечного

Его новшество начинается с того, что он хочет учитывать затенение
Типа, вот у нас есть shadow map, давайте учитывать рассеяние только на тех частичках, которые не в тени
Давайте вот для каждого луча из камеры найдем незатененные depth ranges
И посчитаем вклад интеграла только в этих ranges
По-прежнему, для направленного источника есть аналитическая формула, для точечного – он придумал предрассчитать 2D LUT, чтобы можно было зная начало и конец вычесть-умножить и получить вклад

Дальше идут оптимизации. Если тупо посчитать такой raycast через shadow map для каждого пикселя – получается 91 msec на последней NV карточке в типичном разрешении
Первая мысль – давайте считать не для каждого пикселя, а только для некоторых, а остальное интерполировать
Какие пиксели важные? Давайте трансформируем все в забавное “epipolar” пространство, где лучи от солнца становятся параллельными
Мол, наблюдение такое, что вдоль этих лучей освещение меняется плавно
Поэтому интерполировать лучше в нем
И вот возьмем там сэмплы вдоль лучей от солнца + где есть depth discontinuites
Т.е. проанализуем depth buffer и в местах, где он сильно отличается добавим сэмплов
Считаем для этих пикселей честный трейс через shadow map
А остальное интерполируем

Вторая ключевая оптимизация, типа – этот самый трейс через shadow map, т.е. нахождение отрезков где луч “не в тени”
Используют технику для height map min/max mipmaps
Мол, если есть мипмапы, можно искать промежутки быстрее (я могу подробнее, если интересно)
Ну и остальное мелкая техника

В общем, основные идеи – интерполировать в специальном пространстве, пользуясь тем, что лучи исходят от источника, добавлять depth discontinuities как сэмплы и для трейса лучика через shadow map использовать height map min/max mips
Говорит, получается 2 мсек на топовой NV карте, 8 msec на последнем поколении Интела
Но в общем какие-то идеи в сильно упрощенном виде можно и использовать, если хочется очень крутых light shafts

art321: егора я знаю. я с ним работал. у чувака есть еще мега текстуринг с теселяцией и изменяющимся ландшафтом и все это работает на интегрированной графике. я постараюсь его на кружечки пригласить. чувак этот лайт шафт пишет оч долго мы сравнивали с нвидией у него было значительно быстрее. апдейт презентации не видел но вроде сценка в 2008 году была моя для этой штуки(ну надоже похвастаться)

Simon Kozlov: Да, ты там был в списке благодарностей в конце слайдов
На первом месте!

art321: круто, не знал

Simon Kozlov: Я на всякий случай уточню, что “без хороших артистов” – я имел ввиду, что эффект не фейкается как всегда артом, а почти честно считается

art321: туту смысл был не сделать клево а сделать честно (нахрена -хз ) интел платит че…

Simon Kozlov: Да-да. Т.е. никакая игровая компания бы такого не делала

art321: ну и мегатекстуринг для интегрированной графики – тоже изврат )

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

Yury Degtyarev: кто хочет ознакомиться с тесселяцией, есть его статья в GPU Pro 3
ты тоже там в Acknowledgments :)

Boris Batkin: гляжу в презенташку и понимаю что кодить я такое не возьмусь в том виде, в каком да

Simon Kozlov: О, а ты нашел линк на слайды?

Boris Batkin: только на демо покамест.
там прям в шейдере картиночки пиксельартом
даже прям интересно – в чём рисовалось. не поверю что руками

Simon Kozlov: emacs поди!

Boris Batkin: интересно было-бы сравнить визуально и по производительности с тем, какое в GPU gems 3

Simon Kozlov: А какое там?

Boris Batkin: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
тупое как пробка

Simon Kozlov: Я пробежался и не очень понял идею
Вот он там пишет классическую формулу из Hoffman and Preetham и говорит, надо учитывать для точки volumetric shadow factor
Какая точка имеется ввиду? Каждый пиксель на экране?
Вот луч улетел в бесконечность на far plane – какая это точка в world space?

Boris Batkin: если в бесконечность то вроде никакая
так вроде все пиксели на экране

Simon Kozlov: Ну а должна быть
Там же может тоже быть light shaft

Boris Batkin: значит я тоже что-то не понял
но глядя на картинки не уверен что хочу понимать

Simon Kozlov: Ну короче, это такой хак – он трейсит луч в 2D к источнику и смотрит, сколько окклудеров он пересечет
Если пересек что-нибудь – значит там shaft!
Совершенно без всякой физики, молодца
Впрочем, если ему надо на каждый пиксель трейсить – то можно подразогнать с теми вон интерполяционными идеями

Boris Batkin: в GPU-gems сделано так. трейсится в 2д от точки до источника. и суммируется. всё это медленно экспоненциально затухает
вопрос
чем оно отличается?

Simon Kozlov: Ну, многим. Повторюсь – вот луч улетел в far plane, от какой точки ты трейсишь до источника?

Boris Batkin: в 2д-то?

Simon Kozlov: Да

Boris Batkin: от каждой точки экрана до источника

Simon Kozlov: Ну и берешь черно-белый фактор?
Это такой хак
Очень практический, не имеющий отношения к тому, как свет распрострянется

Boris Batkin: в смысле чёрнобелый? я бы брал light * diffuse
в дефферед
прям как есть

Simon Kozlov: Ну это же может быть occluder, который вообще не на луче
Здание впереди
Оно же никак не может загородить твой воображаемый луч из точки в мире до источника
У чувака происходит более-менее корректное вычисление света
Он идет по лучу до каждой точки в shadow map space
И смотрит по этому лучу, что затенено
И там где незатенено – считает вклад от освещения в этом отрезке
Понимаешь? Трейсит по лучу до точки, не от точки до источника в 2D

Boris Batkin: т-е берёт все точки shadowmap-а
в 3д
трейсит по лучу до источника 3д
?

Simon Kozlov: Не трейсит до источника, вообще
Берет луч от камеры до пикселя
Растеризует этот луч в shadow map space
И по этому лучу в shadow map “трейсит”

Boris Batkin: вот теперь понял

Simon Kozlov: То есть, они считают совершенно разные суммы и факторы
У чувака из Интела много корректнее
Надо ли – скорее всего нет!
Чтобы быстрее работает – тоже вопрос, кстати
Потому что он этот трейс делает для маленького количества пикселей
Сильно меньше, чем родное разрешение

Boris Batkin: ну их оба можно в неродном очевидно
по одним и тем-же причинам

Simon Kozlov: Да, разумеется
Но в статье из GPU Gems про эту оптимизацию не было
Я почему и говорю, что некоторые идеи можно в каком-то виде использовать
Он типа предложил пространство, в котором интерполируется сильно лучше, чем тупо downsample
Такая нелинейная трансформация, хорошо коррелирующая с вкладом, который ты считаешь

Boris Batkin: подумал. разница будет в том, что если здесь источник не видно – то шафты всё равно будут
а если там источник не видно – то и шафтов не видно

Simon Kozlov: Там – это в GPU Gems?
Да будут наверно
Хотя зависит как считают
Если аккумулируют по 2d лучу – то не будет, да

Boris Batkin: там? там в 2д трассируют из точки экрана в точку где луч
и суммируют

Simon Kozlov: Если вклад следующего сэмпла на основе предыдущего – от не будет
А если каждый независимо – то будут какие-то, наверное
Посмотрел на код, каждый независимо
Будут какие-то шафты

Boris Batkin: ну там как только появляется “солнце” – яркий такой луч
а если нет – то блееееееееееееклый

Simon Kozlov: Ага
Ну от коэффициентов затухания зависит
Практический метод – надо настраивать слайдерами :)

Boris Batkin: блин. щас сяду вкодаю его тупо
чтобы “заценить”
у меня правда готовых сцен с “солнцем” нет
но я это дело поборю

Simon Kozlov: У чувака из Интела в демке какая-то сцена

Boris Batkin: у него там .mdl и .mtl файлы
надыть найти конвертор в колладу. подумав – не щас, через недельку
мне как раз есть куда такой эффект сунуть
мне идея трассировать по shadowmap понравилась
в таком раскладе понятно, что делать с лучами – какие упёрлись в far plane
их надо тупо обрезать по zfar последнего каскада
если тени каскадные
можно даже отдельно по каскадам рисовать. там-же интеграл
получается вполне себе луч znear-zfar
для каждого каскада
не, вообще хорошая идея.
надо будет её покурить

Yury Degtyarev: Например, для объёмных теней в частицах. Если делать просто попиксельный/повертексный shadow-лукап в шейдере частиц, то получится говно. Правда 2мс все равно многовато сейчас.

  • Sergant

    делал вроде как такую-же штуку еще 5 лет назад, тут видно к примеру http://www.youtube.com/watch?feature=player_detailpage&v=1jsdHft3YB8#t=242s

    • sim0nsays

      Прикольно, а как делал? Вот так же тяжеловесно как тут описывается?

      • Sergant

        ну в эффекте, который на видео, там 16 выборок из шадовмапы с самой обычно фильтрацией, оптимизации есть конечно, расчет идет только при пересечении вектора “точка на экране-глаз” со сферой источника, выбирались две точки пересечения со сферой. дальняя точка сравнивалась с текущими координатами точки экрана, выбиралась ближняя к камере, между ней и ближним пересечением, или глазом, 16 выборок с постоянным шагом. Небольшой шум добавлялся к шагу. Но самое главное было качественно размыть результат для устранения ступенек. Работало вполне шустро, видео снималось на ати 4870.

      • Sergant

        Боре кстати привет :)

  • Newton Moses

    I have found this post really informative. Feel free to check out https://www.literaturereviewhelp.com/41-literature-review-writers/well-researched/330-review or https://www.researchwritinghelp.com/9-cheapest-help/1150-referencing-a-research-paper whenever you are in need of top quality research paper writing and editing services.

  • Newton Moses

    Thanks for the post. You can also visit https://www.customwritingbay.ca/40-canadian-writers/1338-quick-help whenever you need top quality term paper writing services.