我正在使用LWJGL3处理游戏引擎,其中所有对象都是点精灵。它使用正交相机,我写了一个顶点着色器,计算每个精灵的3D位置(这也会导致鱼眼镜头效果)。我计算到相机的距离,并使用该值作为每个点精灵的深度值。这些精灵的数据存储在VBO中的16x16块中。
我遇到的问题是精灵并不总是从前到后渲染。当远离原点时,深度测试按预期工作,但是当从原点方向看时,精灵会从后向前渲染,从而导致性能下降。
这看起来似乎没有启用深度测试,但是当我禁用深度测试时,后面的精灵被绘制在前面的精灵之上,所以情况并非如此。
这里是完整的顶点着色器:
#version 330 core
#define M_PI 3.1415926535897932384626433832795
uniform mat4 camRotMat; // Virtual camera rotation
uniform vec3 camPos; // Virtual camera position
uniform vec2 fov; // Virtual camera field of view
uniform vec2 screen; // Screen size (pixels)
in vec3 pos;
out vec4 vColor;
void main() {
// Compute distance and rotated delta position to camera
float dist = distance(pos, camPos);
vec3 dXYZ = (camRotMat * vec4(camPos - pos, 0)).xyz;
// Compute angles of this 3D position relative center of camera FOV
// Distance is never negative, so negate it manually when behind camera
vec2 rla = vec2(atan(dXYZ.x, length(dXYZ.yz)),
atan(dXYZ.z, length(dXYZ.xy) * sign(-dXYZ.y)));
// Find sprite size and coordinates of the center on the screen
float size = screen.y / dist * 2; // Sprites become smaller based on their distance
vec2 px = -rla / fov * 2; // Find pixel position on screen of this object
// Output
vColor = vec4((1 - (dist * dist) / (64 * 64)) + 0.5); // Brightness
gl_Position = vec4(px, dist / 1000, 1.0); // Position on the screen
gl_PointSize = size; // Sprite size
}
在第一张图片中,您可以看到游戏的正常外观。在第二个中,我禁用了alpha测试,因此您可以看到精灵从前到后呈现。但是在第三张图片中,当朝着原点的方向看时,精灵被拉回到前面。
编辑: 我几乎100%确定深度值设置正确。精灵的大小与距离直接相关,并且在移动时它们可以正确调整大小。当距离较低时,我还将颜色设置得更亮,这可以按预期工作。
我还设置了以下标志(并且当然清除了帧和深度缓冲区):
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
EDIT2: 这是旋转时的样子的全貌:https://i.imgur.com/v4iWe9p.gifv
EDIT3: 我想我误解了深度测试的工作原理。这是一段关于如何随时间绘制精灵的视频:https://www.youtube.com/watch?v=KgORzkM9U2w 这解释了最初的问题,所以现在我只需要找到一种方法来根据相机的旋转以不同的顺序渲染它们。