Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 一种二维阴影算法_Algorithm_Flash_2d_Shadow - Fatal编程技术网

Algorithm 一种二维阴影算法

Algorithm 一种二维阴影算法,algorithm,flash,2d,shadow,Algorithm,Flash,2d,Shadow,我正计划制作一款游戏,将光(和阴影)作为游戏的一部分,但是我想不出一个有效的算法来实现它们,我相信有一个优雅的解决方案 白色区域由灯光直接照亮,浅灰色由直接照亮的墙壁照亮,深灰色为黑暗 我希望以有效的方式找到这些领域。(实时,光线可以移动) 尽管不现实,但这是我能想到的解决问题的最简单方法,任何其他包括直射光和反射光的实现都是受欢迎的 我的第一次尝试是从光线到屏幕的周长画一条线,然后找到它们相交的第一面墙。但对墙的每个照明部分重复此算法以标记“环境”光是不可行的 另外请注意,游戏是Flash

我正计划制作一款游戏,将光(和阴影)作为游戏的一部分,但是我想不出一个有效的算法来实现它们,我相信有一个优雅的解决方案

白色区域由灯光直接照亮,浅灰色由直接照亮的墙壁照亮,深灰色为黑暗

我希望以有效的方式找到这些领域。(实时,光线可以移动)

尽管不现实,但这是我能想到的解决问题的最简单方法,任何其他包括直射光和反射光的实现都是受欢迎的

我的第一次尝试是从光线到屏幕的周长画一条线,然后找到它们相交的第一面墙。但对墙的每个照明部分重复此算法以标记“环境”光是不可行的


另外请注意,游戏是Flash的,所以我认为我不能使用gpu。

你不需要画所有的光线,只需要画重要的光线。例如,对于一个点光源和一条线,只需求解两个交点


对于反射照明,可以从强度为n的点光源开始,然后每次该光源与墙相交时,将墙拆分为较小的分段,并在照明分段上添加强度为n-1的线性光源。你可以随意多次这样做。

受Ryan回答的启发

在二维栅格中,将屏幕的每个点标记为亮起。然后,对于屏幕上的每一面墙(按与点的接近程度排序),在它们后面画一个阴影:在进入下一面墙之前,首先检查它的哪些部分亮着,哪些没有亮着,以免画两次阴影。标记为下一步绘制阴影的所有墙,因为这些墙可能是照亮的墙。(我们应该在下一部分之前再次检查)

对于每个照明线段(墙),首先检查是否有任何墙与该线段相交。对于每个交叉点,在交叉点处将照明线段拆分为2

对于每个线段的端点,在临时阵列中重复第一部分,并在末尾将所有照明点添加到最终阵列中

第一部分应检查屏幕上的所有点和墙上的所有点一次。所以O(面积+墙的长度),根据场景的复杂程度(墙的数量和有趣的部分),第二部分应用第一部分大约20次


这可能会实时工作,但是请确保在灯光不移动的情况下存储照明区域。

并且您想知道这些GPU在花时间做什么……您是否考虑过使用能够访问GPU的专有库来高效地执行此操作?我一直想知道阴影如何在游戏中使我的计算机如此缓慢。现在我我知道。很抱歉我没有提到,我也计划在Flash中做这个。你可能想在你的问题中添加一个
Flash
标记。这里有一个。@PinnyM:只有当有很多多边形时才是这样。在2D中,它更简单,特别是只有很少的线条。这远没有3D照明那么复杂。据我所知,我可以构造多边形在我用阴影填充的每一行后面。然而,这意味着我必须为每一行填充大约1/4的屏幕区域。假设20行,这意味着5个屏幕区域。再次假设400*600屏幕。这意味着至少400*600*5个操作。如果我有200个墙壁初始照明点,那么我将无法运行这是在合理的时间内完成的。作为比较,我的算法将涉及到向周界的每个点绘制长度为2-300的线。因此,对于一个光源,2000条线和大约300*2000个操作。如果您按到光源的距离排列墙,则可以通过检查是否还有其他墙来改进算法,以填充屏幕大约一次在构造多边形之前被照亮。“半影”仍然是最大的问题,因为即使填充屏幕200次也太难了。@ CSIZ:一个线状光源的数学比计算两个点光稍微复杂一些。屏幕大小和线光的长度并不重要。线,但是这些问题可以通过首先检查线是否相交来解决。我认为,与其先从明亮的房间开始,然后绘制灰色,不如先假设所有东西都是暗的,然后绘制照明部分。这将改善情况,您仍然需要绘制一些阴影,但总体而言,这会更容易呃。