【发布时间】:2014-07-07 22:45:03
【问题描述】:
所以,我尝试在 OpenTK 中使用矩阵,我的“变换”类有一个 Rotation(四元数)和一个 Vector3 作为位置。它提供以下领域:
public virtual Vector3 Right
{
get
{
return Vector3.Transform(Vector3.UnitX, Rotation);
}
}
public virtual Vector3 Forward
{
get
{
return Vector3.Transform(-Vector3.UnitZ, Rotation);
}
}
public virtual Vector3 Up
{
get
{
return Vector3.Transform(Vector3.UnitY, Rotation);
}
}
这就是创建视图和模型矩阵的方式:
public virtual Matrix4 GetMatrix()
{
Matrix4 translation = Matrix4.CreateTranslation(Position);
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return translation * rotation;
}
投影:
private void SetupProjection()
{
if(GameObject != null)
{
AspectRatio = GameObject.App.Window.Width / (float)GameObject.App.Window.Height;
projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov) / 180), AspectRatio, ZNear, ZFar);
}
}
矩阵乘法:
public Matrix4 GetModelViewProjectionMatrix(Transform model)
{
return model.GetMatrix()* Transform.GetMatrix() * projectionMatrix;
}
着色器:
[Shader vertex]
#version 150 core
in vec3 pos;
in vec4 color;
uniform float _time;
uniform mat4 _modelViewProjection;
out vec4 vColor;
void main() {
gl_Position = _modelViewProjection * vec4(pos, 1);
vColor = color;
}
OpenTK 矩阵是转置的,因此是乘法顺序。
此设置的问题在于,所有轴和方向向量以及对象位置都被混合、镜像和颠倒。
现在经过大量的摆弄,我设法得到了一个有用的转换,最终得到了以下结果:
我必须反转四元数的方向:
public virtual Vector3 Right
{
get
{
return Vector3.Transform(Vector3.UnitX, Rotation.Inverted());
}
}
public virtual Vector3 Forward
{
get
{
return Vector3.Transform(-Vector3.UnitZ, Rotation.Inverted());
}
}
public virtual Vector3 Up
{
get
{
return Vector3.Transform(Vector3.UnitY, Rotation.Inverted());
}
}
我不得不像这样修改视图矩阵结构:
public virtual Matrix4 GetMatrixView()
{
Matrix4 translation = Matrix4.CreateTranslation(Position*2).Inverted();
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return translation * rotation;
}
如您所见,我必须反转平移矩阵并将位置乘以 2,以使相机空间与世界空间匹配。什么F?
编辑:看看这个。使用默认/直觉设置,我得到了这个:
[日志]: (0; 0; 10) ->
[日志]: FW(0; 0; -1)
[LOG]: R(-1; 0; 0)
[日志]:上升(0;1;0)
好的,我在 Z 10,看着 0,0,0。正如预期的那样,前向是 x -1。向上是Y 1,也可以。但是水平轴向左?这是什么坐标系?
【问题讨论】:
-
您的 Position、Rotation、ZNear 和 ZFar 的值是多少?
-
znear 是 1,zfar 是 120。位置和旋转是可变的。但在启动位置和旋转分别是标识和零。
-
零旋转,所以是
Quaternion.Identity?否则很奇怪,有了 MV 矩阵的标识,你的模型应该在任何地方渲染。顺便说一句,你在做translation * rotation,你确定要先翻译再旋转吗? -
嗯,我想通过它的位置平移对象,然后通过它的旋转旋转?!否则我会旋转翻译。 PS:是的,轮换就是身份
-
我的意思是,例如,如果您从 (0,0,0) 开始,平移 (-10,0,0),围绕 Z 轴旋转 90 度,您的对象将位于 (0,0,10)。如果先旋转然后平移,您的对象将围绕其中心旋转,然后平移到 (-10,0,0)。因此,根据变换的顺序,它最终会出现在不同的位置。
标签: opengl matrix rotation quaternions opentk