GLM透视矩阵导致Vulkan渲染失效,寻求排查方案
透视矩阵导致Vulkan渲染无内容的排查与解决
问题描述
在Vulkan渲染器中使用GLM创建透视矩阵,顶点着色器中与顶点相乘后画面无任何渲染内容。已尝试定义GLM_FORCE_RADIANS和GLM_FORCE_DEPTH_ZERO_TO_ONE(单独定义或都不定义),fovy参数试过角度和弧度,均无效,但正交矩阵可正常工作。相关代码与设置如下:
投影矩阵创建代码
glm::mat4 projection = glm::perspective(45.0f, 16.0f / 9.0f, 0.1f, 100.0f); glm::mat4 model = glm::mat4(1.0f); model = glm::rotate(model, (float)glfwGetTime() * 30, glm::vec3(0.0f, 0.0f, 1.0f));
顶点着色器代码
#version 460 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec3 aColor; layout(push_constant) uniform MVP { mat4 VP; mat4 Transform; } matrices; layout(location = 0) out vec4 Color; void main() { gl_Position = matrices.VP * matrices.Transform * vec4(aPos, 1.0f, 1.0f); Color = vec4(aColor, 1.0f); }
GLM引入方式
#define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp>
渲染设置
- 正面为逆时针(CCW)
- 深度测试未启用
排查与解决方法
1. 修正fovy参数的单位
定义GLM_FORCE_RADIANS后,glm::perspective要求fovy参数为弧度值,当前传入的45.0f是角度,需转换:
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 16.0f / 9.0f, 0.1f, 100.0f);
2. 调整顶点/模型的Z轴位置
默认相机位于原点并看向-Z方向(右手坐标系),你的顶点Z坐标固定为1.0f,处于相机后方,直接被视锥体裁剪。需将模型移到相机前方:
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -2.0f)); // 平移至相机前方2单位
3. 确认矩阵乘法顺序
GLM采用列主序矩阵,正确的乘法顺序为投影矩阵 × 视图矩阵 × 模型矩阵 × 顶点。检查VP的构造是否正确:
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 VP = projection * view; // 投影在前,视图在后
4. 验证矩阵传递的正确性
先在着色器中跳过矩阵变换,直接输出顶点:
gl_Position = vec4(aPos, 0.0f, 1.0f);
若能渲染内容,说明矩阵传递存在问题。检查push constant的布局:Vulkan中mat4需要16字节对齐,确保MVP结构体的内存布局符合要求,避免数据错位。
5. 检查NDC范围
Vulkan的NDC范围为x∈[-1,1]、y∈[-1,1]、z∈[0,1]。可通过调试工具查看gl_Position的值,确认变换后的顶点是否在该范围内,超出则会被裁剪。
内容的提问来源于stack exchange,提问作者DaniilV
相关产品推荐
相关产品推荐

