漫反射光/阴影

时间:2014-03-19 15:33:43

标签: opengl glsl game-engine shadow lighting

我刚刚在我的引擎中实现了一个灯光系统。在下面的屏幕截图中,您可以看到一个灯光(黄色方块):

1 考虑到在照亮场景的光线之上,它还实现了一个FOV,它会遮挡你视野之外的任何东西。这就是为什么阴影的左侧部分似乎如此偏离。

正如你所看到的那样,光线的阴影非常“坚硬”,因为它们甚至无法照亮其直接范围之外的一个区域。 为了使灯光看起来更好,我对它们应用了一个过滤器,它几乎限制了要照明的范围,并且在该限制范围内略微照亮了该区域:

2

在黄色的大圆圈中,即使没有直射光照射,也能看到该区域是如何被照亮的。

然而,该解决方案带来一些不希望的副作用。正如您在下面的屏幕截图中看到的那样,即使没有光到达某个区域,如果它太靠近光源,它也会被点亮:

10

我想知道是否有任何方法可以通过正确使用着色器来实现我想要做的事情。 我遇到的主要问题来自于我如何绘制这些阴影。

1)首先,我将结构放在光线的范围内。

此时,我正在使用顶点,因为它们定义了阴影投射项的区域: 3

2)然后,对于每个这些对象,我计算它们单独投射的阴影: 4

5

6 它们投射的阴影由CPU完成,通过计算身体每个顶点的投影。

3)然后GPU将这些形状绘制成纹理以构成最终的阴影:

7

我发现的问题是制作这种漫反射阴影效果,我需要最后的阴影。如果我在步骤2)中计算漫射阴影,则在固体B和C之间会出现光隙。

但如果我在第3步中分散阴影,我就不再有顶点信息,因为我所拥有的所有信息都是在一个最终纹理中加起来的3个局部纹理。

那么,无论如何要实现这一目标吗?我的第一个想法是将变量传递给碎片器以计算有多少光进入暗区,但由于我将在最终阴影上处理此信息,因为它没有顶点信息,我完全迷失了什么我应该用这个做法。

我对这种方法可能完全错误,因为我对着色器的使用经验非常有限。

这是我现在所拥有的一个例子,以及我想要的东西: 我拥有:具有光半径的明亮照明(使光线穿过墙壁。 7

我想要的是:距离光线结束的距离越远,阴影越强烈。 7

1 个答案:

答案 0 :(得分:1)

我认为无论你做什么,你都必须以不同方式计算不能直接看到原始光源的场景区域的光线衰减。我不确定你是如何将阴影体积应用到场景中的,但是你可以做一些像生成阴影体积那样对边缘进行分类的事情(即它们来自墙壁还是线条从灯光到角落?),并相应地对待它们。

简而言之,我认为没有任何聪明的着色器特定技巧可以解决这个问题。这是您正在使用的算法的限制,因此您需要改进算法以考虑阴影体中边缘的不同性质。

---编辑---

好的我认为你最好的选择是创建两个阴影卷(或者说是阴影区域,因为我们在2D工作)。一个将与您现在完全一样,另一个将更小 - 您将要排除处于“软”阴影区域。然后,您的片段着色器中将有三个类别:总阴影,柔和阴影和未阴影。

要创建第二个阴影贴图,我想你会想做一些事情,比如在角落周围的光线所创造的边缘添加一个固定的角​​度。

---编辑#2 ---

我认为你可以通过拍摄阴影区域和场景外框的轮廓来解决对象B和C之间的差距问题。因此,对于每个阴影区域,您会找到与外框相交的两个最外面的点,然后扔掉其间的所有线段,并将其替换为框的该部分。我觉得我应该可以命​​名那个算法,但它现在让我逃脱了......

原始场景: Original scene

个人“硬”阴影: Individual "hard" shadows

现在将阴影结合在一起: Union

最后,在阴影周围追踪,保持在盒子的边缘。您要识别的角落是黄色的角落。当您在阴影的周边进行追踪时,您希望切割框的边缘,直到到达对角。编码并不是最简单的事情,但如果你已经做到这一点,我认为你可以搞清楚:)

Silhouette

或者,简单地考虑点亮区域可能更容易。例如,你可以做一些事情,比如拍摄场景框和联合阴影区域的区别。这通常会给你多个多边形;丢弃除了包含光线的一切以外的所有东西,因为其余的都是虚假的间隙。