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

OpenGL旋转立方体出现拉伸问题,疑与Model Matrix相关

解决OpenGL立方体旋转时的拉伸变形问题

嘿,我看到你在学习OpenGL开发简易游戏时,遇到了立方体旋转拉伸的问题,咱们一步步来搞定它!

核心问题1:旋转轴未归一化导致变形

你用来生成旋转矩阵的向量 mgl32.Vec3{0.5, 1.0, 0.0} 不是单位向量(长度不为1)。HomogRotate3D 函数要求旋转轴必须是单位长度的向量,否则生成的矩阵会隐含缩放变换,直接导致模型拉伸变形。

解决方法:对旋转轴做归一化处理,调用向量的 Normalize() 方法:

model := mgl32.Ident4()
// 先归一化旋转轴
rotationAxis := mgl32.Vec3{0.5, 1.0, 0.0}.Normalize()
model = model.Mul4(mgl32.HomogRotate3D(float32(glfw.GetTime()) * mgl32.DegToRad(50.0), rotationAxis))

核心问题2:透视投影宽高比的潜在计算隐患

你的代码里宽高比写的是 800/ float32(600),虽然Go会自动将整数转为float32运算,但如果后续你改成从窗口获取宽高(而宽高是int类型),很容易触发整数除法的错误(比如800/600在整数运算里结果是1,而非正确的1.333...)。

更稳妥的写法:明确将宽高都转为float32后再计算,甚至直接从GLFW窗口获取实时帧缓冲尺寸:

// 获取窗口实际帧缓冲尺寸(避免窗口缩放导致的比例错误)
width, height := window.GetFramebufferSize()
projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(width)/float32(height), 0.1, 100.0)

修改后的完整核心代码片段

model := mgl32.Ident4()
// 归一化旋转轴,避免缩放变形
rotationAxis := mgl32.Vec3{0.5, 1.0, 0.0}.Normalize()
model = model.Mul4(mgl32.HomogRotate3D(float32(glfw.GetTime()) * mgl32.DegToRad(50.0), rotationAxis))

view := mgl32.Ident4()
view = view.Mul4(mgl32.Translate3D(0.0, 0.0, -3.0))

// 正确计算透视投影的宽高比
width, height := window.GetFramebufferSize()
projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(width)/float32(height), 0.1, 100.0)

shader.setMat4("model", model)
shader.setMat4("view", view)
shader.setMat4("projection", projection)

这样修改后,立方体应该就能正常旋转,不会再出现拉伸变形的问题了。


内容的提问来源于stack exchange,提问作者TotallyGamerJet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:03:33