You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 14:48:16