是否可以提取模型视图矩阵的模型部分?
Is it possible to extract the model portion of a modelview matrix?
(这个问题和类似)但是我觉得比较笼统,所以重新发一下。
我在 WebGL 中有一个模型视图矩阵,由一系列从局部对象 space 到世界 space 的变换组成,然后是从世界 space 到齐次 WebGL 坐标的变换(所有方向 -1 到 1)。
这个矩阵是通过一系列复杂的步骤在我们的代码中建立起来的。这些步骤之一是渲染到纹理,然后将纹理 blit 到屏幕上。这个过程被提取出来进行概括,所以我们可以将它用于任何 2D 纹理绘制操作。不幸的是,它提供了自己的 view/projection 转换。在我调用它的时候,我只有组合模型视图矩阵。
我想要做的是保留在模型视图矩阵上所做的转换,因为它是一路构建的,但我不想包括视图转换。换句话说,给定一个模型视图矩阵和一个 known 视图变换,有没有办法提取 just 模型变换作为矩阵?
我们没有使用透视投影,并且我们所有的变换本质上都是二维的,因此不需要通用的解决方案(尽管我之前在 3D 中工作时遇到过这个问题,所以一些可以扩展到 3D 会非常有用)。
如果我没猜错,你在 modelview
中有 Inverse(V)*M
,并且你正在逐步构建它。这意味着在你的代码中你正在做这样的事情:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
... here M transforms ...
... here render or whatever ...
对于多个对象,内容通常如下所示:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
for (all objects)
{
glPushMatrix();
... here M transforms ...
... here render or whatever ...
glPopMatrix();
}
所以要获得 V
你可以这样做:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
double iV[16],iVM[16];
glGetDoublev(GL_MODELVIEW_MATRIX,iV);
for (all objects)
{
glPushMatrix();
... here M transforms ...
glGetDoublev(GL_MODELVIEW_MATRIX,iVM);
... here render or whatever ...
glPopMatrix();
}
现在:
iVM = iV*M
V * iVM = V*iV*M
V * iVM = M
其中V = Inverse(iV)
保存直接视图矩阵,M
保存直接模型矩阵。由于 OpenGL 没有逆矩阵,您可以通过转置 + 位置计算来实现,请参阅:
查看其中的 matrix_inv
函数,结果为:
double M[16],V[16];
matrix_inv(V,iV);
matrix_mul(M,V,iVM);
您可以在此处找到 matrix_mul
代码:
(这个问题和
我在 WebGL 中有一个模型视图矩阵,由一系列从局部对象 space 到世界 space 的变换组成,然后是从世界 space 到齐次 WebGL 坐标的变换(所有方向 -1 到 1)。
这个矩阵是通过一系列复杂的步骤在我们的代码中建立起来的。这些步骤之一是渲染到纹理,然后将纹理 blit 到屏幕上。这个过程被提取出来进行概括,所以我们可以将它用于任何 2D 纹理绘制操作。不幸的是,它提供了自己的 view/projection 转换。在我调用它的时候,我只有组合模型视图矩阵。
我想要做的是保留在模型视图矩阵上所做的转换,因为它是一路构建的,但我不想包括视图转换。换句话说,给定一个模型视图矩阵和一个 known 视图变换,有没有办法提取 just 模型变换作为矩阵?
我们没有使用透视投影,并且我们所有的变换本质上都是二维的,因此不需要通用的解决方案(尽管我之前在 3D 中工作时遇到过这个问题,所以一些可以扩展到 3D 会非常有用)。
如果我没猜错,你在 modelview
中有 Inverse(V)*M
,并且你正在逐步构建它。这意味着在你的代码中你正在做这样的事情:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
... here M transforms ...
... here render or whatever ...
对于多个对象,内容通常如下所示:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
for (all objects)
{
glPushMatrix();
... here M transforms ...
... here render or whatever ...
glPopMatrix();
}
所以要获得 V
你可以这样做:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
... here V transforms ...
double iV[16],iVM[16];
glGetDoublev(GL_MODELVIEW_MATRIX,iV);
for (all objects)
{
glPushMatrix();
... here M transforms ...
glGetDoublev(GL_MODELVIEW_MATRIX,iVM);
... here render or whatever ...
glPopMatrix();
}
现在:
iVM = iV*M
V * iVM = V*iV*M
V * iVM = M
其中V = Inverse(iV)
保存直接视图矩阵,M
保存直接模型矩阵。由于 OpenGL 没有逆矩阵,您可以通过转置 + 位置计算来实现,请参阅:
查看其中的 matrix_inv
函数,结果为:
double M[16],V[16];
matrix_inv(V,iV);
matrix_mul(M,V,iVM);
您可以在此处找到 matrix_mul
代码: