所以,我尝试在OpenTK中使用矩阵,我的"转换" class有一个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) - >
[LOG]:FW(0; 0; -1)
[LOG]:R(-1; 0; 0)
[LOG]:UP(0; 1; 0)
好的,我在Z 10,看着0,0,0。正如预期的那样,前进是x -1。 Up是Y 1,也没关系。但水平轴是否为LEFT?这是一种什么样的坐标系?
答案 0 :(得分:2)
你提到矩阵是转置的,因此乘法顺序颠倒了。例如,你的MVP计算是:
model.GetMatrix()* Transform.GetMatrix() * projectionMatrix;
但是你的翻译*轮换连接顺序错误:
Matrix4 translation = Matrix4.CreateTranslation(Position);
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return translation * rotation;
对于非转置矩阵,正确的乘法顺序为:
translation * rotation * scale
因此,对于您的转置矩阵,它应该反转为:
scale * rotation * translation
所以你的代码应该是:
Matrix4 translation = Matrix4.CreateTranslation(Position);
Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
return rotation * translation;