到目前爲止,我的OpenGL ES程序中存在性能瓶頸。我認爲它會運作良好 - 使用VBO,textureatlas,每次平局等少數綁定。但是,當同時使用許多精靈時,性能會下降很多。我發現瓶頸是CPU限制的(有點驚訝)。更確切地說 - 瓶頸可能是一種計算每個矩形四個頂點(x1,y1,x2,y2,x3,y3,x4,y4)的屏幕位置的方法。這用於碰撞檢測。我在這個方法中做的是重複在着色器中做的事情,我認爲許多CPU週期是由MV乘法引起的。OpenGL ES:從着色器獲取轉換的頂點
Matrix.multiplyMV(resultVec, 0, mModelMatrix, 0, rhsVec, 0);
rhsVec是一個存儲頂點的浮點數組,如上所述。
由於這似乎是瓶頸我想知道如何在着色器中訪問相同的矢量,例如計算剪輯座標時?剪輯座標或甚至更好地管理着色器產生的座標。
頂點着色器onSurfaceCreated
final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);
final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);
mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle,
new String[] {"a_Position", "a_Color", "a_Normal", "a_TexCoordinate"});
textureHandle = TextureHelper.loadTexture(context);
GLES20.glUseProgram(mProgramHandle);
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
//mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
,使頂點變換方法(瓶頸)的
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;
varying vec2 v_TexCoordinate;
attribute vec4 position;
void main()
{
v_TexCoordinate = a_TexCoordinate
gl_Position = u_MVPMatrix * a_Position;
}
片斷
private void calcPos(int index) {
int k = 0;
for (int i = 0; i < 18; i += 3) {
rhsVec[0] = vertices[0 + i];
rhsVec[1] = vertices[1 + i];
rhsVec[2] = vertices[2 + i];
rhsVec[3] = 1;
// *** Step 1 : Getting to eye coordinates ***
Matrix.multiplyMV(resultVec, 0, mModelMatrix, 0, rhsVec, 0);
// *** Step 2 : Getting to clip coordinates ***
float[] rhsVec2 = resultVec;
Matrix.multiplyMV(resultVec2, 0, mProjectionMatrix, 0, rhsVec2, 0);
// *** Step 3 : Getting to normalized device coordinates ***
float inv_w = 1/resultVec2[3];
for (int j = 0; j < resultVec2.length - 1; j++) {
resultVec2[j] = inv_w * resultVec2[j];
}
float xPos = (resultVec2[0] * 0.5f + 0.5f) * game_width;
float yPos = (resultVec2[1] * 0.5f + 0.5f) * game_height;
float zPos = (1 + resultVec2[2]) * 0.5f;
SpriteData sD = spriteDataArrayList.get(index);
switch (k) {
case 0:
sD.xPos[0] = xPos;
sD.yPos[0] = yPos;
break;
case 1:
sD.xPos[2] = xPos;
sD.yPos[2] = yPos;
break;
case 2:
sD.xPos[3] = xPos;
sD.yPos[3] = yPos;
break;
case 3:
sD.xPos[1] = xPos;
sD.yPos[1] = yPos;
break;
}
k++;
if (i == 3) {
i += 9;
}
}
該方法被稱爲用於每個精靈 - 100個精靈重複100次。 MV乘法可能會影響性能?
此操作對您而言可能不會太慢。這是400個矩陣和矢量乘法?儘管可能你不應該使用GPU來進行精靈衝突,但你需要將數據從GPU傳回到CPU,這在你的情況下會慢得多。如果這種乘法確實太慢,那麼必須仔細檢查,以便創建自己的。 –
@MaticOblak - 感謝您的評論。其實我有點解決它 - 而不是使用庫函數,我做了手動矩陣乘法的頂點和volia - 幀率增加,問題似乎解決 - 至少部分。如果您注意較慢的設備,我仍然會使用不超過55-60個精靈。我的Galaxy s7可以管理超過100個精靈,但不是星系標籤 – java
除了已經提供的答案,[*總是*以毫秒爲單位衡量性能而不是fps](https://www.mvps.org/directx/articles/fps_versus_frame_time熱媒)。 –