OpenGLES矩阵优化

时间:2015-01-08 14:29:16

标签: opengl-es-2.0

我在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);

对象都以不同方式缩放,旋转和定位,我的应用程序运行得太慢。我正在寻找许多其他领域,但是分析器显示这个代码非常受性能影响,因此可以更快地完成数学运算吗?

任何提示,非常感谢。

3 个答案:

答案 0 :(得分:0)

通过直接输入转换,缩放和旋转调用矩阵值,您可能获得更多收益。旋转调用可能非常慢......

起始3x3子矩阵的矩阵由3个基本向量(XYZ)组成,可以设置为(在您发布的示例中):

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}个昂贵的三角函数调用(sincos),因此这根本无法获得任何性能。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。如果这有帮助,请考虑投票:)谢谢!