【问题标题】:Preparing model, view and projection matrices for glsl为 glsl 准备模型、视图和投影矩阵
【发布时间】:2015-04-26 14:58:51
【问题描述】:

我正在使用 vecmath 库来帮助处理矩阵数学,同时我正在转换 opengl 程序以更好地利用 glsl

写完问题后,我想我有 3 个小问题:

  • 模型矩阵的值从何而来?
  • 我是否需要重置display() 中的所有模型、视图和投影矩阵?即每一帧
  • 是否在绘制每个对象后重置模式、视图和投影矩阵?

这就是我在GLEventListenerreshape 函数中计算projectionview 矩阵的方式。..

Matrix4f mProjectionMatrix = createPerspectiveProjection(
    60.0f, width / height, 0.1f, 100.0f);
Matrix4f mViewMatrix = new Matrix4f();
mViewMatrix.setIdentity();

辅助函数..

private Matrix4f createPerspectiveProjection(float fov, float aspect, float zNear, float zFar){

    Matrix4f mat = new Matrix4f();

    float yScale = (float) (1 / (Math.tan(Math.toRadians(fov / 2))));
    float xScale = yScale / aspect;
    float frustrumLength = zFar - zNear;

    mat.m00 = xScale;
    mat.m11 = yScale;
    mat.m22 = -((zFar + zNear) / frustrumLength);
    mat.m23 = -1;
    mat.m32  = -((2 * zFar * zNear) / frustrumLength);
    mat.m33 = 0;

    return mat;
}

GLEventListener 中的display() 内部,我不确定接下来的步骤。

从概念上讲,我有以下想法,这些是我需要执行的正确步骤吗? ..

public void display(GLAutoDrawable gLDrawable){

    // reset view matrix, needed?

    // Calculate the model view projection matrix .. where does model matrix get it's values from?

    // translate to Square1's position?
    // rotate to Square1's angle?
    // draw Square1 .. passing MVP matrix

    // translate to Square2's position?
    // rotate to Square2's angle?
    // draw Square2 .. passing MVP matrix
}

这是我的顶点着色器..

uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
void main() {
    gl_Position = uMVPMatrix * vPosition;
}

【问题讨论】:

  • Stack Overflow 的推荐格式是每个线程一个问题。虽然您的子问题可能或多或少密切相关,但考虑将它们可能分离为单独的问题线程是一个好主意。这将提高您获得每个问题的好答案的机会,并且符合Stack Overflow 的建议。

标签: java matrix glsl


【解决方案1】:

我在我的 OpenGL 应用程序中保留了三个矩阵。它们是 ModelViewProjection 矩阵。所有这些矩阵都使用制服发送到着色器,着色器执行此操作。

gl_Position = mProj * mView * mModel * vec4(position, 1.0);

即默认位置在本地对象空间中。将它与 Model 矩阵相乘会应用该模型的平移、旋转和缩放,并且变换后的顶点现在位于世界空间中。

现在顶点乘以 View 矩阵,该矩阵应用相机的变换,例如相机的位置和方向。现在顶点将在眼睛空间中。

最后将顶点与投影矩阵相乘,应用透视或正交的效果,这取决于我选择使用什么。最终在转换之后,顶点将处于标准化设备坐标(范围从 -1+1)并由 OpenGL 渲染。

模型矩阵从哪里得到它的值?

模型矩阵默认为单位矩阵。每当您只想转换实体而不是整个世界时,您将转换矩阵与模型矩阵相乘,并将结果设置为新的模型矩阵。这允许您为场景中模型的每个实例保留单独的属性。

我需要重置display() 中的所有模型、视图和投影矩阵吗?即每一帧?

不,你没有。您可以创建一次矩阵,但每当矩阵的值在客户端(即您的程序)发生变化时,您必须在着色器程序中更新制服。

绘制每个对象后是否重置模式、视图和投影矩阵?

不,你没有。通常,您将保留一个投影和一个视图矩阵,但场景中每个对象都有几个模型矩阵。投影在整个应用过程中通常不会发生变化,因此无需重新更新。视图矩阵与您的相机一起使用,因此通常它也是整个场景的一个。但是,每个对象的模型矩阵会有所不同,因此您必须每帧更新它。

您从哪里获得模型矩阵值?即它们是从什么生成的?

有一些公式可以创建这些矩阵,例如您上面的辅助方法,它根据视野和相机镜头的纵横比生成透视投影矩阵。这些公式在这里很难解释,所以你可以看看我的Transforms类的源代码,它有这样的功能。

在我的 GitHub 存储库中查看我的 Transforms 类的源代码。它没有完全记录在案,但我认为您可以使用它们。

希望这会有所帮助。

【讨论】:

  • 感谢@Sri 的输入,您从哪里获得Model 矩阵值?即它们是从什么生成的?
  • @bobbyrne01 更新了答案。立即检查。
  • @SriHarshaChilakapati:(引用您的回答:)“顶点将位于剪辑坐标中(范围从 -1 到 +1)”。剪辑空间不在范围 [-1,1] 内。在标准化设备坐标中,查看体积表示为 [-1,1] 立方体。剪辑空间透视分界线之前,观看量在 [-w,w] 那里 - 但是,w 可能因每个顶点而异,所以这实际上很难想象为 3D立方体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 2018-02-21
  • 2011-05-11
相关资源
最近更新 更多