【问题标题】:2D light diffuse map artefact2D 光漫反射贴图伪影
【发布时间】:2016-12-18 03:21:46
【问题描述】:

我正在尝试在基于 libGDX 的游戏上实现一个简单的 2D 光引擎。这个想法是在没有着色器的情况下创建这个光引擎。我暂时不打算渲染任何阴影。 我已经设法用三角形和渐变渲染了一个光照贴图,但问题是当多个光源重叠时,我得到了一些像这张图片中的伪影:

黄色光源与其他光源重叠时会产生深色边框。

我正在使用以下混合函数来渲染灯光:

Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE);

有没有办法去掉这个黑边?

渐变从黄色变为黑色,完全不透明。因为GL_ONE 应该是加色的,所以颜色应该只会变亮吧?

更新 1:

使用 Nico Schertler 解释的着色器肯定更好,但仍有一些参数我不确定。

这是我想出的片段着色器

void main() {
  float intensity = 0.02;
  vec2 pos = vPosition;
  float dist = distance(pos, u_origin) / u_radius;
  vec4 color = vec4(intensity * (vColor.rgb / ((dist * dist) + 0.01)), 1);
  gl_FragColor = color;
}

问题是我不确定常量intensity = 0.020.01 我已添加到函数中以使其看起来不错。此外,半径变量现在是屏幕高度和宽度之间的最大值。

更新 2:

我最终选择了以下等式:

void main() {
  float dist = distance(vPosition, u_origin) / u_radius;
  vec4 color = vec4((vColor.rgb) / (pow(dist, 2) + 0.01), vColor.a);

  gl_FragColor = color;
}

然后结合基于相同方程的遮挡贴图(使未照亮的地方变暗)。这是最终输出:

【问题讨论】:

  • 那个较暗的带是一种错觉。欢迎您使用任何图形编辑器检查这些值,看看它们是否变暗 :) 目前看来您没有使用 sRGB 进行渲染,但您应该这样做。还有其他的东西,比如二次衰减,可能会掩盖这一点。

标签: java opengl libgdx light


【解决方案1】:

这在很大程度上取决于你如何喷灯。

例如如果您使用一些截断的二次函数作为灯光的亮度(相对于与中心的距离),即类似的东西:

如果你添加两个灯,你会得到这个配置文件:

在此配置文件中,您会看到明显的不连续性。这种不连续性的原因是原始函数的截断。因此,您的图像中很可能存在任何形式的截断光函数(无论是二次光函数、线性光函数还是其他),这会导致两个光相交处的明亮区域。

那么如何解决呢?物理上正确的光分布随二次距离衰减(在 2D 中,您也可以主张线性衰减),x 是与光源的距离:

light = factor / x^2

这个函数有两个问题。首先,它没有得到紧凑的支持。这意味着您必须绘制一个无限大的 splat(或至少与屏幕一样大)。这可能不是什么大问题。一旦它变得非常小,您也可以将其切断。第二个问题更严重。如果x 变为0(即您直接在光的位置上),则无法计算该值(它趋于无穷大,因为所有光能都集中在一个没有区域的点上)。所以这真的取决于你想用光照贴图做什么。当然,你可以用类似于

的方式进行正则化
light = factor / ((x)^2 + epsilon)

,其中epsilon 是一个非常小的数字。如果您的场景是从上方观看的,那么这个 epsilon 可能是地面上的灯光高度(平方)。然后,您将获得如下配置文件:

瞧,没有间断。但是您很可能需要一个片段着色器来实现这一点。

如果您不关心物理正确性,高斯 splat 也可能会产生漂亮的结果:

light = factor * exp(-x^2 / variance)

【讨论】:

  • 我想我不得不使用一些着色器来实现这一点,我将尝试使用网格和着色器,看看它是否看起来更好
  • 我已经尝试使用您给我的功能(请参阅我的更新),但您能解释一下 factorvarianceespilon 应用于我的参数 radiusdistance。谢谢
  • factor 只是一些缩放,通常与光的强度相关。 variance 是高斯方差,它指定了光线的聚焦程度。您应该尝试一些参数。在radius^2/4radius^2/9 范围内的东西应该会产生好的结果。 epsilon 是任意数字。正如我所提到的,您可以将其设置为灯光在地面上的虚拟高度。它还影响亮度下降的幅度。我想,我在示例中使用了epsilon=1
猜你喜欢
  • 2014-04-25
  • 2017-09-04
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多