从视图矩阵中清除比例组件。独立于相机的缩放
Posted
技术标签:
【中文标题】从视图矩阵中清除比例组件。独立于相机的缩放【英文标题】:Clear a scale component from view matrix. Camera-independent scaling 【发布时间】:2017-09-15 15:29:22 【问题描述】:我需要我的小程序按相机距离缩放小玩意儿,以便随时方便地移动对象。我想我有两个选择:
计算gizmo到相机的距离,做一个缩放矩阵,循环乘所有点:
glm::mat4 scaleMat;
scaleMat= glm::scale(scaleMat, glm::vec3(glm::distance(cameraPos,gizmoPos)));
for (int i = 0; i < vertices.size(); i++)
vertices[i] = glm::vec3(scaleMat * glm::vec4(vertices[i], 1.0));
仅为 Gizmo 清除视图 (lookAt) 矩阵的比例分量。
如果我使用第一种方式,我的 Gizmo 比例会在我更改相机位置时随时累积比例并增加 Gizmo 的大小。我认为第二种方式更准确,但如何做到这一点?谢谢!
【问题讨论】:
您是否打算每次对同一个起始对象应用不同的缩放比例?以这种方式编辑顶点效率很低 @magicleon 是的,每次乘以矩阵是奇怪行为的原因。我得到了它。但是第二种方式如何实现呢? 如何在着色器中进行相同的缩放,将缩放矩阵作为制服传递? @codeNoob 我建议的第二种方式在答案中! @magicleon 对不起,最后一个问题。您如何看待,将对象转换(不是小玩意)存储在一个矩阵中或修改数据的最佳方法是什么?我问你,因为我想使用鼠标选择器,我想为它存储实际数据。可能是在鼠标拾取的那一刻精确地乘以一个修改过的矩阵? 【参考方案1】:如果你想每次都对同一个模型应用不同的缩放,你不应该操纵顶点(实际上你不应该这样做),而是操纵模型矩阵。通过它,您可以在不通过代码处理顶点的情况下操作对象。 我会选择这样的东西:
glm::mat4 modelMatrix(1.0f);
modelMatrix = glm::scale(modelMatrix,glm::vec3(glm::distance(cameraPos,gizmoPos)));
这将为您提供缩放的模型视图矩阵。现在您只需要将它传递给您的顶点着色器。
大致上你应该有这样的东西:
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 M;
void main()
gl_Position = M * vec4(vertexPosition_modelspace,1);
我没有测试过代码,但它与我的一个项目的代码非常相似。在那里我保留了我的模型矩阵,以便累积缩放,但如果你每次都向顶点着色器传递一个全新的矩阵,则什么都不会被记住。
如果您需要更多关于将制服传递给着色器的信息,请查看here at my current project's code。
您可以在TARDIS::applyScaling
中找到缩放,在main.cpp
中找到着色器加载
【讨论】:
你说服我使用第一种方法。 :)) 但是我们永远不会知道如何从视图矩阵中清除比例分量。 :)) 无论如何,谢谢! 拿到后没那么难,建议你以后试试!也许这些教程可以带来一些清晰! opengl-tutorial.org/beginners-tutorials/… 对不起,最后一个问题。您如何看待,将对象转换(不是小玩意)存储在一个矩阵中或修改数据的最佳方法是什么?我问你,因为我想使用鼠标选择器,我想为它存储实际数据。可能是在鼠标拾取的那一刻精确地乘以一个修改过的矩阵? 我想我没明白你在问什么:( 如果您需要一种存储缩放状态的方法(在这种情况下),模型矩阵还可以让您存储此类信息,而原始顶点保持不变!以上是关于从视图矩阵中清除比例组件。独立于相机的缩放的主要内容,如果未能解决你的问题,请参考以下文章
如何从 WinRT Windows.Media API 中获取 Hololens 可定位相机视图和投影矩阵