Delphi OpenGL多重矩阵转换
我有用于模型的简单顶点着色器Delphi OpenGL多重矩阵转换,delphi,opengl,matrix,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;
#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;
}
我从那里经过
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)处的树根)
模型不仅放大了,还改变了坐标,不再放在地形上。
是否可以使用模型的缩放、旋转、平移和另一个平移、缩放和旋转制作一个模型矩阵?还是我应该做点别的?来自GLScene
的矩阵数学似乎很好
编辑:我不能通过先缩放矩阵来使用正确的顺序
,因为我有这个
地形的结构是由64x64块组成的分块,每个块都有基本坐标。所以要把它放在一起,我首先需要将每个块翻译到适当的位置,然后缩放以放大图像并用鼠标旋转。 每个模型还具有指定给地形的绝对位置。我应该缩放和旋转模型(拥有模型的修改器),并将其放置在地形上的适当位置
transMat
(将瓷砖和模型放在屏幕中央),scaleMat
和rotMat
为地形和模型共享。但是本地scMat
和trMat
用于放大模型并将其放置在正确的位置
如果我使用rotMat*scaleMat*transMat
让地形保持原样,但使用rotMat*transMat*trMat*scaleMat*scMat
的模型,我有这个
再近一点
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;
现在它可以按预期工作了,谢谢您的帮助。您必须在转换之前应用缩放。应用矩阵的正确顺序是
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;
当您要缩放它们或将它们从该位置移动时,可以使用公式将新变换与这些变换结合起来。假设您要应用第二个刻度、新的旋转和新的平移,其矩阵是ScaleMatrix1
、RotationMatrix1
和TranslationMatrix1
。您的最终模型矩阵为:
ModelMatrix = TranslationMatrix1 *TranslationMatrix2*RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;
EDIT2
如果你想保持地形的结构,我认为你必须用地形的比例矩阵来缩放模型的位置。然后,从该位置计算模型的平移矩阵。使用共享旋转矩阵和模型自己的比例,如下所示
pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;
结果看起来很奇怪:模型像点,放大后会快速增长(分配给鼠标滚轮)。可能是因为原始地形逻辑是:平移->缩放->旋转。当我做地形矩阵数学时,比如缩放->平移->在某个点旋转,我可以捕捉到树木在正确大小和位置的图片。但贴图块会分别分割和缩放。让像terrain这样的模型一起平移->
所有比例
->所有旋转
工作!几乎:(很多树仍在飞翔。我无法将逻辑更改为缩放->平移->旋转,因为我的地形不适合模型或分割。@user2091150缩放->平移->旋转是应用任何变换的正确方式。这是一个数学问题,而不是取决于你使用的算法的选择。我将编辑我的答案,并提供更多详细信息。正确的选择不是吗?)顺序取决于旋转是关于什么的。是关于原始原点还是翻译原点?@DavidHeffernan当然。但3D建模程序的工作方式总是缩放、旋转、平移。顺便说一下,这里的问题不是旋转与平移,而是平移与缩放,正确的顺序是缩放、平移问题是地形的构造方式需要平移,然后缩放,这是模型无法使用的顺序。
pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;