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

Volumetric Lighting.

Страницы: 1 2 Следующая »
#0
11:18, 30 апр. 2021

Пытаюсь приготовить физически корректное объемного освещение по этому папиру.
https://www.pbr-book.org/3ed-2018/Volume_Scattering/Volume_Scattering_Processes
Вроде бы все более-менее уяснил, но мне не дает покоя параметр Albedo, который the probability of scattering (versus absorption) at a scattering event (вероятность рассеивания (против поглощения)). Если я правильно понимаю, то это просто множитель? Насколько физически корректно будет, если в качестве него использовать цвет, при условии что фазовая функция (Henyey-Greenstein) независима от длинны волны? Задача дать понятные крутилки художникам, transmittance они вроде как из экспоненциального тумана понимают.

#1
13:17, 2 мая 2021

Когда луч сталкивается с частицей он либо поглощается (absrobtion), либо меняет направление (scattering). Вероятности этих событий можно задавать двумя способами.
1) коэффициенты absorbtion и scattering
2) albedo и extinction (absorbtion + scattering). Два способа взаимно конвертируются друг в друга. Extenction - контролирует плотность, а albedo баланс между scattering и absorbtion. Он в некотором смысле является множителем. Так чем больше albedo, тем меньше лучей поглощаются и больше выходят наружу. Если для он задается как vec3, то для разных каналов это соотношение будет разным.  Фазовая функция это распределение направлений на этапе scattering-а и с albedo не связано.

Transmittance - это общая пропускаемость сквозь volume, которая падает по мере увеличения extinction. Ее явно задавать не нужно, она высчитывается коде.

#2
14:57, 2 мая 2021

xruck
> Фазовая функция это распределение направлений на этапе scattering-а и с albedo
> не связано.
С альбедо нет, но она может быть зависима от длинны волны, если я правильно понимаю. Потому и уточнил.
То есть в целом rgb альбедо это более-менее PBR подход. Понял, спасибо.

#3
(Правка: 9:10) 8:52, 3 мая 2021

тут надо учитывать, что поглощение можно аппроксимировать двумя способами:
1) просто экспоненциальное затухание для всего луча, то есть

float density = ...;
float absorb = exp(-path_length * density);
float3 reflected_color = lerp(background_color, scattered_color, absorb);
таким образом поглощают туман, некоторый дым, пар, пыль и подобные среды, которые можно представить как взвесь относительно крупных частичек (больше длины волны) с каким-то альбедо цветом. именно этот способ описан в твоём пейпере.
2) затухание считается отдельно для каждой длины волны
float3 density = float3(...); //каждая волна поглощается по-разному
float3 absorb = exp(-path_length * density); //float3
float3 reflected_color = lerp(background_color, scattered_color, absorb);
таким образом поглощают свет, например, воздух (поэтому небо синее, так как оно рассеивает короткие длины волн сильнее, чем красные), мелкий сигаретный дым или морская вода. обращу внимание, что считать таким подходом рассеяние для каналов RGB — это не то же самое, что считать рассеяние для всего спектра, который потом переводится в RGB. результат может быть разным, но в реалтайме на это забивают.

оба подхода в разной степени PBR, но художникам гораздо проще обращаться с первым, так как в нём всего два параметра — density и scattered_color, который по факту определяется через albedo. второй же подход — более общий, он включает в себя первый подход как частный случай, но его гораздо труднее настраивать, потому что density — это rgb цвет, но он определяет _поглощение_, то есть если ты хочешь, например, синюю воду, то должен дать ему жёлтый цвет (потому что красная и зелёная волны поглощаются).

вот тут в районе формул (6) и (9) это хорошо объясняется: https://www.tandfonline.com/doi/pdf/10.1080/19475683.2015.1050064 (только сейчас заметил, что у них в формуле (6), кажется, перепутаны местами Iw и Ib, но текстом объяснение даётся правильное)

#4
15:49, 3 мая 2021

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

#5
(Правка: 15:55) 15:54, 3 мая 2021

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

#6
16:04, 3 мая 2021

Suslik
> и ни у кого такой проблемы нет.
Видел подобное на многих движках, например UE. Надо поискать...
Такой есть, но это не совсем то

+ Показать
#7
16:38, 3 мая 2021

/A\
Не понял как такое возможно. Я на фрокселях делаю, единственный достоверный косяк это то, что затухание дирекшнл лайта вдоль луча аппроксимировать дорого, если с инъекциями делать. А резолв идет как раз от ближнего слайса к дальнему и никаких проблем сортировки быть не должно.
Артефакт на скрине это по-моему косяк блендинга, у меня партиклы освещенные вольюмом такие артефакты дают, пока не разобрался как побороть, кроме как аддитивно блендить.

#8
17:59, 3 мая 2021

