Рассчитать радиус объема света от интенсивности
В настоящее время у меня есть проблема с вычислением радиуса объема света для отложенного рендеринга. При низкой интенсивности света объемный объем выглядит правильным, но когда интенсивность света (и, следовательно, радиус) увеличивается, объем света становится все более и более малым.
Я рассчитываю радиус объема света (в мировом пространстве) следующим образом:
const float LIGHT_CUTOFF_DEFAULT = 50;
mRadius = sqrt(color.length() * LIGHT_CUTOFF_DEFAULT);
Затем я использую это значение для масштабирования поля.
В моем шейдере я вычисляю затухание следующим образом:
float falloff = 5;
float attenuation = max(0, 1.0 / (1+falloff*(distance*distance)));
Поэтому, очевидно, я бездельничаю с математикой. Затухание должно быть линейным, верно? Но как мне теперь правильно рассчитать значение мирового масштаба для объема света?
PS светлый цвет может выходить за рамки (1,1,1), так как я планирую использовать HDR-рендеринг.
1 ответ
Не используя это уравнение, свет горит вечно.
plot 1.0 / (1+5*(x*x))
на wolframalpha.com:
[РЕДАКТИРОВАТЬ] Поскольку значения светлых цветов могут превышать единицу, следующие 1/255 необходимо будет разделить на наибольший компонент RGB.
Вам понадобится порог. Предполагая, что ваш монитор не может отображать ничего более тусклого, чем 1/255 перед черным,
solve 1.0 / (1+f*(x*x)) = 1/255, x
куда f
твой falloff
, За f = 5
эффективный радиус ~7.
Вы могли бы, вероятно, увеличить 1/255
немного в зависимости от вашего приложения, и вы можете не заметить ничего плохого. В качестве альтернативы, выдумайте искусственную функцию спада, которая не бесконечна:)
Эта проблема также обсуждается здесь: https://gamedev.stackexchange.com/questions/51291/deferred-rendering-and-point-light-radius, где функция настроена на достижение нуля на пороге.