我正在为我正在编写的Java2D等距游戏编写一些照明代码 - 我找到了一些我想尝试实现的算法 - 其中一个我在这里找到:
问题是这种算法需要一些最佳的像素着色效果,而我还没有找到通过Java2D实现的方法。最好是某种方法通过图形硬件,但如果不可能 - 至少是一种在软件中快速达到同样效果的方法。
如果那是不可能的,有人可以指导我使用Java2D的更优化算法吗?我考虑过每瓦片照明 - 但我发现drawPolygon方法不是硬件加速的,因此执行速度非常慢。
我想尝试避免本机依赖项或小程序中提升权限的要求。
由于
答案 0 :(得分:2)
自从我发布这个问题以来,我做了很多研究 - 有很多选择,JavaFX确实打算(在以后的版本中)为感兴趣的人提供自己的着色器语言。还有一个允许您将自己的着色器加载到GPU上的LWJGL。
然而,如果您陷入Java2D(就像我一样),仍然可以在等距游戏中实现照明,这只是一个尴尬的问题。因为你无法在每像素级别上执行灯光着色。
外观如何:
我已经实现了(高度抛光 - 经过一些抛光后,我可以向你保证它看起来很棒)投射阴影的效果,对光照贴图进行深度排序,以及在不降低帧速率的情况下应用光照。以下是它的外观:
你会在这个屏幕上看到一个漫射光(没有阴影但是这一步我说的相对容易与到达那里的步骤相比)投射阴影 - 实体背后的区域在光线的范围内阻挡光线通过 BUT 的最大下降被遮蔽为环境光,但实际上这个区域被传递给灯光呈现常规地考虑已发生的阻塞量,以便光线可以施加更漂亮的梯度(或某种褪色效果)。
漫反射光照的当前实现只是简单地将遮挡区域渲染为环境颜色,并将非遮挡区域渲染为光的颜色 - 显然,尽管您已经进一步应用了褪色效果光(执行的那部分我还没有完成 - 但正如我所说的那样相对容易。)
我是怎么做到的: 我不保证这是最优化的方法,但对于那些感兴趣的人:
基本上,这种效果是通过使用大量的Java形状操作来实现的 - 使用VolatileImage可以加速光照贴图的渲染。
生成光照贴图时,渲染例程执行以下操作:
创建一个Area对象,其中包含一个覆盖的Rectangle 整个屏幕。此区域将包含您的环境 照明。
然后在灯光中反复询问他们的情况 如果路上没有障碍物,那么光铸区就会出现。
它接受此区域对象并在世界中搜索Actors \ Tiles 包含在该区域内的灯光将投射在其中。
对于发现在光线投射区域遮挡视线的每块瓷砖,它将计算光源位置和障碍物的差异。 位置(基本上创建一个指向 AT 的向量 来自光源的阻碍 - 这是你想投射阴影的方向)这个指向矢量(在世界上 空间)需要转换为屏幕空间。
一旦完成,就会采取垂直于该向量的方法 标准化。这基本上为您提供了一条可以旅行的路线 通过乘以任何给定的长度来向下行进给定的方向。这个向量是 垂直于你想要投射阴影的方向。
几乎完成后,您构建一个由四个点组成的多边形。 前两个点位于屏幕坐标的基础上 你的障碍的中心点。要得到第一点,你想要 向上移动你的垂直向量(以5计算)的数量 你的瓷砖高度的一半[这是相对准确的 近似虽然我认为这部分算法略有不同 不正确 - 但它没有明显的视觉效果衰减] - 然后当然增加了障碍物的起源。得到的 第二,你做同样的事情,而是往下走。
两点的其余部分以完全相同的方式计算 - 只有这些点需要朝向方向向外投射 你的阴影投影向量是在4中计算出来的。你可以选择任意大量投射向外投射 - 只要它至少到达你光线投射区域之外(所以如果你只是想要做它愚蠢地将你的阴影投影向量乘以因子10,你应该是安全的)
从刚构建的这个多边形构建一个区域,然后 调用" intersect"将你的光照区域作为第一个方法 参数 - 这将确保您的阴影区域无法到达 在灯光投射区域的范围之外。
从你的光线中减去你所构造的阴影区域 以上。此时你现在有两个区域 - 区域 灯光投射通畅,光线投射的区域 阻碍 - 如果你的演员有能见度障碍因素 您曾经确定某个特定演员正在阻挠 视图 - 你也有它阻碍视图的等级 您可以稍后在绘制光效时进行应用(这将允许您在更暗的\更明亮的阴影之间进行选择,具体取决于遮挡的光线数量
减去您在(1)中构建的环境光区域 光线区域和遮挡的光线区域使您无法应用 环境光线到照明效果将接管的区域 并渲染成
现在您需要将光照贴图与深度缓冲世界的渲染例程合并
既然您已经渲染了光照贴图并且它包含在易变图像中,您需要将其投入到您的世界渲染例程和深度排序算法中。由于后缓冲区和光照贴图都是易失性图像,因此在世界范围内渲染光照贴图是相对最佳的。
你需要构建一个多边形,它本质上是一个条带,包含你的世界瓷砖的垂直条纹将被渲染到的内容(看看我的屏幕截图,你会看到一系列细对角线分隔这些条带这些条是我所指的。您可以逐条渲染此光照贴图的某些部分(在您渲染该条带中的最后一个图块后将其渲染到条带上 - 显然 - 必须在上应用光照贴图地图)。您可以使用相同的图像映射,只需将该条带用作图形的剪辑 - 您需要在每个条带渲染时将该条带多边形向下转换。
无论如何,就像我说的那样,我并不保证这是最优化的方式 - 但到目前为止它对我来说还是很好。 光照贴图应用于p