Rangkuman: Saya mendapatkan pelambatan FPS segera setelah saya mencoba mewarnai sprite (yaitu: gandakan tekstur dengan warna dalam fragmen shader)
Detail:
Perangkat keras: iPod touch 4
Saya menggambar 700 sprite di layar menggunakan glDrawArrays. Dan ya saya mengumpulkan semua ini dalam satu panggilan undian. Berikut ini menunjukkan struktur data Vertex:
struct Vertex {
float Position[2];
float Color[4];
float Texture[2];
};
Ya saya mengirim warna dengan setiap titik karena saya secara selektif perlu mewarnai beberapa sprite tetapi tidak yang lain. Berikut ini adalah fragmen shader yang saya gunakan:
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord );
}
Sampai sekarang ini berfungsi BESAR, memberi saya FPS 60 penuh !!!
TAPI
Segera setelah saya mengubah fragmen shader ke yang berikut (untuk memungkinkan pewarnaan):
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord ) * DestinationColor;
}
Menggunakan tekstur 64x64 png berikut yang mengandung saluran alfa, rendering dengan glEnable (GL_BLEND):
Kinerja turun menjadi 47 FPS hanya karena perubahan tunggal ini {hanya dengan perkalian dengan SATU vektor} (FPS diukur menggunakan instrumen xcode dan detektif OpenGL). Apa yang sedang terjadi ?
Terima kasih.
Edit:
Saya juga telah mencoba melepas per atribut warna titik:
struct Vertex {
float Position[2];
float Texture[2];
};
Dan memodifikasi fragmen shader sebagai berikut:
precision lowp float;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord ) * vec4(1.0,0.0,0.0,1.0);
}
Ini berjalan pada 52 FPS untuk 700 sprite (keuntungan hanya 5 FPS). Jadi ini bukan interpolasi, sepertinya penggandaannya sangat mahal. Hanya SATU multiplikasi ini?
Jawaban:
Saya tidak berpikir masalah kinerja terjadi pada perkalian, tetapi pada interpolasi Anda
DestinationColor
di segitiga, antara vertex dan fragmen shader. Anda memiliki empatfloat
s untuk menyisipkan di antara simpul pohon, untuk setiap fragmen untuk setiap sprite.Untuk 700 sprite masing-masing 64x64 piksel, ini adalah 11468800 operasi tambahan per frame yang Anda minta untuk dilakukan GPU. Sangat mungkin bahwa Anda akan kehilangan beberapa vsyncs, dan karenanya jatuh ke FPS 40-ish.
Jika Anda ingin setiap simpul memiliki warna yang berbeda, sehingga Anda dapat memiliki gradien untuk setiap sprite, Anda kurang beruntung. Ada juga beberapa trik lain yang mungkin ingin Anda coba, tetapi saya pikir ini bukan masalahnya.
Karena apa yang tampaknya Anda lakukan adalah mewarnai setiap sprite, Anda dapat menurunkannya
DestinationColor
menjadiuniform
, menggunakannya langsung dalam fragmen shader, dan mengubahnya untuk setiap panggilan. Dengan begitu tidak akan ada interpolasi yang terjadi. Anda akan kehilangan seluruh batching, tetapi Anda mungkin bisa batch sedikit jika Anda mengurutkannya berdasarkan warna.sumber