OpenGL多矩阵变换

use*_*150 9 delphi opengl matrix

我有模型的简单顶点着色器

#version 330

layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 2) in vec2 VertexUV;

out VS_GS_VERTEX
{
    vec3 vs_worldpos;
    vec3 vs_normal;
    vec2 VertexUV;
} vertex_out;

uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 lookAtMatrix;

void main(void)
{
    mat4 MVP = projectionMatrix * lookAtMatrix * modelMatrix;

    gl_Position = MVP * vec4(VertexPosition, 1.0);
    gl_Normal = mat3(modelMatrix) * VertexNormal;

    vertex_out.vs_worldpos = gl_Position.xyz;
    vertex_out.vs_normal = gl_Normal;
    vertex_out.VertexUV = VertexUV;
}
Run Code Online (Sandbox Code Playgroud)

我在那里传递了modelMatrix

  modelMat := MatrixMultiply(transMat, baseMat);
  modelMat := MatrixMultiply(modelMat, scaleMat);
  modelMat := MatrixMultiply(modelMat, rotMat);
  glUniformMatrix4fv(modelMatrix_loc, 1, false, @modelMat);
Run Code Online (Sandbox Code Playgroud)

其中transMat用于定位,scaleMat用于放大整个图像,rotMat用于旋转整个地形. 没有规模 一切都很好,而baseMat是地形上模型的坐标

baseMat := CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
Run Code Online (Sandbox Code Playgroud)

但是当我尝试通过自己的模型的比例放大模型时(模型有基于零的坐标,例如树的根在(0,0,0))

  scMat := CreateScaleMatrix(AffineVectorMake(scale, scale, scale));
  trMat := CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));

  baseMat := MatrixMultiply(scMat, trMat);
Run Code Online (Sandbox Code Playgroud)

与模型的规模

模型不仅放大了,它们也改变坐标而不再放在地形上.是否可以使用模型的缩放,旋转,平移,另一种平移,缩放和旋转来制作一个模型矩阵?或者我应该做点什么?矩阵数学来自GLScene和似乎工作得很好.

编辑:我不能通过proper order缩放首先使用矩阵,因为我有这个

缩放图像 缩放更多
terrain的结构是64x64块的块,每块都有基本坐标.所以要把它放在一起我需要先将每个块转换到正确的位置然后再缩放以放大图像并用鼠标旋转.每个模型还具有分配给地形的绝对位置.我应该缩放和旋转模型(自己的模型的修改器)并将其放在地形上的适当位置.transMat(将瓷砖和模型放在屏幕中央),scaleMatrotMat为地形和模型共享.但是本地scMattrMat扩大模型并把它放到正确的地方.

如果我保持地形工作原样,rotMat * scaleMat * transMat但使用模型,因为rotMat * transMat * trMat * scaleMat * scMat我有这个 楷模
更接近一点
靠近1米

Edit2:将顶点着色器更改为

uniform mat4 modelMatrix;
uniform mat4 MVP;

void main(void)
{
    vec4 modelPos = modelMatrix * vec4(VertexPosition, 1.0);
    gl_Position = MVP * modelPos;
    gl_Normal = mat3(modelMatrix) * VertexNormal;

    vertex_out.vs_worldpos = gl_Position.xyz;
    vertex_out.vs_normal = gl_Normal;
    vertex_out.VertexUV = VertexUV;
}
Run Code Online (Sandbox Code Playgroud)

并通过

modelMatrix = modelRotMat * modelScaleMat;
mvpMatrix = projMat * lookAtMat * rotMat * scaleMat * modelTransMat * transNat;
Run Code Online (Sandbox Code Playgroud)

现在它按预期工作,谢谢你的帮助.

dar*_*ius 7

您必须在翻译之前应用缩放.应用矩阵的正确顺序是

FinalMatrix = TranslationMatrix * RotationMatrix * ScaleMatrix;
Run Code Online (Sandbox Code Playgroud)

(你可以在特定的情况下切换旋转和平移,这取决于你想要旋转的内容,但通常会是这样的)所以,如果你想要结合更多它们,你必须这样做;

FinalMatrix = TranslationMatrix1 *TranslationMatrix2* RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;
Run Code Online (Sandbox Code Playgroud)

编辑

因此,您的模型在地形上具有基准位置旋转和缩放.并且您希望不时向其添加其他变换.你需要很多矩阵.从您模型的地形基础坐标,计算TranslationMatrix2.你CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z))应该没事.模型在地形上的基本比例和旋转也应该在RotationMatrix2和中ScaleMatrix2.这三个矩阵可以保持每个模型在地形上的基本比例位置和方向.你的最终模型矩阵将是

ModelMatrix =  TranslationMatrix2 *RotationMatrix2 * ScaleMatrix2;
Run Code Online (Sandbox Code Playgroud)

如果要缩放它们或从该位置移动它们,可以将新变换与公式相结合.比方说,你想申请第二的规模,以及新的旋转和一个新的翻译,其矩阵是ScaleMatrix1,RotationMatrix1TranslationMatrix1.您的最终模型矩阵将是:

ModelMatrix =  TranslationMatrix1 *TranslationMatrix2*RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;
Run Code Online (Sandbox Code Playgroud)

EDIT2

如果你想保留你的地形结构,我认为你必须使用用于地形的比例矩阵来缩放模型的位置.然后,从该位置计算模型的平移矩阵.使用共享旋转矩阵和模型自己的比例,如下所示

pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;
Run Code Online (Sandbox Code Playgroud)