C++ 逆vp矩阵和摄影机位置的光线方向不正确

C++ 逆vp矩阵和摄影机位置的光线方向不正确,c++,glsl,raytracing,vulkan,compute-shader,C++,Glsl,Raytracing,Vulkan,Compute Shader,我的光线生成有一个我不理解的问题。光线的方向计算错误。我将这段代码从DirectX 11移植到Vulkan,在那里它工作得很好,所以我很惊讶我无法让它工作: vec4 farPos = inverseViewProj * vec4(screenPos, 1, 1); farPos /= farPos.w; r.Origin = camPos.xyz; r.Direction = normalize(farPos.xyz - camPos.xyz); 然而,这段代码工作得非常完美: vec4

我的光线生成有一个我不理解的问题。光线的方向计算错误。我将这段代码从DirectX 11移植到Vulkan,在那里它工作得很好,所以我很惊讶我无法让它工作:

vec4 farPos = inverseViewProj * vec4(screenPos, 1, 1);
farPos /= farPos.w;

r.Origin = camPos.xyz;
r.Direction = normalize(farPos.xyz - camPos.xyz); 
然而,这段代码工作得非常完美:

vec4 nearPos = inverseViewProj * vec4(screenPos, 0, 1);
nearPos /= nearPos.w;
vec4 farPos = inverseViewProj * vec4(screenPos, 1, 1);
farPos /= farPos.w;

r.Origin = camPos.xyz;
r.Direction = normalize(farPos.xyz – nearPos.xyz);
[编辑]矩阵和摄像机位置设置如下:

const glm::mat4 clip(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f);
projMatrix = clip * glm::perspectiveFov(FieldOfView, float(ViewWidth), float(ViewHeight), NearZ, FarZ);
viewMatrix = glm::inverse(glm::translate(glm::toMat4(Rotation), -Position));

buffer.inverseViewProjMatrix = glm::inverse(projMatrix * viewMatrix);
buffer.camPos = viewMatrix[3];
[Edit2]如果从原点开始,我在屏幕上看到的是正确的。然而,如果我向左移动,例如,它看起来好像我向右移动。我所有的光线似乎都被打乱了。在某些情况下,扫射相机看起来就像我在空间中的另一个点上移动一样。我假设相机的位置不等于透视矩阵的奇点,但我不知道为什么


我想我误解了一些基本的东西。我遗漏了什么?

多亏了这些评论,我发现了问题所在。我错误地构建了视图矩阵,方法与中的完全相同:

glm::inverse(glm::translate(glm::toMat4(旋转),-Position))

这等于先平移,然后旋转,这当然会导致一些不需要的东西。此外,
位置
为负数,
camPos
是使用视图矩阵的最后一列而不是反向视图矩阵获得的,这是错误的


我的分形光线投射器无法注意到这一点,因为我从未远离原点。事实上,在这样的环境中没有参考点。

乍一看,我没有看到明显的错误。您能否更详细地描述一下“不起作用”在您的案例中的具体表现?我假设您成功地使用了相同的矩阵,例如,在相同的应用程序中绘制几何图形?您知道在Vulkan中,与Direct3D相反,剪辑空间y轴指向下方吗?除此之外,我建议您使用
nearPos
作为光线原点,而不是相机系统原点。这样做的好处是,您的代码不仅可以处理居中透视投影,还可以处理任何可以用4×4矩阵描述的投影。此外,你的光线只会击中近平面前方的物体,就好像它们像光栅化管道一样被正确剪裁一样……我没有以其他方式使用相同的矩阵,除了分形光线跟踪器;很可能有不正确的地方。我知道反演,我将用投影矩阵代码更新问题。如果我使用nearPos,那么像我在那里那样计算光线方向是行不通的,是吗?我想避免第二次矩阵乘法。另一方面,在没有矩阵的情况下可能会更有效……摄影机在世界空间中的位置不是视图矩阵的平移。它是逆视图矩阵的平移。-注
glm::inverse(viewMatrix)*glm::vec4(0,0,0,1)
glm::vec4(0,0,0,1)
是视图空间中的相机位置try
buffer.camPos=glm::inverse(viewMatrix)[3]