当前位置: 首页 > 知识库问答 >
问题:

在着色器上计算归一化设备坐标会显示不同于在cpu上计算的结果

柴丰
2023-03-14

我已经创建了一个正投影相机,用于我简单的OpenGL2D渲染器。目前我有一个问题,当我在着色器上计算它们时,计算的归一化设备坐标是错误的,但当我在cpu上计算它们时,我得到了想要的结果。

我使用以下公式创建了一个正投影矩阵:

2 / (right - left), 0, 0, -((right + left) / (right - left)),
0, 2 / (top - bottom), 0, -((top + bottom) / (top - bottom)),
0, 0, -2 / (zFar - zNear), -((zFar + zNear) / (zFar - zNear)),
0, 0, 0, 1

其中右=1280,左=0,上=0,下=720,zFar=1.0和zNear=-1.0。

因此,如果我使用以下顶点位置创建一个矩形:

float vertices[5 * 4] = {
    //vertex pos                tex pos
    0.0f,    720.0f, 0.0f,      0.0f, 0.0f, //bottom left
    1280.0f, 720.0f, 0.0f,      1.0f, 0.0f, //bottom right
    1280.0f, 0.0f,   0.0f,      1.0f, 1.0f, //top right
    0.0f,    0.0f,   0.0f,      0.0f, 1.0f  // top left
};

它应该导致一个矩形填充整个屏幕。

为了计算归一化的设备坐标,我使用以下公式:

ViewProjectionMatrix * Transform * Position
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord;

uniform mat4 u_ViewProjection;
uniform mat4 u_Transform;
uniform vec4 position;
out vec2 v_TexCoord;

void main()
{
    v_TexCoord =  a_TexCoord;
    gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
}

Mat4x4f transform = Mat4x4f::translate(Mat4x4f(1.0f), Vector3f(0.0f, 0.0f, 0.0f)) * 
Mat4x4f::scale(Vector3f(1.0f, 1.0f, 1.0f));

// ViewProjectionMatrix * Transform * Position
Vector4f tl = camera.getViewProjectionMatrix() * transform * Vector4f(0.0f, 0.0f, 0.0f, 1.0f); 

所以我的问题...是我在着色器中做错了什么,还是可能是其他原因造成的?

共有1个答案

姚宪
2023-03-14

您必须transpsoe这些矩阵,因为OpenGL矩阵是以列为主的顺序存储的。

参见OpenGL着色语言4.6、5.4.2向量和矩阵构造函数,第108页:

为了通过指定向量或标量来初始化矩阵,将组件按列为主的顺序分配给矩阵元素:

mat4(float, float, float, float,  // first column
     float, float, float, float,  // second column
     float, float, float, float,  // third column
     float, float, float, float); // fourth column
  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]
[  0   0   0   1 ]        [  3   7  11  15 ]
[ Xx, Xy, Xz, 0, Yx, Yy, Yz, 0, Zx, Zy, Zz, 0, Tx, Ty, Tz, 1 ]
2 / (right - left), 0,                  0,                   0,
0,                  2 / (top - bottom), 0,                   0,
0,                  0,                  -2 / (zFar - zNear), 0,
-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((zFar + zNear) / (zFar - zNear)), 1

另一种选择是在顶点着色器中颠倒乘法顺序:

gl_Position = vec4(a_Position, 1.0) * u_Transform * u_ViewProjection;

参见GLSL编程/向量和矩阵运算:

如果向量从左边乘到矩阵,则结果对应于从左边乘到矩阵的行向量。这相当于将一个列向量乘以从右边转置的矩阵:

 类似资料:
  • 我是机器人和爪哇的新手。我已经构建了一个计算器,当我输入3个输入时,我需要它来自动显示结果,但我不知道该怎么做。 我将multiply添加到了一个文本视图(通过属性onclick),它可以工作,但我希望它能在textview中自动显示。

  • 问题内容: 我有一个python代码在名为A的远程计算机上进行一些计算。我通过名为B的计算机通过A连接到A。是否可以在B的计算机上显示图形? 问题答案: 如果在远程计算机(B)上的Mac OS X上使用matplotlib,则必须首先确保使用基于X11的显示后端之一,因为本机Mac OS X后端无法将其图导出到另一个显示。选择后端可以通过 可以通过提供不正确的后端名称来获得受支持的后端列表:mat

  • 我是Javascript新手,我创建的html计算器有问题。当我在html/javascript计算器中输入一个数字并按下“calculate”(计算)按钮时,正确的答案会出现,但只会出现一秒钟,然后结果就会消失。 我的目标是能够在calculator html表单中输入一个数字,按calculation,让结果连续显示(不被擦除),直到进行另一次计算。 我的代码如下所示: 关于如何修复此代码的任

  • 问题内容: 我如何使用JPA条件API执行以下操作: 使用CriteriaBuilder.countDistinct在一个列/路径上执行此操作很简单,但是如何在两个路径/列上执行此操作? 问题答案: 这是一个较晚的答案:-)尽管我不确定情况是否有所改变。 最近,我遇到了非常相同的需求,并使用concat解决了该需求,即通过将列连接为 伪列 ,然后将其连接到 伪列 上。 但是我不能使用,因为它生成了

  • 问题内容: 我编写了一个脚本,该脚本在用户每次登录我们域中的计算机时运行。此脚本记录用户以及他们登录的计算机。任意数量的用户可以登录任意数量的计算机。 我只是从一个不在的顾问那里继承了这个IT环境,并且正在编写这个小查询,因此当接到用户的呼叫时,我可以按该用户的名字进行搜索,并合理地预测该用户正在使用的计算机。他们登录到任何给定计算机的次数。 这是“登录”表中数据的示例: 我要敲定的逻辑是跨多个列

  • 问题内容: 我有一组建立形状的X和Y点,我需要知道对象是否在其中,该对象的计算是什么? X和Y坐标示例: 我对数学不是很满意:(因此,我希望得到一些支持来理解它的完成方式。 我到目前为止的例子,但似乎并不十分可靠: 问题答案: 您可以从这里开始:http : //en.wikipedia.org/wiki/Point_in_polygon 您可能还会研究JTS拓扑套件。特别是使用此功能。 编辑 :