Cool Stack

Réaliser un effet de feux en 2D

Pour ce premier article, je vous propose de vous expliquer la conception d’un effet visuel simple, l’effet de feu. Je vais m’attacher ici exclusivement à l’aspect théorique et algorithmique, je vous laisse ensuite le soin de passer à l’implantation (assez simple quand on a bien compris l’algorithme). L’implantation est possible, dans tous les langages(C, C++, java, C#, VB, Delphi, Assembleur…), à partir du moment où vous avez un quelconque moyen d’afficher des bitmaps (GDI, GTK, DirectX, OpenGL…).

L’algorithme utilisé ici est basé sur une remarque très simple que l’on peut faire en regardant un feu : « la couleur d’un point est une moyenne de la couleur des points directement en dessous à l’instant précédent ». En général on utilise l’équation suivante :

X(t) = (A(t-1) + B(t-1) + C(t-1) + D(t-1)) / 4
algo feux

Pour calculer l’image entière, il suffit d’appliquer cette formule sur l’ensemble des pixels de l’image. Pour calculer la nouvelle image, il nous faut donc l’ancienne (celle au temps t-1). En réalité, 1 seule image suffit. En effet, comme la formule ne prend en compte que les pixels situés en dessous du pixel en cours de calcul, si nous écrasons la nouvelle couleur et que nous appliquons la formule sur les pixels en partant du haut de l’image, alors l’image calculée sera correcte et nous aurons simplifié notre algorithme.

Maintenant que nous avons des flammes, il nous faut les braises. Pour plus de réalisme nous modifieront les braises très légèrement à chaque image afin d’obtenir un effet de « feu dansant». Pour créer des braises, il existe plusieurs méthodes mais nous retiendront ici la plus simple. Nous allons définir les pixels de la ligne la plus en bas de manière aléatoire. Par exemple avec la formule suivante :

C(x,y) = random(0,1) * MAX_COULEUR

Nous avons donc maintenant l’algorithme suivant :

Fonction Suivante(Image img)
    Pour x=0 à MAX_X
        Img(x,MAX_Y) = Random(0,1) * MAX_COULEUR
    Fin Pour
    Pour y = 0 à MAX_Y-1
        Pour x = 0 à MAX_X
            Img(x,y) = (Img(x-1,y+1) + Img(x,y+1) + Img(x+1,y+1) + Img(x,y+2))/4
        Fin Pour
    Fin Pour
Fin
feux noir et blanc

Si vous l’utilisez tel quel, vous aurez alors une animation d’image en niveau de gris et nous constatons qu’en choisissant bien vos couleurs vous aurez un feu assez joli. En réalité c’est ici que réside toute la difficulté de cet effet. En règle générale on utilise une palette de 256 couleurs comme celle-ci :

Plage couleur
0 à 32 noir au rouge foncé
32 à 96 orange au jaune
96 à 255 jaune au blanc
feux noir et blanc

Ceci étant dit, si vous utiliser des bitmaps en couleur réelle (32bit) il nous faut maintenant 2 images pour faire correctement notre effet. La première en niveau de gris, correspondant à celle que nous avons calculée jusqu'à maintenant et une seconde en couleur calculer à partir de la première en appliquant la palette notes ci-dessus. Nous pouvons aussi utiliser plus facilement un simple tableau d’entier représentant notre image en niveau de gris.

Voilà vous savez maintenant tout ce qu’il faut savoir pour passer à l’implantation de cet effet.

Remarque

En ce qui est de mon implantation personnelle, j'ai souvent remarque, que la formule suivante donnait de meilleur résultat esthétique:

X = (A + B + C + D + E + F + G) / 7
algo feux v2

Posted Mer 16 février 2005 by Stéphane Planquart in programmation graphique