opengl - 漫射光/阴影

标签 opengl glsl game-engine shadow lighting

我刚刚在引擎中安装了照明系统。在以下屏幕截图中,您可以看到一个亮起的指示灯(黄色方框):

考虑到在照亮场景的光线之上,它还实现了FOV,该FOV将遮挡视场之外的任何物体。这就是为什么阴影的左侧部分看起来如此偏离的原因。

如您所见,光线的阴影非常“硬”,因为它们甚至无法照亮其直接作用范围之外的区域。
为了使灯光看起来更好,我对它们应用了滤镜,这在很大程度上限制了要照明的范围,并且还在此范围内稍微照亮了区域:

在黄色大圆圈中,即使没有直射光,您也可以看到该区域的照明方式。

然而,该解决方案具有一些不希望的副作用。从以下屏幕截图中可以看到,即使一点光都没有到达某个区域,但如果它太靠近光源,它也会被照亮:

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

1)首先,我将灯光范围内的结构取下。

现在,我正在处理顶点,因为它们定义了阴影转换项的区域:

2)然后,对于这些对象中的每一个,我分别计算它们转换的阴影:



它们转换的阴影由CPU通过计算 body 每个顶点的投影来完成。

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

我发现的问题是,要制造这种弥漫的阴影效果,我需要最终的阴影。如果我要在步骤2)中计算扩散阴影,则在实体B和C之间会出现光隙。

但是,如果我在步骤3中将阴影扩散,那么我将不再拥有顶点信息,因为我拥有的所有信息都是将3个局部纹理加到一个最终纹理中。

那么,有没有实现这一目标的方法呢?我的第一个想法是将变化传递给fragmentshader以计算有多少光进入暗区,但是由于我将在没有顶点信息的最终阴影上处理此信息,因此我完全不知道该做什么。我应该使用的方法。

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

这是我现在所拥有以及我所渴望的一个示例:
我所拥有的:具有光半径的普通照明(这会导致光穿过墙壁。

我想要的是:阴影离光的结束点越远,强度就越高。

最佳答案

我认为,无论您做什么,都将不得不为无法直接看到原始光源的场景区域计算不同的光衰减。我不确定您是如何实际将阴影体积应用于场景的,但是在生成阴影体积时(例如,它们是来自墙还是来自线条),您可能可以执行类似对边缘进行分类的操作从光到角?),并相应地对待它们。

简而言之,我认为您不可以使用任何针对着色器的巧妙技巧来解决此问题。这是您使用的算法的局限性,因此您需要改进算法,以考虑阴影体积中边缘的不同性质。

- - 编辑 - -

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

要创建第二个阴影贴图,我想您会想做一些事情,例如为在拐角处发出的光线所产生的边缘添加固定角度。

-编辑2-

我认为您可以通过获取阴影区域和场景外框的轮廓来解决对象B和C之间的间隙问题。因此,对于每个阴影区域,您都将找到与外框相交的两个最外点,然后将它们之间的所有线段都扔掉,并用框的该部分替换。我觉得我应该能够为该算法命名,但此刻我却逃脱了……

原始场景:

各个“硬”阴影:

现在将阴影结合在一起:

最后,在阴影周围跟踪,并保持框的边缘。您要识别的角是黄色的。在跟踪阴影的周围时,您需要跨框的边缘进行切割,直到到达对角为止。这不是最容易编写的东西,但是如果您已经走了这么远,我想您可以弄清楚:)

另外,简单地考虑被照亮的区域可能会更容易。例如,您可以做一些事情,例如将场景框和联合的阴影区域区分开来。这通常会为您提供多个多边形。丢弃除了包含光的那个以外的所有东西,因为其余的都是虚假的空隙。

关于opengl - 漫射光/阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22510775/

相关文章:

python - 使用 Pyglet/OpenGL 绘制具有自定义厚度的线条?

c++ - 在 OpenGL 中使用不同的着色器程序?

unity-game-engine - 在 Unity3D 中创建 Controller 管理器

javascript - 移相器 : add physics to graphic objects

algorithm - 寻找范围内的东西

c - GLFW GLSL OPENGL问题

c++ - GLM 在声明后定义一个 vec3

c - 如何实现一个函数以在其本地范围之外使用?

c++ - 球体的 OpenGL UV 贴图(有接缝)

algorithm - 与第一个生命点已知的射线盒相交