所以我的问题有点奇怪,我希望我能得到一些帮助。
在我移植的游戏中,它使用布尔数组来确定图块是否被照亮。
在原始源代码中,游戏会在未照亮/玩家视野之外的区域应用抖动图案:
我最初想做的是将布尔数组直接发送到着色器,但在了解到这不容易管理后,我想我会采取另一种方法,即将灯光值转换为一对整数通过以下功能:
public void rebuildLightmap() {
boolean[] storage = new boolean[64];
for(int z=0;z<SIZE;z++) {
for(int x=0;x<SIZE;x++) {
storage[z*SIZE+x]=this.dungeonFloor.isLit(x+(xPos * SIZE), z+(zPos * SIZE));
}
}
for(int i=0;i<2;i++) {
lightMap[i]=0;
int len = 31;
for(int j=0;j<32;j++) {
if(storage[i * 32+j]) {
lightMap[i] += 1<<len--;
}
}
}
}
从那里开始,我计划将光照贴图整数作为一对整数发送到着色器,然后使用按位运算来检查相关位并相应地对图块进行着色。
但是,当我尝试编译着色器时,它告诉我“&”操作数在 glsl 中未定义整数,这与我在 Shadertoy 上看到的以及 OpenGL 社区中其他人讨论的一些示例背道而驰。
我的问题是如何在 GLSL 着色器中执行按位 AND 运算?我正在使用版本 400 Core,如果有帮助的话。
作为一些附加信息,我使用基于块的系统来渲染图块,其中地图被分解为 8x8 的图块部分并加载到帧缓冲区中,如下所示:
我的主要尝试是用一对整数构建光照贴图,然后将整数传递给 GLSL,我尝试执行以下操作:
我不熟悉 LWJGL (甚至你的程序)的复杂性,但我认为算法的关键是这样的:
#extension GL_EXT_gpu_shader4 : enable
void rebuildLightmap() {
int[] storage = new int[2];
for(int z=0; z<SIZE; z++) {
for(int x=0;x<SIZE;x++) {
int index = z*SIZE+x;
int result = this.dungeonFloor.isLit(x+(xPos * SIZE), z+(zPos * SIZE));
storage[index & 31] ^= result << (index & 31);
}
}
// Mostly unchanged
for(int i=0;i<2;i++) {
lightMap[i]=0;
int len = 31;
for(int j=0;j<32;j++) {
if(storage[(i<<5)+j]) {
lightMap[i] += 1<<len--;
}
}
}
}
您只需确保
dungeonFloor.isLit
返回 0 或 1。
技巧是不是发送完整的 64 位整数,而是发送两个 32 位整数,并从之前索引的位置,执行模数,选择 64 个整数位的下限或上限范围。