2014-11-24 18 views
0

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

Я расчет радиуса объема света (в мировом пространстве), как это:

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.

+0

Линейный? Нет. Это квадратично, вы можете сразу сказать, потому что оно основано на квадрате расстояния. –

ответ

4

Не используя это уравнение, свет продолжается вечно.

plot 1.0/(1+5*(x*x)) в wolframalpha.com: enter image description here

[EDIT] Поскольку ваши значения цвета света могут пойти выше одного, следующий 1/255 нужно будет разделить наибольшим компонентом RGB.

Вам понадобится порог. Предположим, что ваш монитор ничего диммер, чем 1/255 до черного не может отобразить,

solve 1.0/(1+f*(x*x)) = 1/255, x

enter image description here

Где f ваша falloff. Для f = 5 эффективный радиус ~ 7.

enter image description here

Вы могли бы увеличить 1/255 немного в зависимости от вашего приложения, и вы не могли бы что-нибудь плохо неправильно заметить. В качестве альтернативы, выпустить функцию искусственного спада, которая не бесконечна :)

Эта проблема также обсуждается здесь: https://gamedev.stackexchange.com/questions/51291/deferred-rendering-and-point-light-radius, где функция отрегулирована так, чтобы достигнуть нуля на пороге.

+0

Я вычисляю радиус теперь следующим образом: 'radius = sqrt (colMaxVal * 254)/sqrt (LIGHT_CUTTOFF_DEFAULT);' и это выглядит правильно для меня. Но теперь у меня есть еще один вопрос: я ли я прав, что я допускаю световые значения выше 1.0 для HDR? И с этой функцией ослабления мне нужны довольно высокие значения освещенности, чтобы загорать большие области. Я предполагаю, что для этого я должен использовать другой? Но этот выглядит очень физически корректно для меня ... – C0dR

+1

@ C0dR нашел связанный пост здесь: http://gamedev.stackexchange.com/questions/21057/does-the-linear-attenuation-component-in-lighting-models -Иметь-а-физико-счетчик. Чтобы сделать отсроченный рендеринг эффективным, вы хотите, чтобы радиус был мал, но с квадратичным затуханием большая часть вычислений предназначена для небольших добавок. По этой причине вам может понадобиться более постепенный спад, добавляя линейный компонент. – jozxyqk

Смежные вопросы