Все без исключения современные существующие графические движки основываются на уравнении рендеринга:
Это уравнение является основополагающим уравнением, описывающим общий случай геометрической оптики. И всё бы ничего, но в этом есть одна загвоздка: это уравнение масштабируется не так, как волновая оптика, которую оно аппроксимирует. В волновой оптике каждой точке пространства соответствует единственная величина — напряжённость электромагнитного поля \(F(\vec p)\), котора подчиняется уравнениям максвелла:
В геометрической оптике каждой точке пространства соответствует функция radiance'а \(L(\vec p, \vec \omega)\). Это на две размерности выше (\(\vec \omega \in R^2\)), чем в волновой оптике!
Есть ещё одно важное различие этих двух представлений: эти два представления являются линейными по источникам света (то есть финальная картина для двух источников света является суммой картинок для двух отдельных источников света), но уравнение рендеринга фундаментально не является линейным относительно окклюдеров. То есть две тени в уравнении рендеринга не являются аддитивными, они не являются мультипликативными, они являются мультипликативными для отдельно взятого источника — это жуткое различие по сравнению с волновой оптикой, в которой таких проблем нет.
Есть ещё много опосредованных фактоидов, намекающих, что мы что-то делаем не так, когда пытаемся представлять волновую реальность геометрически. Например, согласно голографическому принципу, информация, заключённая в объёме реального пространства, определяется площадью границы этого пространства, а не его объёмом. Этому есть некоторая параллель в геометрической оптике — размер полигональной 3д сцены грубо масштабируется как размер её текстур, который пропорционален её площади. Но для объёмов в геометрической оптике это уже не выполняется, хотя в реальности должно.
Мои предыдущие эксперименты с голограммами также дали мне более ясную интуицию, что на самом деле информация, заключённая в 3д сцене, однозначно и полно описывается произвольным _срезом_ её волнового поля, а не _объёмом_:
Последней каплей стало запощенное в соседнем треде видео(не моё), где некий деятель моделирует оптику как волновое уравнение, которое решается через клеточный автомат:
В принципе это видео — тривиальный, самый буртфорсный из всех возможных способов решения волнового уравнения. Но даже в таком виде можно заметить фундаментальные отличия от уравнения рендеринга. Основное отличие — что клеточный автомат работает на локальных правилах и состояние каждой клетки имеет размер o(1). То есть эволюция каждой клетки определяется только её ближайшими соседями и в ней хранится одно-два-десять чисел, а не "radiance probe" размером \(R^2\).
После этого видео меня ну просто прижало — ведь то же самое можно сделать гораздо эффективнее. Нет никакого смысла решать переходные процессы волнового уравнения, если интересует только steady-state решение. Получать его можно из аналитических, а не из численных соображений. Короче, встречайте, я написал первую версию 2д волнового солвера для света:
[Краткое пояснение, что здесь происходит: сверху источник света, две горизонтальных чёрточки в качестве окклюдеров для демонстрации теней]
На что смотреть на картинке выше. Обратите внимание, что на границах пенумбры видны волновые разводы. Это ничто иное как airy disk. То есть дифракционные эффекты в таком подходе являются не следствием дополнительных вычислений, а артефактами (как и в реальности). Например, если посчитать ту же самую сцену для большей длины волны, это выглядит так:
Обратите внимание, что дифракционные эффекты становятся ещё более выражены. Можно также визуализировать соответствующее комплексное поле (которое и является основополагающим описанием сцены с волновом подходе):

