ios - SpriteKit Texture Atlas vs Image xcassets
sprite-kit performance-testing (1)
Primero, revisa tu prueba para que coincida con esto:
for (int i=0; i<10; i++) {
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.xScale = 0.5;
sprite.yScale = 0.5;
float spawnY = arc4random() % 768;
sprite.position = CGPointMake(0, spawnY);
SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
[sprite runAction:[SKAction repeatActionForever:action]];
SKAction *move = [SKAction moveByX:1200 y:0 duration:2];
// next three lines replace the runAction line for move
SKAction *remove = [SKAction removeFromParent];
SKAction *sequence = [SKAction sequence:@[move, remove]];
[sprite runAction:sequence];
[self addChild:sprite];
}
Ejecute sus pruebas y debe notar que su tasa de cuadros NUNCA se deteriora como en sus pruebas. Básicamente, sus pruebas ilustran lo que sucede cuando nunca elimina los nodos, pero sigue creando nuevos.
A continuación, agregue la siguiente línea a su ViewController cuando configure su skview:
skView.showsDrawCount = YES;
Esto le permitirá ver el conteo de los sorteos y comprender adecuadamente dónde está obteniendo su aumento de rendimiento con SKTextureAtlas.
Ahora, en lugar de tener una sola imagen, reúna 3 imágenes y modifique su prueba eligiendo una de esas imágenes al azar cada vez que crea un nodo, puede hacerlo de la siguiente manera:
NSArray *imageNames = @[@"image-0", @"image-1", @"image-2"];
NSString *imageName = imageNames[arc4random() % imageNames.count];
En su código, cree su sprite con ese nombre de imagen cada vez que pase por el bucle. es decir:
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:imageName];
En su prueba de SKTextureAtlas, use ese mismo nombre de imagen, obviamente, para crear cada sprite.
Ahora ... vuelva a ejecutar sus pruebas y tome nota del conteo de sorteos en cada prueba.
Esto debería darle un ejemplo tangible de lo que se trata el procesamiento por lotes con SKTextureAtlas.
No se trata de renderizar la misma imagen sprite miles de veces.
Se trata de dibujar muchas imágenes de sprites diferentes en el mismo pase de sorteo.
Es probable que haya una sobrecarga en la obtención de esta optimización de representación, pero creo que el conteo de los sorteos debería explicarse por qué esa sobrecarga es discutible cuando se consideran todas las cosas.
Ahora, puedes hipotetizar un poco más :)
ACTUALIZAR
Como se mencionó en los comentarios, mi publicación fue para exponer por qué su prueba no fue una buena prueba de los beneficios de SKTextureAtlas y tuvo fallas si buscó analizarla de manera significativa. Su prueba fue como la prueba de sarampión con una prueba de paperas.
A continuación se muestra un proyecto de github que armé para señalar dónde es apropiado un SKTextureAtlas y, de hecho, superior a los xcassets.
Simplemente ejecute el proyecto en su dispositivo y luego toque para alternar entre las pruebas. Puedes saber cuándo se está probando con SKTextureAtlas porque el conteo de los sorteos será 1 y la tasa de cuadros será de 60 fps.
Aislé lo que se optimizará con un SKTextureAtlas. Es una animación de 60 cuadros y 1600 nodos que reproducen esa animación. Desplazamiento sus cuadros de inicio para que no todos estén en el mismo cuadro al mismo tiempo. También mantuve todo uniforme para ambas pruebas, de modo que es una comparación directa.
No es correcto que alguien piense que el uso de SKTextureAtlas solo optimizará todo el renderizado. Su optimización se logra al reducir el conteo de sorteos a través de la representación por lotes. Por lo tanto, si su ralentización de cuadros no es algo que se pueda mejorar a través del procesamiento por lotes, el atlas de SKTexture es la herramienta incorrecta para el trabajo. derecho ?
Similar a la agrupación de objetos, donde puede obtener optimización al no crear y matar sus objetos del juego constantemente, sino reutilizarlos de una agrupación de objetos. Sin embargo, si no estás creando y matando objetos constantemente en tu juego, la agrupación no va a optimizar tu juego.
Según lo que vi que describía como un problema de su juego en el registro de discusión, la agrupación es probablemente la herramienta adecuada para el trabajo en su caso.
Estoy haciendo un juego y noté que durante algunas escenas, mis FPS seguían cayendo alrededor del área de 55-60FPS (usando el atlas de texturas). Esto me volvió loco, así que decidí colocar todos mis activos en la carpeta Images.xcassets y, de esta forma, 60FPS constantes.
Pensé que esto era una casualidad o que estaba haciendo algo mal, así que decidí comenzar un nuevo proyecto y realizar algunos puntos de referencia ...
La documentación de Apple dice que el uso de texturas atlas mejorará el rendimiento de la aplicación. Básicamente, permitiendo que su aplicación aproveche la representación por lotes. Sin embargo...
La prueba ( https://github.com/JRam13/JSGlitch ):
- (void)runTest
{
SKAction *spawn = [SKAction runBlock:^{
for (int i=0; i<10; i++) {
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.xScale = 0.5;
sprite.yScale = 0.5;
sprite.position = CGPointMake(0, [self randomNumberBetweenMin:0 andMax:768]);
SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
[sprite runAction:[SKAction repeatActionForever:action]];
SKAction *move = [SKAction moveByX:1200 y:0 duration:2];
[sprite runAction:move];
//notice I don''t remove from parent (see test2 below)
[self addChild:sprite];
}
}];
SKAction *wait = [SKAction waitForDuration:.1];
SKAction *sequence = [SKAction sequence:@[spawn,wait]];
SKAction *repeat = [SKAction repeatActionForever:sequence];
[self runAction:repeat];
}
Resultados:
Las pruebas muestran repetidamente que el uso de xcassets se realiza mucho mejor que la contraparte de atlas en FPS. Sin embargo, el atlas parece administrar la memoria ligeramente mejor que los xcassets.
¿Alguien sabe por qué estos resultados muestran que images.xcassets tiene mejor rendimiento que el atlas?
Algunas hipótesis que he encontrado:
- xcassets está mejor optimizado que atlasas.
- las atlasas son buenas para dibujar muchas imágenes en un solo pase de dibujo, pero tienen una sobrecarga más grande con sprites repetidos. Si es verdadero, esto significa que si tu sprite aparece varias veces en la pantalla (como fue el caso en mi juego original), es mejor eliminarlo del atlas.
-
Las hojas de atlas deben rellenarse para optimizar el rendimiento.
Actualizar
Para esta próxima prueba, seguí adelante y eliminé el sprite de los padres después de que se fuera de la pantalla. También utilicé 7 imágenes diferentes. Deberíamos ver una gran ganancia de rendimiento usando atlas debido al conteo de sorteos, pero ...