透视投影 OPENGL 和计算着色器

Posted

技术标签:

【中文标题】透视投影 OPENGL 和计算着色器【英文标题】:Perspective Projection OPENGL and Compute Shaders 【发布时间】:2016-04-24 06:30:43 【问题描述】:

我正在关注这个网站来学习使用计算着色器的光线追踪:https://github.com/LWJGL/lwjgl3-wiki/wiki/2.6.1.-Ray-tracing-with-OpenGL-Compute-Shaders-%28Part-I%29

我的问题,本教程详细介绍了获取透视投影的过程。我认为我正确地遵循了他的步骤,但我得到了错误的结果,我相信我在矩阵计算中犯了一个错误。

我的透视投影代码-

//Getting the perspective projection using glm::perspective
glm::mat4 projection = glm::perspective(60.0f, 1024.0f/768.0f, 1.0f, 2.0f);

//My Camera Position
glm::vec3 camPos=glm::vec3(3.0, 2.0, 7.0);

//My View matrix using glm::lookAt
glm::mat4 view = glm::lookAt(camPos, glm::vec3(0.0, 0.5, 0.0),glm::vec3(0.0, 1.0, 0.0));

//Calculating inverse of the view*projection
glm::mat4 inv = glm::inverse(view*projection);

//Calculating the rays from camera position to the corners of the frustum as detailed in the site.
glm::vec4 ray00=glm::vec4(-1, -1, 0, 1) * inv;
ray00 /= ray00.w;
ray00 -= glm::vec4(camPos,1.0);

glm::vec4 ray10 = glm::vec4(+1, -1, 0, 1) * inv;
ray10 /= ray10.w;
ray10 -= glm::vec4(camPos,1.0);

glm::vec4 ray01=glm::vec4(-1, 1, 0, 1) * inv;
ray01 /= ray01.w;
ray01 -= glm::vec4(camPos,1.0);

glm::vec4 ray11 = glm::vec4(+1, +1, 0, 1) * inv;
ray11 /= ray11.w;
ray11 -= glm::vec4(camPos,1.0);

上述转换的结果:

[![在此处输入图片描述][1]][1]

作为附加信息,我正在使用调用我的计算着色器

//Dispatch Shaders. 
glDispatchCompute ((GLuint)1024.0/16, (GLuint)768.0f/8 , 1);

我还使用

将值传递给着色器
//Querying the location for ray00 and assigning the value. Similarly for the rest
GLuint ray00Id = glGetUniformLocation(computeS, "ray00");
glUniform3f(ray00Id, ray00.x, ray00.y, ray00.z);

GLuint ray01Id = glGetUniformLocation(computeS, "ray01");
glUniform3f(ray01Id, ray01.x, ray01.y, ray01.z);

GLuint ray10Id = glGetUniformLocation(computeS, "ray10");
glUniform3f(ray10Id, ray10.x, ray10.y, ray10.z);

GLuint ray11Id = glGetUniformLocation(computeS, "ray11");
glUniform3f(ray11Id, ray11.x, ray11.y, ray11.z);

GLuint camId = glGetUniformLocation(computeS, "eye");
glUniform3f(camId, camPos.x, camPos.y, camPos.z);

根据 derhass 的建议更新了答案。

我的图像现在看起来像: Latest Image

【问题讨论】:

我建议您也运行相应的 lwjgl 代码并比较矩阵和向量。还要检查统一位置的有效性(!= -1)或使用explicit locations 我已经检查了制服位置的有效性,并且它们是正确的。根据您的建议,我已经给了他们明确的位置,但结果保持不变。我将尝试运行 lwjl 代码并比较矩阵。 【参考方案1】:

glm 库使用标准的 OpenGL 矩阵约定,这意味着在创建矩阵时考虑了乘法顺序 Matrix * Vector。所以下面的代码是错误的:

//Calculating inverse of the view*projection
glm::mat4 inv = glm::inverse(view*projection);

视图矩阵(从世界空间转换到眼睛空间)和投影矩阵(从眼睛空间转换到剪辑空间)的组合是projection * view,而不是您所说的view * projection(它将应用投影在视图之前)。

【讨论】:

抱歉回复晚了,我已经添加了你的建议,但它似乎不起作用。我已经更新了我的问题以包含您的建议。因为,我没有足够的声誉,我不能有超过 2 张图片:) 谢谢!!! 嗨,我用这个 glm::mat4 inv = glm::transpose(glm::inverse(projection*view)); .我只是换了,它。感谢您的帮助。

以上是关于透视投影 OPENGL 和计算着色器的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中的 OpenGL 中将坐标从 3D 透视投影映射到 2D 正交投影

OpenGL chapter3 基础渲染

OpenGL 透视投影推导图解

用于具有fovy和aspect的透视的OpenGL投影矩阵

∑GL-透视投影矩阵的推导

∑GL-透视投影矩阵的推导