从强度计算光体积半径

Posted

技术标签:

【中文标题】从强度计算光体积半径【英文标题】:calculate light volume radius from intensity 【发布时间】:2014-11-24 00:17:31 【问题描述】:

我目前在计算延迟渲染器的光体积半径时遇到问题。在低光照强度下,体积大小看起来是正确的,但是当光照强度(以及半径)增加时,光照体积似乎越来越小。

我正在计算光体积半径(在世界空间中),如下所示:

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

所以显然我在搞乱数学。衰减应该是线性的,对吧?但是我现在如何正确计算光照体积的世界比例值?

附:因为我打算使用 HDR 渲染,所以灯光颜色可以超过 (1,1,1)。

【问题讨论】:

线性?不。这是二次方,您可以立即判断,因为它基于距离的平方。 【参考方案1】:

不使用该等式,光永远亮着。

plot 1.0 / (1+5*(x*x)) wolframalpha.com:

[编辑] 由于您的灯光颜色值可以高于 1,因此需要将以下 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,其中函数被调整为在阈值处达到零。

【讨论】:

我现在像这样计算半径:radius = sqrt(colMaxVal*254) / sqrt(LIGHT_CUTTOFF_DEFAULT);,它看起来对我来说是正确的。但现在我有另一个问题:我允许 HDR 的光值高于 1.0 是否正确?有了这个衰减功能,我需要相当高的光照值来点亮更大的区域。我假设要解决这个问题,我必须使用另一个?但这对我来说在物理上看起来很正确...... @C0dR 在这里找到了相关帖子:gamedev.stackexchange.com/questions/21057/…。为了使延迟渲染更有效,您希望保持半径较小,但对于二次衰减,大部分计算仅用于少量添加。出于这个原因,您可能需要更渐进的衰减,添加一个线性组件。

以上是关于从强度计算光体积半径的主要内容,如果未能解决你的问题,请参考以下文章

用C++编程 输入一球半径,求球的体积? (需要编程的详细过程)

实验10-1 圆形体体积计算器 (20分)

[PTA]实验10-1 圆形体体积计算器

[PTA]实验10-1 圆形体体积计算器

python程序设计:输入球体半径r,计算球体的体积和表面积

1068.球的半径和体积