我在OpenGLES中渲染了100多个3D对象,我想知道是否可以优化这个标准矩阵代码以提高性能速度:
Matrix.setIdentityM(modelMatrix, 0);
Matrix.translateM(modelMatrix, 0, x, y, z);
Matrix.scaleM(modelMatrix, 0, scale,scale,1.0f);
Matrix.rotateM(modelMatrix, 0, angle, 0.0f, 0.0f, 1.0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, viewMatrix, 0, modelMatrix, 0);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, projectionMatrix, 0, modelViewProjectionMatrix, 0);
对象都以不同方式缩放,旋转和定位,我的应用程序运行得太慢。我正在寻找许多其他领域,但是分析器显示这个代码非常受性能影响,因此可以更快地完成数学运算吗?
任何提示,非常感谢。
答案 0 :(得分:0)
通过直接输入转换,缩放和旋转调用矩阵值,您可能获得更多收益。旋转调用可能非常慢......
起始3x3子矩阵的矩阵由3个基本向量(X
,Y
,Z
)组成,可以设置为(在您发布的示例中):
X = (cos(angle)*scale, sin(angle)*scale, .0f)
Y = (-sin(angle)*scale, cos(angle)*scale, .0f)
Z = (.0f, .0f, 1.0f)
注意:订单取决于实施
接下来,无论是第4行还是第4列(取决于订单实施),在您的情况下都是翻译:
T = (x, y, z, 1.0f)
由于有{4}个昂贵的三角函数调用(sin
和cos
),因此这根本无法获得任何性能。rotate
如果可能,尝试丢失角度参数并将其替换为way
向量,该向量是对象面向的向量。标准还包括up
向量,它是面向对象的向量。有了这两个向量,您就可以使用前两个的叉积来计算right
向量。结果是有3个垂直向量,应该归一化并乘以标度然后直接插入矩阵作为上述3个基本向量。
在您的情况下,您可以获得一个方向,并且由于您的Z
向量似乎是静态的,您可以在这两个上使用交叉产品来获得第三个。
答案 1 :(得分:0)
矩阵乘法的结果可写为:
结果= ITSR。
对于每个矩阵乘法(我假设矩阵是4x4),你有64次乘法和64次加法。现在你有4个矩阵,你正在成倍增加。这是很多补充和乘法!我们假设您正在使用列向量。
为了加快速度,请执行以下操作:
翻译矩阵只有最后一(第4)列的值。因此,当您乘以IxT时,结果矩阵仍然只有第4列中的值。所以为了加快速度,只需创建一个矩阵,第4列是平移向量,就像这样,而不是进行全矩阵乘法:
So, we have IT = | 1 0 0 0 | | 1 0 0 tx | | 1 0 0 tx |
| 0 1 0 0 | | 0 1 0 ty | = | 0 1 0 ty |
| 0 0 1 0 | | 0 0 1 tz | | 0 0 1 tz |
| 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 |
转移到ITxS,因为缩放仅影响对角线 - 它只影响元素m [0] [0],m [1] [1]和m [2] [2],你可以简单地将这些元素相乘矩阵由尺度表示。所以我们将:
Sx = m[0][0] * scale;
Sy = m[1][1] * scale;
Sz = m[2][2] * 1.0;
但是,由于IT中的所有对角线元素都是1,您只需将比例值写入对角线......就像这样:
ITS = | Sx 0 0 tx |
| 0 Sy 0 ty |
| 0 0 Sz tz |
| 0 0 0 1 |
所以到目前为止,我们没有进行任何矩阵乘法 - 我们只是手工创建了矩阵。所以你可以创建一个看起来像ITS的矩阵。这可以节省2个矩阵乘法!!
现在转到ITSR ......在这里,只需将标准矩阵乘法运算为:
Result = ITSR = | Sx 0 0 tx | | A D G 0 |
| 0 Sy 0 ty | | B E H 0 |
| 0 0 Sz tz | | C F I 0 |
| 0 0 0 1 | | 0 0 0 1 |
你可以稍微加快速度,但为了清楚起见,只需进行全矩阵乘法。所以你只需要做一个矩阵乘法,而不是3。
此外,如果您的相机视图没有改变(viewMatrix),则不必为每个帧导出它,投影矩阵也是如此。我不知道你是不是......只是说。
希望这有帮助。
答案 2 :(得分:0)
@ user3725725 - 我假设您正在使用列向量
Matrix.setIdentityM(modelMatrix, 0);
// Set up the scale
modelMatrix[0] = scale;
modelMatrix[5] = scale;
// Set up Translation
modelMatrix[12] = tx;
modelMatrix[13] = ty;
modelMatrix[14] = tz;
// Do the rest of the matrix multiplication
Matrix.rotateM(modelMatrix, 0, angle, 0.0f, 0.0f, 1.0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, viewMatrix, 0, modelMatrix, 0);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, projectionMatrix, 0, modelViewProjectionMatrix, 0);
PS。如果这有帮助,请考虑投票:)谢谢!