Zusammenfassung: Ich bekomme eine FPS-Verlangsamung, sobald ich versuche, die Sprites zu tönen (dh: Textur mit Fragment im Fragment-Shader multiplizieren)
Einzelheiten:
Hardware: iPod touch 4
Ich zeichne 700 Sprites mit glDrawArrays auf dem Bildschirm. Und ja, ich staple all dies in einem einzigen Draw Call. Das Folgende zeigt die Vertex-Datenstruktur:
struct Vertex {
float Position[2];
float Color[4];
float Texture[2];
};
Ja, ich sende Farbe mit jedem Scheitelpunkt, da ich einige Sprites selektiv tönen muss, andere jedoch nicht. Es folgt der Fragment-Shader, den ich verwende:
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord );
}
Bis jetzt funktioniert es großartig und gibt mir volle 60 FPS !!!
ABER
Sobald ich den Fragment-Shader auf Folgendes ändere (um das Abtönen zu ermöglichen):
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord ) * DestinationColor;
}
Verwenden der folgenden 64x64-PNG-Textur mit Alphakanal, Rendern mit glEnable (GL_BLEND):
Die Leistung sinkt auf 47 FPS nur aufgrund dieser einzigen Veränderung {nur durch Multiplikation mit ONE Vektor} (FPS gemessen Xcode Instrumente und OpenGL Detektiv verwenden). Irgendwelche Ideen, was los ist?
Vielen Dank.
Bearbeiten:
Ich habe auch versucht, pro Scheitelpunkt-Farbattribut abzustreifen:
struct Vertex {
float Position[2];
float Texture[2];
};
Ändern Sie den Fragment-Shader wie folgt:
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);
}
Es läuft mit 52 FPS für 700 Sprites (ein Gewinn von nur 5 FPS). Das ist also keine Interpolation, die Multiplikation scheint extrem teuer zu sein. Nur diese EINE Multiplikation?
Antworten:
Ich glaube nicht, dass das Leistungsproblem bei der Multiplikation auftritt, sondern bei der Interpolation Ihrer
DestinationColor
Dreiecke zwischen Scheitelpunkt- und Fragment-Shadern. Sie haben vierfloat
Sekunden Zeit, um zwischen Baumscheitelpunkten für jedes Fragment für jedes Sprite zu interpolieren.Für 700 Sprites mit jeweils 64 x 64 Pixel sind dies 11468800 zusätzliche Vorgänge pro Frame , die die GPU ausführen soll. Es ist durchaus möglich, dass Ihnen einige vsyncs fehlen und Sie daher auf 40 FPS fallen.
Wenn Sie möchten, dass jeder Scheitelpunkt eine andere Farbe hat, sodass Sie für jedes Sprite Farbverläufe haben können, haben Sie kein Glück. Es gibt auch einige andere Tricks, die Sie vielleicht ausprobieren möchten, aber ich denke, das ist nicht der Fall.
Da das, was Sie scheinen jeden Sprit zu tun ist , färbt, könnten Sie Ihre degradieren
DestinationColor
zu einuniform
, verwenden Sie es direkt im Fragment - Shader, und es für jeden Anruf ändern. Auf diese Weise finden keine Interpolationen statt. Sie verlieren die gesamte Stapelverarbeitung, können jedoch möglicherweise ein wenig stapeln, wenn Sie sie nach Farbe sortieren.quelle