渲染和眼空间未对准会导致光线投射不精确

时间:2019-04-28 09:23:35

标签: java opengl projection-matrix

一段时间以来,我一直在从事类似Minecraft的体素游戏的工作,并决定通过射线投射实现块放置和破坏。但是,我意识到,当非常靠近一个块站立时,该块会绕自身旋转,而不是围绕相机(或观察平面)旋转。眼睛位置偏离大约。在任何给定轴上为0.5。我非常确定这就是为什么我的光线投射无法精确运行的原因,我认为问题出在投影上。

我尝试使用不同的投影方法,但是它们都具有相同的结果。创建视图矩阵时调整相机的位置也不起作用,并导致一些奇怪的拉伸和错误的旋转。

我的投影矩阵代码:

public static Matrix4f createProjectionMatrix (float fov, float aspectRatio, float clipNear, float clipFar) {
    float tanHalfFOV = (float)Math.tan(fov/2);
    float zm = clipFar + clipNear;
    float zp = clipFar - clipNear;

    Matrix4f matrix = new Matrix4f();
    matrix.m00(1.0f / (tanHalfFOV * aspectRatio));
    matrix.m11(1.0f / tanHalfFOV);
    matrix.m22(-zm / zp);
    matrix.m32(-2.0f * clipNear * clipFar / zp);
    matrix.m23(-1.0f);

    return matrix;
}

视图矩阵代码:

public static Matrix4f getViewMatrix () {
    return new Matrix4f().rotateXYZ(rotation).translate(-position.x, -position.y, -position.z);
}

着色器代码:

#version 400 core

in vec3 worldCoords;
in vec2 textureCoords;

out vec2 passTextureCoords;

uniform mat4 projViewMatrix;

void main () {
    gl_Position = projViewMatrix * vec4(worldCoords, 1.0);

    passTextureCoords = textureCoords;
}

渲染代码:

public static void render (ChunkMesh cm) {
    Renderable model = cm.getModel();

    Shaders.CHUNK_MESH_SHADER.activate();
    Shaders.CHUNK_MESH_SHADER.loadToUniform("projViewMatrix", Display.getProjectionMatrix().mul(Camera.getViewMatrix(), new Matrix4f()));

    GL30.glBindVertexArray(model.vaoID);
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);

    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, BlockTexture.TEXTURE.textureID);

    GL11.glDrawElements(GL11.GL_TRIANGLES, model.vertexCount, GL11.GL_UNSIGNED_INT, 0l);

    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL30.glBindVertexArray(0);

    Shaders.CHUNK_MESH_SHADER.deactivate();
}

在任何给定的轴上,射线投射的效果都很好,但是当面对两个轴之间时,射线投射的原点似乎与屏幕的中心不同。由于我的问题集中在未对准而不是光线投射上(这似乎可行),因此仅在需要时添加代码。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

这是一个有根据的猜测,因为您没有确切指定实际的Matrix4f。但是,假设某些标准约定(如lwjgl的Matrix4f类),构造函数将初始化新矩阵以标识。因此,您需要修改createProjectionMatrix()函数以添加

matrix.m33(0.0);

将最后一个元素显式设置为零,因为没有它,您实际上设置了w_clip = -z_eye + 1,将投影中心移动了1个单位到您认为相机所在的位置。