Давайте начнём что-нибудь обсуждать, если будет какое-то обсуждение по теме, я попытаюсь рассказать, как мой последний эксперимент работает. А то не хочу потратить 2 часа на распинания, чтобы выяснилось, что никому не интересно.
Интересный факт: знаете, что самое сложное в тестовых расчётах выше и что практически невозможно, используя простые конечные автоматы? Неотражающие поверхности. Просто-напросто сделать поверхность, которая блокирует свет и ничего не отражает, очень сложно, так как эта задача является эквивалентной задаче неотражающих граничных условий для волнового уравнения (которая печально известна тем, что практически не решается). Я обошёл эту проблему, используя принцип, схожий с тем, как отражают свет диэлектрики: на поверхности диэлектрика формируются электрические диполи в противофазе с падающим светом, которые его либо отражают, либо поглощают. Так вот можно вывести параметры наводящихся диполей так, чтобы свет полностью блокировался. Однако, всё равно наблюдаются небольшие отражения под острыми углами падения — у меня есть подозрение, что это — френель, от которого в волновой оптике принципиально невозможно избавиться. Но это я спекулирую.
Текущий солвер является жутким брутфорсом, написан на CPU без оптимизаций исключительно как proof of concept. Расчёты выше на нём считаются порядка 1-5 сек, однако, что интересно, не зависят от разрешения: финальное поле представляется суперпозицией диполей, а не регулярной сеткой, поэтому производительность зависит от количества диполей, а не от разрешения сетки.
Suslik
> После этого видео меня ну просто прижало — ведь то же самое можно сделать
> гораздо эффективнее.
А почему прижало то? У Onigiri хорошее видео, которое просто демонстрирует волновые эффекты. А условия для возникновения волновых эффектов - очень простые. Да, считать может быть неэффективно, да, это не реальное моделирование света, а просто что-то похожее. Но сходство например есть и между уравнениями Максвелла и СТО. Или например есть сходства в теории волны пилота и квантовой механики
Ну т.е. почему бы не поразвлекаться с клеточными автоматами так как это сделал Onigiri.
Suslik
> нет никакого смысла решать переходные процессы волнового уравнения, если интересует только steady-state решение. Получать его можно из аналитических
А как это делается? Ведь по сути надо посчитать распространение волн за большое время и вычислить среднюю амплитуду для каждой точки.
> финальное поле представляется суперпозицией диполей
Поясни простым языком. Интересует, какими данными оперирует твой алгоритм, каков конечный результат, какие основные структуры данных.
MrShoor
> Ну т.е. почему бы не поразвлекаться с клеточными автоматами так как это сделал Onigiri.
прижало меня вовсе не потому что он сделал что-то плохо или неправильно, а потому что мне стало любопытно, что будет, если попробовать немного по-другому.
Panzerschrek[CN]
> А как это делается? Ведь по сути надо посчитать распространение волн за большое время и вычислить среднюю амплитуду для каждой точки.
в том-то и дело, что это — жуткая переголова, которая никому не нужна. например, если есть точечный монохроматический источник, который непрерывно испускает волну, то для каждой точки можно элементарно посчитать вклад от него в амплитуду. и далее любую сцену можно представить как суперпозицию точечных источников. вопрос лишь в том, какие точечные источники _индуцируются_ на поверхности непрозрачных объектов, чтобы они себя вели в результате именно как непрозрачные.
Panzerschrek[CN]
> Поясни простым языком. Интересует, какими данными оперирует твой алгоритм, каков конечный результат, какие основные структуры данных.
диполь — это, считай, два близко расположенных источника. каждый источник описывается своим положением и комплексной амплитудой (то есть действительная амплитуда + фаза). алгоритм состоит из двух частей: в первой части даются известные источники на вход (например, в картинке выше — один точечный источник сверху) и где находятся окклюдеры. на выходе этой стадии алгоритма (самая сложная часть) — массив диполей на поверхности окклюдеров, поле которых при сложении с исходными источниками "гасит" поле внутри окклюдеров. то есть поглощение делается путём расчёта противофазных источников, которые спавнятся на поверхности окклюдеров. такое поглощение — это чисто волновой эффект, у которого нет аналогов в геометрической оптике, потому что в геометрической оптике источники всегда складываются конструктивно, а в волновой они могут интерферировать деструктивно. и именно благодаря деструктивной интерференции поверхностных наведённых диполей реальные тела могут быть непрозрачными.
на второй стадии алгоритма на вход подаётся просто массив точечных источников и строится их интерференционная картина (просто сложением в каждом пикселе). если всё было сделано правильно на первой стадии, то они интерферируют в то, что должно получиться.
Suslik
Получается, что вторичные источники в большом количестве создаются на границах разделения сред. Не многовато ли их в итоге получается? По идее, они должны быть расставлены гуще минимальной длины волны.
Suslik
> в первой части даются известные источники на вход (например, в картинке выше —
> один точечный источник сверху) и где находятся окклюдеры. на выходе этой стадии
> алгоритма (самая сложная часть) — массив диполей на поверхности окклюдеров,
> поле которых при сложении с исходными источниками "гасит" поле внутри
> окклюдеров.
Слабо представляю, как это делается. Через решение линейной системы, как в радиосити?
Panzerschrek[CN]
> Получается, что вторичные источники в большом количестве создаются на границах
> разделения сред. Не многовато ли их в итоге получается? По идее, они должны
> быть расставлены гуще минимальной длины волны.
прикол в том, что их влияние их всех сразу каждого на каждую точку можно считать через fft. именно в этом сила fft. причём интересный момент заключается в том, что волновая оптика принципиально линейна, поэтому её можно решать через fft, а геометрическая — принципиально нет, поэтому её нельзя.
Имбирная Ведьмочка
> Слабо представляю, как это делается. Через решение линейной системы, как в радиосити?
для отдельных плоскостей известно точное решение. но для перекрывающихся геометрий, которые влияют друг на друга — да, нужно решать систему. сейчас я её решаю гаусс-зейделем, но план заключается в том, чтобы с помощью fft считать влияние всего на всех и далее солвить итерациями Якоби. разница с радиосити заключается в том, что в радиосити не существует эффективного способа посчитать влияние всего на всех, а в волновой оптике — можно.
Suslik
>То есть дифракционные эффекты в таком подходе являются не следствием дополнительных вычислений, а артефактами (как и в реальности). Например, если посчитать ту же самую сцену для большей длины волны, это выглядит так:
Вот только мы плохо определяем реальную длину волны света. Длина волны может быть чистая, а может быть смесью других длин, какие именно волны наложили дифракцию - а хрен его знает без призмы. В компьютере с этим для игр никто особо заморачиваться не будет, нарисуют три чистых луча разной интенсивности и баста. Потому, как ни садитесь, а сядете на ящики от тары вместо стульев - такая реализация в железе. Вопрос стоит в том, как на приемлемом уровне халтуры сделать картинку полегче. Если есть такой алгоритм, и он не прибит гвоздями к плюсам и студии, то для движкописателей он имеет ценность. А если выигрыша по скорости там нет, то пока интерес представляет лишь в теории - всё равно как халтурить, но фпс нужен повыше.
Suslik
Кстати, а в скольких измерениях ты всё считаешь? В Двух?
Надо в трёх считать. Там будут всякие причуды вроде поляризации света.
Suslik
> В геометрической оптике каждой точке пространства соответствует функция radiance'а L(p, ω). Это на две размерности выше (ω ∈ R²), чем в волновой оптике!
На три, ибо там еще λ — Максвелл решает сразу для всех частот.
К сожалению, константа там такая, что эта асимптотика практически бесполезна, особенно для реалтаймовых применений. Вот в оффайн рендере, возможно, какая-нибудь вариация волнового алгоритма и зарешает.
> То есть две тени в уравнении рендеринга не являются аддитивными, они не являются мультипликативными, они являются мультипликативными для отдельно взятого источника — это жуткое различие по сравнению с волновой оптикой, в которой таких проблем нет.
В волновой оптике все то же самое: никакой линейности по окклюдерам нет, будь то граничные условия или наведенные диполи (которые зависят от решения — откуда и возникает нелинейность).
> В принципе это видео — тривиальный, самый буртфорсный из всех возможных способов решения волнового уравнения.
Стандартная явная схема. Для правильного соотношения между шагами по времени и пространству очень даже неплохой алгоритм, и по точности и по устойчивости. Я в универе точно таким же баловался.
> Так вот можно вывести параметры наводящихся диполей так, чтобы свет полностью блокировался.
Я для поглощающих граничных условий использовал половину одномерного волнового уравнения:
\(\displaystyle\partial_t^2\varphi-\partial_x^2\varphi=0\quad\rightarrow\quad(\partial_t+\partial_x)(\partial_t-\partial_x)\varphi=0.\)
Соответственно, на границе можно сделать \((\partial_t+\partial_x)\varphi=0\) и получится поглощающее граничное условие. По идее, это должно быть эквивалентно диполю соответствующей ориентации.
> Расчёты выше на нём считаются порядка 1-5 сек, однако, что интересно, не зависят от разрешения: финальное поле представляется суперпозицией диполей, а не регулярной сеткой, поэтому производительность зависит от количества диполей, а не от разрешения сетки.
Так просто вывод поля будет \(O(N^2)\) же? Возможно, в 3D получится срезать одну размерность если нас не интересует световое поле в толще, но как считать непонятно, ибо у FFT \(O(N^3)\) будет.
> на выходе этой стадии алгоритма (самая сложная часть) — массив диполей на поверхности окклюдеров, поле которых при сложении с исходными источниками "гасит" поле внутри окклюдеров.
Так, по идее, это надо рекурсивно запускать, ибо наведенные диполи сами могут наводить другие диполи.
Я бы просто записал уравнение на стационарное состояние и решал его мультигридом, а поверхности сделал гранусловиями.
Panzerschrek[CN]
> Надо в трёх считать. Там будут всякие причуды вроде поляризации света.
поляризацию считать возможно, но не обязательно. я вместо конкретно уравнений максвелла считаю уравнения по типу акустики (то есть волны плотности). у них нет поляризации, и если поляризационные эффекты не интересуют, их легко можно не считать. на самом деле ещё проще акустики — уравнение Гельмгольца, оно описывает распространение монохромного акустического сигнала (то есть фиксированной частоты).
}:+()___ [Smile]
> На три, ибо там еще λ — Максвелл решает сразу для всех частот.
лямбда нужна, чтобы считать дисперсию. если дисперсия не нужна, достаточно считать для трёх (r, g, b) частот и получить цвет.
> В волновой оптике все то же самое: никакой линейности по окклюдерам нет, будь то граничные условия или наведенные диполи (которые зависят от решения — откуда и возникает нелинейность).
идея в том, что если использовать итеративную схему вроде якоби, то одна итерация солвера является чисто линейной операцией. то есть полный поиск решения — нелинейная большая система, но одна итерация солвера — это линейный fft.
> Я для поглощающих граничных условий использовал половину одномерного волнового уравнения:
да, это так делается. у обычного волнового уравнения две характеристики (характеристические линии в смысле диффуров): одна соответствует волне, бегущей влево, вторая — волне, бегущей вправо. на неотражающей границе можно выбросить характеристику, соответствующую обратной волне, и считать практически уравнение переноса. на самом деле это не совсем точно и всё равно отражает, но так почти всегда делают.
> По идее, это должно быть эквивалентно диполю соответствующей ориентации.
основная идея прыжков с диполями — их можно считать на fft. граничные условия нельзя.
> Возможно, в 3D получится срезать одну размерность если нас не интересует световое поле в толще, но как считать непонятно, ибо у FFT O(N3) будет.
это пока что — главный вопрос. пока что я хочу считать распространение поля в толще. в принципе если это заработает, то можно делать хотя бы GI для volume rendering'а.
> Я бы просто записал уравнение на стационарное состояние и решал его мультигридом, а поверхности сделал гранусловиями.
я тоже думал об этом в ключе того, как решают уравнения гравитации для всяких звёздных кластеров: точечные массы при дальнодействии можно аппроксимировать одной точкой. похожим образом можно строить иерархии источников и считать у них дальнее поле приближённым/усреднённым образом. это что-то вроде геометрического мультигрида. в алгебраическом мультигриде будет O(N^2) явных связей, чего я хочу избежать.
можно даже переформулировать, чем я тут занимаюсь. я хочу написать рендер на основе fft. все эти диполи и волны — это лишь средство того, как оптику свести к свёртке. но это возможно! также ты поднял правильный вопрос, как рендер 3д сцены свести к свёртке в 2д (что должно быть теоретически возможно), но для начала я хочу свести его хотя бы к свёртке в 3д.
Suslik
> лямбда нужна, чтобы считать дисперсию.
Не, это понятно. Просто ты говорил в контексте эквивалентности геометрической и волновой оптики.
> идея в том, что если использовать итеративную схему вроде якоби
Мне кажется, это будет медленнее, чем решать все сразу мультигридом.
> в алгебраическом мультигриде будет O(N^2) явных связей, чего я хочу избежать.
Его, наверное, можно модифицировать и выкинуть детальную сетку вдали от источников.
}:+()___ [Smile]
> Не, это понятно. Просто ты говорил в контексте эквивалентности геометрической и волновой оптики.
они эквивалентны, если не интересует спектральный рендер. то есть в 99% около-геймдева, где цвет описывается r, g, b триплетом, а не спектром.
> Мне кажется, это будет медленнее, чем решать все сразу мультигридом.
мне кажется, что на форуме никого кроме тебя и дельфигеймера нет, кто мог бы такие идеи проверить и чисто теоретически получить результат, который никто не получал раньше. ну или хотя бы получить опыт и левелап своей интуции. это я к тому, что давай прогать и пробовать разные идеи. интересное ведь направление?
Суслик, твоя проблема в том, что ты не умеешь изъясеятся простым языком. Вот слабо описать свою теорию волновало рендера одним предложением?
Тема в архиве.