Graphics Vulkan右手坐标系变为左手坐标系 问题:

Graphics Vulkan右手坐标系变为左手坐标系 问题:,graphics,coordinate-systems,vulkan,Graphics,Coordinate Systems,Vulkan,应用投影矩阵后,Vulkan右手坐标系变为左手坐标系。如何使其与Vulkan坐标系一致 细节: 我知道Vulkan是右手坐标系 X+指向右侧 Y+指向下方 Z+指向屏幕内部 我在顶点着色器中看到了这一行: 此时:我正在定义场景中心的摄影机位置和(4,4,-10)世界空间中长方体的位置 结果是: 正如你在上面的图片中所看到的,我得到了屏幕内的Z-点,但它应该是正的 这是预期的,我需要补充一些东西,还是我做错了什么 代码的有用部分: 投影计算: 相机UBO填充: 我不使用或不知道Vulcan,

应用投影矩阵后,Vulkan右手坐标系变为左手坐标系。如何使其与Vulkan坐标系一致

细节: 我知道Vulkan是右手坐标系

  • X+指向右侧
  • Y+指向下方
  • Z+指向屏幕内部
我在顶点着色器中看到了这一行:

此时:我正在定义场景中心的摄影机位置和(4,4,-10)世界空间中长方体的位置

结果是:

正如你在上面的图片中所看到的,我得到了屏幕内的Z-点,但它应该是正的

这是预期的,我需要补充一些东西,还是我做错了什么

代码的有用部分: 投影计算:

相机UBO填充:


我不使用或不知道Vulcan,但透视投影矩阵(至少在OpenGL中)正朝
Z-
方向查看,该方向反转坐标系的一个轴。这将反转坐标系的缠绕规则

如果要保留原始绕组,而不仅仅是在矩阵中反转
Z
轴矢量,有关更多信息,请参阅:


因此,只要将
Z
轴按
-1
进行缩放,或者通过与
glScale(1.0,1.0,-1.0)的某种类比进行缩放或通过直接矩阵单元格访问。

只要所有内容都正确绘制,坐标系就不重要了。Vulkan不在场景上施加任何坐标系(没有默认投影),仅在图像/附件/屏幕空间上。投影矩阵和世界空间是为了您的方便而定义的,如果它适合您,也可以。如果你想保持所有坐标的持久性,那么你需要改变投影矩阵。从vulkan的角度看这无关紧要,但我必须有一个正确的坐标系,在这个坐标系中可以定义场景中的事物并获得预期的行为是的,当然。但是Vulkan并没有让你使用任何特定的坐标系。所以,这取决于你选择一个对你来说方便的。Frank D.Luna的《使用DirectX进行3D游戏编程入门》一书对如何创建投影矩阵进行了详细说明。基于此和典型的OpenGL转换,我准备了一个生成投影矩阵的程序。因此,如果您想创建一个与Vulkan坐标系的其余部分一致的矩阵,我认为更改矩阵生成代码以满足您的需要应该不难。您是否使用了glm的
glm\u FORCE\u DEPTH\u ZERO\u TO\u ONE
定义,如前所述?是的,我使用了。我在这里修复了我的问题:谢谢你的评论!谢谢你的回复,现在更清楚了。你的意思是我应该直接缩放投影矩阵吗?因为它不起作用。。另外,为了改变坐标系设置Y+向上X+向右和Z+向后(右手),我创建了一个矩阵来旋转它,但它不起作用。我是要用投影还是用相机来放大它?在乘以它之前,我必须将坐标系从左手调换到右手,是吗?@Andreactania rotating对此没有任何作用。直接缩放投影可以更改深度缓冲区和NDC范围行为。由于我不使用vulkan,所以如果需要反转深度测试或翻转NDC Z范围,我现在不使用。因此,缩放视图矩阵(它是modelview的一部分)更安全。问题是,相机处于逆矩阵形式,因此缩放可能不会执行此操作,因为您需要反转最有可能的行而不是列。此外,这样做后,您的相机将以相反的方式观看,因此请将其调转。@Andreactania第二次学习如果您在投影中缩放x,并将相机调转y 180度,则无需更改NDC或深度测试即可工作。是的,您仍然会查看
Z-
,但缠绕规则将是相同的。。。。此外,如果您想使用第一个选项,您仍然可以使用缩放,即使是对行,如果您转置之前和之后。。。但是,对于矩阵中3个元素的简单反转符号来说,这是很多操作。感谢您对Z轴反转投影的澄清。另外,我选择了第二种解决方案,我被迫将面部方向从顺时针改为逆时针@在opengl中,
glFrontFace(GL_CW)最有可能翻转的AndreaCatania
GL_CCW
因此在vulkan中也应该类似,无需重新定义网格。。。
gl_Position = scene.cameraProjection * scene.cameraView * meshUBO.model * vec4(vertexPosition, 1.0);
void Camera::reloadProjection(){
    projection = glm::perspectiveRH_ZO(FOV, aspect, near, far);
    isProjectionDirty = false;
}
    SceneUniformBufferObject sceneUBO = {};
    sceneUBO.cameraView = camera.transform;
    sceneUBO.cameraProjection = camera.getProjection();