Рассчитать радиус объема света от интенсивности

В настоящее время у меня есть проблема с вычислением радиуса объема света для отложенного рендеринга. При низкой интенсивности света объемный объем выглядит правильным, но когда интенсивность света (и, следовательно, радиус) увеличивается, объем света становится все более и более малым.

Я рассчитываю радиус объема света (в мировом пространстве) следующим образом:

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, где функция настроена на достижение нуля на пороге.

Другие вопросы по тегам