Dampire
> А резолв идет как раз от ближнего слайса к дальнему и никаких проблем
> сортировки быть не должно.
Так это не проблема сортировки, а проблема "блендинга", точнее формулы накапливания transmittance.
Я все хотел сравнить эти популярные апроксимации и реально физически корректный рендеринг объема, но пока некогда.

#9
(Правка: 18:18) 18:17, 3 мая 2021

Дайсы уже сравнивали. Как минимум фроксели работают нормально. На какой-то странице есть сравнение с path-трейсером. Правда у них еще до кучи и шэдоу-вольюмы для каждого источника, чтобы затухание в неравномерной среде посчитать.
https://www.ea.com/frostbite/news/physically-based-unified-volume… -in-frostbite

#10
(Правка: 6:10) 6:05, 4 мая 2021

/A\
> Я все хотел сравнить эти популярные апроксимации и реально физически корректный рендеринг объема, но пока некогда.
я так и не понял, какую из этих формул ты считаешь аппроксимацией. потому что любой реймарчинг делается через интегрирование двух величин: прозрачности и светимости. при этом интегрировать можно хоть сзади наперёд, хоть спереди назад, формулы можно соответствующим образом перевернуть и результат будет одинаковым(правильным). аппроксимации начинаются там, где случается первый ивент скаттеринга: в реалтайм техниках ты не можешь проследить полный путь рассеянного луча и поэтому для него используется либо предпросчитанное значение светимости, либо для него игнорируется окклюжен. однако, ни одна из этих аппроксимаций не даст тех артефактов, которые ты описываешь.

Dampire
> https://www.ea.com/frostbite/news/physically-based-unified-volume… -in-frostbite
они используют первый (упрощённый) подход, который я описал — поглощение считается одним float'ом. таким образом нельзя рендерить атмосферу, тонкий дым и воду.

#11
11:41, 4 мая 2021

Suslik
> при этом интегрировать можно хоть сзади наперёд
Светимость надо домножать на интеграл прозрачности, так что совсем от балды не получится.
На скрине у /A\, походу, проблема именно с отсутствием взвешивания светимости.

#12
(Правка: 11:59) 11:53, 4 мая 2021

}:+()___ [Smile]
> Светимость надо домножать на интеграл прозрачности, так что совсем от балды не
> получится
да всё получится, потому что в обоих направлениях можно считать внутренний и внешний интеграл одновременно:

//front to back
float3 total_emission = 0.0f;
float3 total_absorption = 1.0f;
for(float ray_pos = ray_start; ray_pos < ray_end; ray_pos += step)
{
  float3 sample_absorption = exp(-GetAbsorptionDensity(ray_pos) * step);
  float3 sample_emission = GetEmissionDensity(ray_pos) * step;

  total_emission += total_absorption * sample_emission;
  total_absorption *= sample_absorption;
}

//back_to_front
float3 total_emission = 0.0f;
float3 total_absorption = 1.0f;
for(float ray_pos = ray_end; ray_pos > ray_start; ray_pos -= step)
{
  float3 sample_absorption = exp(-GetAbsorptionDensity(ray_pos) * step);
  float3 sample_emission = GetEmissionDensity(ray_pos) * step;

  total_emission += sample_emission;
  total_emission *= sample_absorption;
  total_absorption *= sample_absorption;
}
это сходится к одному и тому же, так как поглощение по всему лучу мультипликативно.

}:+()___ [Smile]
> На скрине у /A\, походу, проблема именно с отсутствием взвешивания светимости.
я не понимаю, что именно у него на скрине происходит, но это больше всего похоже на какую-то кашу, которая получается, когда они попытались замазать артефакты лоурез пасса тумана, который у них рендерится в 1/4 разрешения.

#13
12:29, 4 мая 2021

Suslik
> я не понимаю, что именно у него на скрине происходит
Это артефакт в UE из-за фиксированного шага маршинга. Первое пересечение происходит слишком близко, потом идет много коротких шагов по области с низкой плотностью, потом еще короткие шаги по пустоте, потом длинные шаги, пока наконец не находит второе пересечение вдали и маршинг упирается в ограничение по количеству шагов.
Я эту проблему решал увеличением длинны шага с расстоянием и получалось маршить внутри атмосферы на 700км. Хотя маршинг такого разряженого пространства это изначально неудачное решение, но зато делать быстро.

#14
12:55, 4 мая 2021

/A\
Это какая-то самопальная реализация или что-то старое? На данный момент в UE4 нативный Volumetric Fog реализован на фрокселях, а не реймаршинге. Там нет каких-либо адаптивных шагов, только размер 3D текстуры как раз с экспоненциальным, если не ошибаюсь, ростом в глубину.
https://docs.unrealengine.com/en-US/BuildingWorlds/FogEffects/Vol… og/index.html

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