有没有一种简单的方法在OpenGL中获得阴影?

16

我最近编写了一些景观代码,并向场景中添加了一些漫反射光照,但令我失望的是,没有阴影。我在网上寻找了数小时,试图找到在OpenGL中实现阴影的方法,但似乎它们都非常复杂,而且非常适用于它们自己的演示程序。

是否有任何简单的方法来制作阴影?


3
不完全是。阴影不是内置在管道中的,你需要自己生成它们(有许多方法可以做到这一点,每种方法都有其优缺点),然后自己渲染它们。 - GManNickG
OpenGL不会产生阴影,它会将每个点渲染成如果该点和光源之间没有任何障碍物的状态。 - Amir Zadeh
1
除非你想学习图形编程的内部机制,否则你可能想使用图形引擎(如Horde3D)或游戏引擎(Ogre或Irrlicht),而不是纯OpenGL。这将为您节省重新发明轮子(好吧,可能是许多轮子)的时间,并让您直接跳入您想要实现的内容。OpenGL是一个低级API。 - Kos
2个回答

30

不,光栅化在这方面非常差(即使最近的AAA游戏也有明显的阴影伪影),但所有人都习惯了这一点。

解决方案包括(大致从简单/较差到最佳/最难):

  • 没有阴影。只需使用较暗的颜色来考虑遮挡。xNormalBlender
  • 如果您想为角色提供简单的近似阴影,则可以在地面上放置一个简单的平面多边形,并使用透明模糊纹理。例如,查看《塞尔达传说》的屏幕截图。甚至一些最近的游戏仍然使用此方法。
  • Lightmaps。仅适用于静态几何,但光照完美(预计算)。实现相对简单。存在许多工具。
  • Shadow volumes,由Carmack普及。像素精密,相对简单,速度相当慢。适用于少量对象。没有软阴影。
  • Shadow maps。如果您从未制作过任何openGL,则有点难以实现。很难正确操作。像素化阴影。处理大量多边形。不适用于大型世界。
  • 数不胜数的Shadow maps变体。近年来进行了大量研究。当前最佳的是Cascaded Shadow Maps:难度大,仍然难以使其看起来完美,但速度快,可以处理大量多边形和巨大的世界。
  • 射线追踪阴影:这可能是下一代技术。除了一些研究论文外,没有人真正使用它。非常复杂,在动态环境中表现不佳(但在巨大的静态场景中效果不错)。像素精密或软阴影,具体取决于您有多少备用GPU。有几个变体;截至2014年,由于性能原因,还没有出现在任何游戏中

通常的方法是将美观但仅限于静态的方法与动态但效果不太好的方法混合使用。例如,参见我关于灯光贴图阴影映射的教程。


谢谢您的评论,我不知道。消息已相应更新。 - Calvin1602
我只想指出,在虚幻引擎4中,实时阴影并不算是真正的“研究”。你可以自行决定它是否属于下一代技术。 - Bartek Banachewicz
如果您是指UE4中使用的Crassin论文,那么体素仅用于次要“光线”。仍然存在阴影图。 - Calvin1602
嗨,Calvin,非常有用的列表。但是我想问一下,渲染到纹理阴影(http://download.java.net/media/jogl/www/ts1361.pdf)是否也包含在其中之一。这可能是一种过时的技术吗? - elect
@elect 这被称为阴影映射,至少目前仍是最先进的技术之一(其中的变体)。 - Calvin1602
显示剩余2条评论

6

不需要。

我所知道的最简单的方法是使用预生成的阴影纹理,通过多重纹理叠加到地形上。复杂的部分是生成这个纹理,但如果您不使用定向光照,则一个简单的“大模糊点”通常比没有好。


哦,更简单的方法是使用已经内置了它的引擎,但我假设你不仅仅是为别人的引擎构建模型(很好,我也不是)。 - Zooba
不,我不想为别人的引擎构建模型。至于上面的答案,我在哪里可以找到如何做到这一点? - user354346
任何有关多重纹理的基础介绍都会涵盖它。诀窍在于将纹理设置为包裹(带有透明边缘),并使用地形上的UV参数来定位它。或者,您可以为阴影制作额外的表面,在平坦的表面上很容易,但在地形上需要更多的操作... - Zooba
如果你想要地形阴影,最简单的方法是将高度图(假设黑色是最低点)转换为纹理并应用于整个地形。我之前的回答是从“为角色提供阴影”角度出发的,而不是添加地形阴影。 - Zooba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接