Vulkan中绕非Z轴旋转三角形出现变形的问题排查
问题根源与解决方法
核心问题
你当前的实现存在两个关键错误,直接导致绕X轴旋转时出现变形和显示不完整:
累积旋转引发的浮点数精度丢失
你在update函数中,每帧都对已经旋转过的顶点重复应用同一个旋转矩阵,相当于反复叠加旋转操作。浮点数的精度是有限的,多次累积计算后,顶点坐标会出现不可忽视的误差,这些误差会破坏三角形顶点的相对位置关系,最终表现为“拆分变形”。绕X轴旋转时顶点Z坐标超出裁剪空间
原始顶点的Z坐标均为0,绕X轴旋转时,顶点的Y分量会转化为Z分量。随着旋转角度不断累积,顶点的Z坐标会逐渐超出Vulkan默认的裁剪范围(NDC空间的Z轴通常为[-1,1]区间),超出范围的顶点会被GPU裁剪器丢弃,导致三角形显示不完整。
而绕Z轴旋转时,顶点的Z坐标始终保持为0,不会触发裁剪逻辑,因此旋转表现正常。
修复方案
正确的做法是保留原始顶点数据,将顶点变换逻辑移至顶点着色器中完成,避免直接修改顶点数据:
- 保存顶点的初始位置,绝对不要在
update函数中修改它们; - 用一个变量记录总旋转角度,每帧递增(例如
totalRotX += glm::radians(1.0f)); - 每帧基于总角度重新计算模型矩阵:
obj.model = glm::rotate(glm::mat4(1.0f), totalRotX, glm::vec3(1,0,0));
- 在顶点着色器中结合模型、视图、投影矩阵完成顶点变换:
#version 450 core layout(location = 0) in vec3 inPosition; layout(location = 1) in vec4 inColor; uniform mat4 u_model; uniform mat4 u_view; uniform mat4 u_proj; layout(location = 0) out vec4 outColor; void main() { gl_Position = u_proj * u_view * u_model * vec4(inPosition, 1.0); outColor = inColor; }
这种方式既避免了浮点数累积误差的问题,又能让GPU高效完成顶点变换,同时只要投影矩阵设置正确,就不会出现顶点被裁剪的情况。
内容的提问来源于stack exchange,提问作者Christopher Weronski
相关产品推荐
相关产品推荐

