9

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

#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;
}

我通过那里 modelMatrix

  modelMat := MatrixMultiply(transMat, baseMat);
  modelMat := MatrixMultiply(modelMat, scaleMat);
  modelMat := MatrixMultiply(modelMat, rotMat);
  glUniformMatrix4fv(modelMatrix_loc, 1, false, @modelMat);

其中 transMat 用于定位, scaleMat 用于放大整个图片, rotMat 用于旋转整个地形。 无刻度 一切都很好,而 baseMat 是地形上模型的坐标

baseMat := CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));

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

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

  baseMat := MatrixMultiply(scMat, trMat);

与模型的比例

模型不仅放大了,它们还改变了坐标,不再放置在地形上。是否可以用模型的缩放、旋转、平移和另一种平移、缩放和旋转来制作一个模型矩阵?还是我应该做点别的?矩阵数学GLScene似乎工作正常。

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

缩放图像 扩展更多
地形的结构是 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;
}

并通过

modelMatrix = modelRotMat * modelScaleMat;
mvpMatrix = projMat * lookAtMat * rotMat * scaleMat * modelTransMat * transNat;

现在它按预期工作,感谢您的帮助。

4

1 回答 1

7

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

FinalMatrix = TranslationMatrix * RotationMatrix * ScaleMatrix;

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

FinalMatrix = TranslationMatrix1 *TranslationMatrix2* RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;

编辑

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

ModelMatrix =  TranslationMatrix2 *RotationMatrix2 * ScaleMatrix2;

当您想要缩放它们或将它们从该位置移动时,您可以将新的转换与那些与公式结合起来。假设您要应用第二个比例、新的旋转和新的平移,其矩阵为ScaleMatrix1RotationMatrix1TranslationMatrix1。您的最终模型矩阵将是:

ModelMatrix =  TranslationMatrix1 *TranslationMatrix2*RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;

编辑2

如果您想保持地形的结构,我认为您必须使用用于地形的比例矩阵来缩放模型的位置。然后,从该位置计算模型的平移矩阵。使用共享的旋转矩阵,和模型自己的比例,像这样

pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;
于 2013-09-19T15:34:16.800 回答