rendering optimisation / optimisation du rendu


texte en français plus bas.

Hi,
Here's a little note on rendering optimization.
As it may be useful to other developers, I write it in English and French (below).

1. what is the problem?
with large maps, I noticed that the game lags when the player moves.

2. the cause
When the player moves, it is necessary to refresh the background image.
But when the map is large, the size of the image to manipulate can be large.
As it is necessary to do it with each "step" of the player, this impacts rendering performances.

3. the solutions in place
Several elements were already in place.
a. generate and load the entire map once, when launching the level (or game).
b. separate elements to display into several “layers”:
 - a layer for background: heavy (the image is completely filled), but the rendering is only updated when necessary.
 - a layer for "sprites": animated elements and decorations, which are updated each frame, to display animations.
c. Only calculate rendering and interactions for elements "in" the screen area.
   We do not calculate elements which will not be visible or which will not have interaction with the player.
d. define a "dead zone" in which the player moves without requiring background refresh:
  the larger the area, the closer the player will appear to the "edge" of the screen.
  As long as the player remains in this "zone", the background does not change.
e. when the background needs to be updated, we "copy" the area corresponding to the size of the screen, from the background source image, and "paste" it on the game screen. ( then we do the same for the sprites).

4. Optimization
Despite this, on big maps there was still a slowdown.
To reduce the processing, I added a “buffer layer” for the background.
This layer is the size of the game's display area, plus a margin around 200px.
When the display area approaches the edge of the buffer layer (here 10 pixels), we copy an area corresponding to the size of the buffer layer from the background source image.
And it is from this buffer layer that we will do the “copy and paste” to generate the image on the screen.

Thus, with each move, instead of manipulating the entire image, we only manipulate a small part, which optimizes performance.

5. possible improvements
An additional option would be to preload the next buffer image in order to avoid the micro freeze that occurs when the buffer is updated.
For this, I could use 2 buffer images:
 - the one currently in use
 - the next one to preload, in anticipation.

#######################################

Bonjour,
Voici une petite note explicative sur l'optimisation du temps de rendu.
Comme cela peut être utile à d'autres développeurs, je l'écris en français et anglais.

1. quel est le problème ?
avec des grandes cartes, j'ai constaté que le jeu ramait lors du déplacement du joueur.

2. la cause
Quand le joueur se déplace, il est nécessaire de rafraichir l'image d’arrière plan.
Mais quand la carte est grande, la taille de l'image à manipuler peut être importante.
Comme il est nécessaire de la faire à chaque "pas" du joueur, cela impacte les performances de rendu.

3. les solutions en place
plusieurs éléments étaient déjà en place.
a. générer puis charger l'ensemble de la carte une seule fois, au lancement du niveau (ou du jeu).
b. séparer les éléments à afficher en plusieurs "calques" :
    - un calque pour l'arrière plan : lourd (l'image est complètement remplie), mais l'affichage n'est mise à jour que lorsque que c'est nécessaire.
    - un calque pour les "sprites" : des éléments animés et les décors, qui sont mis à jour à chaque frame, pour afficher les animations.
c. ne calculer l'affichage et les interactions que pour les éléments "dans la zone de l'écran.
    On ne calcul pas les éléments qui ne seront pas visible ou qui n'auront pas d'interaction avec le joueur.
d. définir une "zone morte" dans laquelle le joueur se déplace sans que cela ne nécessite de rafraichir l’arrière plan :
     plus la zone est grande, plus le joueur donnera l'impression de se rapprocher du "bord" de l'écran.
     Tant que le joueur reste dans la "zone", l'arrière plan ne change pas.
e. quand l’arrière plan doit être mis à jour, on "copie" la zone correspondant à la taille de l'écran, depuis l'image source d’arrière plan, et on la "colle" sur l'écran du jeu. (puis on fait de même pour les sprites).

4. l'optimisation
Malgré cela, sur les grandes cartes il y avait toujours un ralentissement.
Pour réduire le traitement, j'ai ajouté un "calque tampon" (buffer en anglais) pour l’arrière plan.
Ce calque à la taille de la zone d'affichage du jeu, plus une marge tout autour de 200px.
Quand la zone d'affichage s'approche du bord du calque tampon (ici 10 pixels), on copie une zone correspondant à la taille du calque tampon depuis l'image source d’arrière plan.
Et c'est depuis ce calque tampon qu'on fera le "copier-coller" pour générer l'image sur l'écran.

Ainsi, à chaque déplacement, au lieu de manipuler l'ensemble de l'image, on ne manipule qu'une petite partie, ce qui optimise les performances.

5. améliorations possibles
Une option supplémentaire serait de précharger la prochaine image "buffer" afin d'éviter le micro "freeze" qui se produit quand le buffer est mis à jour.
Pour cela, je pourrais utiliser 2 images buffer :
 - celle en cour d'utilisation
 - la prochaine à précharger, en prévision.

Leave a comment

Log in with itch.io to leave a comment.