C++-动态阴影投射

C++ - Dynamic Shadow Casting

本文关键字:阴影 动态 C++-      更新时间:2023-10-16

我正在为学校做一个游戏项目,遇到了一个照明问题。我读了很多教程和这个主题,但似乎没有一个对我有效。我唯一能产生的有效算法是用光线投射对线条进行粗糙变形(这显然导致了帧速率问题等)。将阴影投影到2D平面上的最佳方法是什么?

如果您使用的是OpenGL之类的东西,那么有很多关于这个主题的教程。如果你正在编写自己的渲染器,你将不得不做更多的工作,尽管同样的原则也适用。

有很多方法可以获得阴影,但很大程度上取决于您的需求和计算能力。我认为最流行/最常见的两种方法是

  1. 光线跟踪阴影
  2. 阴影贴图

光线跟踪阴影在我看来更容易理解和实现。基本上,当对像素进行着色时,会向光源投射光线,其中最大光线长度是到光源的距离。如果光线没有击中任何东西,则要着色的点被认为不在阴影中。如果光线命中的距离小于到灯光的距离,则光线处于阴影中。用通俗的英语来说,你可以把它想象成,如果我的眼睛位于世界上的这个位置,我对光线有直接的视线吗?

这种方法会给你完美的硬边阴影。这是因为光源被认为是无限小的。当您想要柔和的阴影或聚光灯锥角衰减时,它可能会变得稍微复杂一些。

阴影贴图在实时/游戏应用程序中更常用,尽管随着新机器中核心数量的增加,我相信阴影贴图的相关性会越来越低。

这里有一个关于OpenGL中阴影贴图的教程,但这个概念与任何其他渲染系统的概念相同。http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/

简而言之,阴影贴图只是从灯光的角度渲染3D场景,但不是存储场景中对象的颜色,而是存储深度值。然后,稍后从摄影机的角度进行渲染时,将使用阴影贴图作为深度值的查找。从摄影机的视点着色的点需要转换到用于生成阴影贴图(或深度图像)的同一视图/投影矩阵的空间中,这样您就可以知道如果从灯光的视点渲染,着色的像素会在哪里。

阴影贴图往往会占用更多内存,而且通常比光线跟踪更快。光线跟踪几乎不占用任何内存,可以很容易地进行线程处理,但如果场景有很多几何体,则投射光线的速度成本可能会非常昂贵。

添加阴影的方法还有很多,但如果没有更多关于你想要什么的细节,就很难给出方向。例如,如果你只是想在游戏中的角色下面有一个黑暗的区域,你可以使用带有圆形渐变的精灵来伪造阴影。精灵阴影速度极快,但除非你的地板完全平坦,否则看起来就不对劲。如果希望在平面上有精确的阴影,也可以使用投影阴影,基本上是使用光线投射将几何体从灯光位置投影到地板上,并将其渲染为黑色。但同样,这真的取决于你的需求。您可能想更新您的问题,了解有关您的项目的更多细节。