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

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

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

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)));

Так что, очевидно, я возился с математикой. Затухание должно быть линейным, верно? Но как мне теперь правильно рассчитать значение мирового масштаба для объема света?

P.S. цвет света может выходить за пределы (1,1,1), так как я планирую использовать HDR-рендеринг.


person C0dR    schedule 24.11.2014    source источник
comment
Линейный? Нет. Это квадратичная величина, вы сразу можете сказать, потому что она основана на квадрате расстояния.   -  person Andon M. Coleman    schedule 24.11.2014


Ответы (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, где функция настроена так, чтобы достичь нуля на пороге.

person jozxyqk    schedule 24.11.2014
comment
Теперь я вычисляю радиус так: radius = sqrt(colMaxVal*254) / sqrt(LIGHT_CUTTOFF_DEFAULT); и мне кажется, что это правильно. Но теперь у меня другой вопрос: правильно ли я понимаю, что допускаю значения освещенности выше 1,0 для HDR? И с этой функцией затухания мне нужны довольно высокие значения освещенности, чтобы осветить большие площади. Я полагаю, чтобы решить эту проблему, я должен использовать другой? Но этот выглядит довольно физически правильным для меня... - person C0dR; 24.11.2014
comment
@C0dR нашел связанный пост здесь: " title="имеет ли компонент линейного затухания в моделях освещения физический счетчик">gamedev.stackexchange.com/questions/21057/. Чтобы сделать отложенный рендеринг эффективным, вы хотите, чтобы радиус был небольшим, но с квадратичным затуханием большая часть вычислений выполняется только для небольших дополнений. По этой причине вам может понадобиться более плавный спад, добавив линейный компонент. - person jozxyqk; 24.11.2014