OpenTK矩阵转换 [英] OpenTK matrix transformations

查看:77
本文介绍了OpenTK矩阵转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是顶点着色器:

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main(void)
{
    gl_Position = projection * view * model * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
}

我的理解是,通过各种变换,模型空间最终变成了剪辑空间,即由直接绘制到视口的每个轴中的每个单元所绑定的盒子,即(-1,1,0)是在视口的左上方.当我从着色器中删除所有矩阵变换时,

My understanding is that using various transformations, the model space is eventually turned to clip space, which is a box bound by each unit in each axis drawn directly to the viewport, i.e. something at (-1, 1,0) is at the top left of the viewport. When I remove all matrix transforms from the shader,

gl_Position = gl_Vertex;

并传入一个简单的四边形作为模型

and pass in, as the model, a simple quad

public Vector3[] verts = new Vector3[] {
    new Vector3(-1f, -1f, 0),
    new Vector3(1f, -1f, 0),
    new Vector3(1f, 1f, 0),
    new Vector3(-1f, 1f, 0),
};

public Vector2[] coords = new Vector2[] {
    new Vector2(0, 1f),
    new Vector2(1f, 1f),
    new Vector2(1f, 0f),
    new Vector2(0f, 0f),
};

public uint[] indices = new uint[] {
    0,1,2,
    0,2,3,
};

我得到了预期的全屏图像.当我应用转换时,图像显示为 如您所料,屏幕中央的一个小方块.当我尝试在CPU上的剪辑坐标中计算模型顶点的位置时,就会出现问题:

I get the expected full screen image. When I apply the transformations, the image appears as a small square in the centre of the screen, as you'd expect. The problem arises when I try to calculate the position of a vertex of the model in clip coordinates on the CPU:

public Vector4 testMult(Vector4 v, Matrix4 m)
{
    return new Vector4(
        m.M11 * v.X + m.M12 * v.Y + m.M13 * v.Z + m.M14 * v.W,
        m.M21 * v.X + m.M22 * v.Y + m.M23 * v.Z + m.M24 * v.W,
        m.M31 * v.X + m.M32 * v.Y + m.M33 * v.Z + m.M34 * v.W,
        m.M41 * v.X + m.M42 * v.Y + m.M43 * v.Z + m.M44 * v.W);
}

Matrix4 test = (GlobalDrawer.projectionMatrix * GlobalDrawer.viewMatrix) * modelMatrix;

Vector4 testv = (new Vector4(1f, 1f, 0, 1));
Console.WriteLine("Test Input: " + testv);
Console.WriteLine("Test Output: " + Vector4.Transform(testv, test));
Vector4 testv2 = testMult(testv, test);
Console.WriteLine("Test Output: " + testv2);
Console.WriteLine("Test Output division: " + testv2 / testv2.W);

(传入的矩阵与传递到着色器的矩阵相同)

(The matrices passed in are identical to the ones passed to the shader)

然后程序继续进行操作,以在剪辑空间之外提供输出,然后用W除以0.

The program then proceeds to give output outside of clip space, and the division by W leads to divisions by 0:

Test Input: (1, 1, 0, 1)
Test Output: (0.9053301, 1.207107, -2.031746, 0)
Test Output: (0.9053301, 1.207107, -1, 0)
Test Output division: (Infinity, Infinity, -Infinity, NaN)

矩阵创建如下:

projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, window.Width / (float)window.Height, 1.0f, 64.0f);
projectionMatrix =
(1.81066, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.031746, -1)
(0, 0, -2.031746, 0)

viewMatrix = Matrix4.LookAt(new Vector3(0,0,4), -Vector3.UnitZ, Vector3.UnitY);
viewMatrix = 
(1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, 1, 0)
(0, 0, -4, 1)

modelMatrix = 
(0.5, 0  , 0  , 0)
(0  , 0.5, 0  , 0)
(0  , 0  , 1  , 0)
(0  , 0  , 0  , 1)

所以,问题是为什么;我在做什么错了?

So, the question is why; what am I doing wrong?

推荐答案

编辑(从评论中添加真实答案)

默认情况下,您的OpenTK矩阵是转置的.它看起来使用行向量而不是列向量.因此,您需要以(model * view * proj)而不是(proj * view * model)进行乘法.要么在上载矩阵之前转置所有矩阵.

Your OpenTK matrices are transposed by default. It looks to use row vectors instead of column vectors. Therefore you need to do the multiplication as (model * view * proj), not (proj * view * model). Either that or transpose all the matrices before uploading them.

实际上,剪辑空间不是从-1到1,而是从-W到W,其中W是剪辑空间向量的第四个分量.

Actually clip space is not from -1 to 1, but rather from -W to W, where W is the fourth component of the clip space vector.

您可能会想到的是归一化设备coodinates ,它在每个轴上的范围从-1到1.通过将剪辑空间矢量的X,Y和Z坐标除以剪辑空间W分量,可以得到此值.这种划分称为透视划分.

What you're probably thinking of is called normalized device coodinates, which ranges from -1 to 1 on each axis. You get this value by dividing the X,Y, and Z coordinates of the clip space vector by the clip space W component. This division is called perspective division.

这是在将剪辑空间坐标传递到gl_Position之后在幕后完成的.

This is done behind the scenes after you pass the clip space coordinate to gl_Position.

虽然您的剪辑空间坐标为0,但对我来说似乎不正确.

Your clip space coordinate is 0 though, which doesn't seem to be correct to me.

此处有更多详细信息: OpenGL常见问题解答:转换 .

There's some more detail here: OpenGL FAQ : Transformations.

这篇关于OpenTK矩阵转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