【问题标题】:C++ - Dynamic Shadow CastingC++ - 动态阴影投射
【发布时间】:2014-02-28 01:37:19
【问题描述】:

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

【问题讨论】:

    标签: c++ algorithm shadow


    【解决方案1】:

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

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您抽出宝贵时间为我写出来!我正在使用 SFML 进行渲染,但我仍会查看您向我展示的教程。我应该把这个问题提出来,但我正在寻找光照贴图上的主要投影点(有点像this)
    • 我自己刚刚开始使用 SFML 来处理窗口、事件、声音和网络的东西。我很惊讶没有任何关于阴影贴图的教程。至少,我没有通过快速网络搜索找到任何东西。虽然,SFML 在后台使用 OpenGL,但您应该能够在 SFML 命令之间插入自己的 OpenGL 命令。阴影贴图的棘手部分是您需要一个屏幕外帧缓冲区来存储深度图像,并且有几种方法可以处理它。如果您的阴影不会移动,我会查看光照贴图(将光照烘焙到纹理中)
    • 是的,我已经 Google 无情地试图在上面找到任何东西。我正在制作一个 roguelike 地牢爬行者,所以我的阴影很可能需要是动态的。
    • 最终你可能会想要立方体贴图阴影,这样你就可以拥有手电筒的灯光效果。基本上是一样的,但是你需要为立方体的每一面渲染阴影贴图,你需要从中投射阴影。这是我知道做点光阴影的唯一方法。您可以在 Unity 中轻松完成所有这些操作,但不确定这是否会违反您所学课程的规则。我还猜想你的课程不需要阴影,因为他们没有教你怎么做;)可能想要专注于游戏/设计,然后担心照明/效果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2016-06-21
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多