当前位置: 首页 > 知识库问答 >
问题:

Java中的2D软件照明问题

明松
2023-03-14

我正在用纯Java创建一个2D自上而下的平铺游戏,现在我正在尝试实现一种实现照明的方法。

首先,关于如何渲染的一些细节:有一个screen类处理所有渲染。像素被放入一个int[width*height]数组中,该数组使用buffereImage图形在实际屏幕上绘制。drawImage()

我现在做照明的方法是通过创建第二个int[宽*高]数组来保存所有应该从实际像素中减去的亮度。我试着只使用从0f1f的浮点来表示RGB强度。

例如,环境照明为0.3f。我所做的是一个像素到像素的操作,对于将要绘制的每个像素,其RGB值被分解,减少70%(1f-0.3f),重新组合成单个int,并存储在次要int[width*height]数组中。在将像素传输到BuffereImage时,我减去二级数组中的相应值,得到一个更暗的图像,正如预期的那样。

这是一个使图像变暗的例子,效果很好,问题出现在实际点亮它们时:我给了玩家一个lightRadius和3个light color component floats(RGB)。在渲染播放器时,我还通过执行以下操作渲染辅助阵列内的灯光:

int mask = subtractMask[xx + yy * width];

int mr = (mask >> 16) & 255;
int mg = (mask >> 8) & 255;
int mb = mask & 255;

mr -= (int) (dist * light.r * mr);
mg -= (int) (dist * light.g * mg);
mb -= (int) (dist * light.b * mb);

subtractMask[xx + yy * width] = mr << 16 | mg << 8 | mb;

其中dist是一个从0f1f的数字,它使光线随着与光源的距离而消失,而light. r/g/b是来自播放器的光线的每个组成部分。这段代码所做的基本上是“把从一个像素中取出的一点点光线还给它”。正如你所看到的,mr,mg和mb被做得更小(-=),然后被组合回将从相应像素中减去的数字中,从而使减法的结果更大(更轻)。对于白光,我得到了想要的结果:

当然,这可以通过以下事实来解释:瓷砖的蓝色值非常小,使环境光带走一小部分,并使灯光将这一小部分反射回来(正如你所看到的,最大的影响是在玩家的裤子上,裤子是蓝色的)。我仍然想不出一种方法,可以使照明与像素的亮度无关,并且通过任何方式组合组件(我期望第二张图像的结果是亮度与第一张图像相同,但颜色为蓝色)都看起来很好。那么,我该如何实现这种效果呢?

同样,为了使照明成为圆形,我简单地计算一些光x^2 y^2

共有1个答案

颜昕
2023-03-14

我认为最好的方法是先将环境光和播放器光的值相加,将其钳制到[0…1]范围,然后将像素值相乘。

所以:

环境光:[0.3,0.3,0.3]
玩家光(在某些位置):[0.0,0.0,1.0]
总光:[0.3,0.3,1.0]

原始像素值:[100200100]
输出像素值:[30,60100]

如果你这样做,你也可以有一个静态浮点[]代表每个像素的光量,只有当环境光或播放器光改变时才改变它。然后,你不需要计算每一帧的光照,只需在整个图像上应用一次光照。

 类似资料:
  • 我已经和LWJGL一起开发这个游戏几个星期了。自从我增加了跳跃的能力后,向上的碰撞给我带来了很多问题。 这个游戏是一个基于2D瓷砖的侧翻游戏。总的来说,除了玩家跳跃时,碰撞几乎是完美的。起初我想“哦,也许我只需要改变跳跃机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生这种情况。 现在,对于实际问题本身:如果玩家在传递某个x坐标时跳转,他们将通过平铺,并测试顶部碰撞返回false。 这是整个

  • 问题内容: 在Java中,为什么每个类都必须声明其所属的包。我的意思是,已经使用文件系统的文件夹结构描述/强制使用了软件包hierachy。在我看来,该行: 作为每个类的第一行,都是多余的信息。但我很确定有充分的理由让它存在。 问题答案: 我的意思是,已经使用文件系统的文件夹结构描述/强制使用了软件包hierachy。 不必要。虽然以这种方式组织代码当然是一个好主意,但这不是必需的。还请记住,源代

  • 本章介绍如何使用JOGL将光照效果应用于对象。 要设置光照,最初使用glEnable()方法启用光照。 然后使用GLLightingFunc接口的GLLightingFunc glLightfv(int light, int pname, float[] params, int params_offset)方法为GLLightingFunc 。 该方法有四个参数。 下表描述了gllightfv()

  • 软件版本号对照表 软件名称 版本 Red Hat JBoss Data Virtualization 6.3.0 + Patches Red Hat JBoss Developer Studio 10.4.0 Red Hat JBoss Enterprise Application Platform 6.4.0

  • 1.数据库100w数据插入 2.Java并发框架 3.java线程的实现,区别 4.注解的实现,原理 5.Java类加载器

  • 问题内容: 我正在使用Eclipse,并且有一段时间没有使用Java了。但是,我可以在命令行上编译我的代码,并生成必要的文件。在Eclipse中,它抱怨。这是什么意思,我该如何解决? 样例代码: 我的项目的名称是。 问题答案: Eclipse希望声明的包与目录层次结构匹配-因此,它希望Java文件位于源根目录下的“ Devices”目录中。目前,该文件似乎直接位于您的源根目录中。因此,创建适当的目