java - 渲染和眼空间错位导致不精确的光线投射
问题描述
我一直在开发类似 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();
}
沿着任何给定的轴,光线投射都表现得非常好,但是当面对两个轴之间时,光线投射看起来就像它的原点与屏幕的中心不同。由于我的问题集中在未对齐而不是光线投射(这似乎有效)上,因此我只会在需要时添加代码。任何帮助表示赞赏!
解决方案
这是一个有根据的猜测,因为您没有准确指定Matrix4f
实际是什么。但是假设有一些标准约定,比如Matrix4f
来自 lwjgl 的类,构造函数会将新矩阵初始化为恒等式。因此,您需要修改您的createProjectionMatrix()
功能以添加
matrix.m33(0.0);
将最后一个元素显式设置为零,因为没有它,您实际上设置了w_clip = -z_eye + 1
,将投影中心移动到您认为相机所在位置的前面 1 个单位。
推荐阅读
- python - Python Pandas中DataFrame的总结和聚合?
- sql - 添加到父子关系中的行而不是列
- javascript - Vue卡片渲染图片两次
- javascript - 如何将已更改为字符串的索引数组的项目保存到变量Javascript中
- google-cloud-platform - 减少 GKE 集群的启动磁盘大小
- snowflake-cloud-data-platform - Snowflake 仓库是否基于 EC2 之类的虚拟机?
- ruby-on-rails - 单选按钮选择的值未在生产中显示
- angular - 不使用自定义事件时,地图无法提供给 Angular Leaflet 侧边栏组件
- javascript - 如何检查元素是否已初始化 jQuery UI 小部件(滑块、日期选择器等)
- azure - Azure ARM:使用访问密钥从存储帐户创建 Linux VM