IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Moteur de particules


Sujet :

OpenGL

  1. #1
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut Moteur de particules
    Coucou a tous !
    J'ai juste un petit pb ; je me lance dans la gestion de particule ( version simplifié ... et je vient de commencer . )

    J'ai un petit probléme dont je trouve pas l'origine ( je soupsonne la fonction random() , mais vraiment a défaut de trouver autre chose ... , c'est surement un petit truc, j'ai le nze dessus mais je le vois pas )

    En gros, j'affiche 3000 particules, que je régénère si elle sont "morte" .
    Seul pb, il se produit d'abord un jet de particule ( pas celui que je veut ) puis aprés, l'effet que je souhaite appait .

    C'est pas facile a décrire alors je vous ai fait un exe

    http://max.cat.free.fr/Bureau.zip

    Laisser le tourner une 10aine de seconde et vous constaterez par vous meme .

    EDIT : je pense avoir comprit ;o)
    ca doit devnir du faite, qua l'instant 0, je créer les 3000 particules en meme tps ! Et que aprés elle n'ont plus de raison d'être créer en meme tps ( elle sont renouveller a leur mort, qui est du a un facteur random() ).
    PB close je pense ... je vais voir ca vite fait, puis je tag ca "résolu" jespére

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Effectivement, ton problème ressemble furieusement à un problème de création simultanée : les "effets geyser" sont en général démarrés en créant les particules une à une, jusqu'à un nombre maximal (3000, donc, dans ton cas). Ensuite, elles sont "régénérées" en fonction des pertes et/ou de l'arrivée sur un cadre "englobant", souvent les limites de l'affichage.

    Par contre, deux petits bémols sur le résultat de ton application :
    - T'aurais pu prévoir une sortie simple, j'ai dû killer le processus...
    - C'est extrêmement lent, à un point que c'en est presque anormal : que fais-tu donc comme calculs pour perdre autant de temps ??

  3. #3
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    autant pour moi ... la sortie normal est "echap"

    Sinon , oui c'est assez lent ( ~500 fps chez moi ) mais je ne vois vraiment comment faire + court . En plus pour le moment les particules n'ont même pas de donnée menbre couleur ( ce qui risque encore d'alourdir la chose ) ...
    a chaque frame, j'affiche donc mes 3000 particules et j'apelle ceci dans ma boucle d'affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    void cFireTest::MajParticle(int rang) 
    {
    	// MAJ du LifeTime
    	AllParticles[rang].LifeTime -=  AllParticles[rang].FadeTime ;
    	if (  AllParticles[rang].LifeTime < 0 )
    	{
    		AllParticles[rang].LifeTime = 1 ;
    		AllParticles[rang].Position.X = 300 + (double) ( 50*rand()/(RAND_MAX+1.0) ) ;
    		AllParticles[rang].Position.Y = 100 + (double) ( 20*rand()/(RAND_MAX+1.0) ) ; 
    		AllParticles[rang].Vitesse.X = -0.1 + (double) ( 0.2*rand()/(RAND_MAX+1.0) ) ;
    	    AllParticles[rang].Vitesse.Y = 0.1 + (double) ( 0.3*rand()/(RAND_MAX+1.0) ) ;
    	}
     
    	// MAJ de la position
    	AllParticles[rang].Position +=  AllParticles[rang].Vitesse ;
    	AllParticles[rang].Vitesse += AirGravitation   ;
    }
    edit: je vient de tester mes fps sur un autre "moteur" de particule ( celui de Nehe's ) et je suis a 999 ( maximum de mon logiciel qui me donne les fps) ... donc j'ai clairement loupé qquchose dans mon code , je vais fouiner

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Clad3
    Sinon , oui c'est assez lent ( ~500 fps chez moi ) mais je ne vois vraiment comment faire + court . En plus pour le moment les particules n'ont même pas de donnée menbre couleur ( ce qui risque encore d'alourdir la chose ) ...
    500 fps ??? A vu de nez, j'aurais plutôt dit 4 ou 5 fps !!
    Entendons-nous bien : pour moi, une frame est une image où quelque chose a changé : rafraîchir la même image n'entre pas en ligne de compte, du moins pour l'humain en face ("si ça bouge pas, c'est que c'est mort !" ;-))

    Citation Envoyé par Clad3
    a chaque frame, j'affiche donc mes 3000 particules et j'apelle ceci dans ma boucle d'affichage : <snip>
    Je crois voir le problème... Entre les calculs en "double" et 4 appels à rand() par particule [si rand() était une fonction performante, ça se saurait.... ;-)], je comprends que ça prenne du temps... Surtout à la conversion vers les coordonnées écran...

    Reste à savoir ensuite ce que tu veux réellement : implémenter un modèle réaliste (=grosse puissance CPU requise), ou implémenter un truc genre démo (=pas réaliste, mais très rapide) ?

  5. #5
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    4 5 fps ?? oula, chez moi je peut t'assuer que c'est trés "smooth" ( zut je retrouve plus d'équivalent jolie en francais !) .
    500 fps sans syncro horizontal ( ou vertical, je confond toujours ).

    Enfin quand aux différents calcul ( je me suis aussi posé la question ; je les ai remplacé par des attribution a des valeurs "fixe" genre 1 . Et ca ne m'a pas fait gagner grand chose en fps . Donc au pire le pb vient des affectation ; mais pas de la valeur qui est affecté .

    Ce que je veut faire ? Quelquechose qui me permette de faire ( au final ... j'en suis loin ) de faire des choses comme de la fumée , du feu , une fontaine ect ... Pas seulement en "démo" ; mais pour un jeu . Donc ca doit être fluide ( voila le mot que je cherchais lol ) et jolie

    Tient sinon, je suis entrain de me demander ou j'ai loupé le coche , dans la plusparts des moteurs de particules , le centre des effet ( la ou il y a le + de particules ) sont +- blanc . Et je n'arrive pas a reproduire ca avec du blending ...

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Clad3
    4 5 fps ?? oula, chez moi je peut t'assuer que c'est trés "smooth" ( zut je retrouve plus d'équivalent jolie en francais !) .
    500 fps sans syncro horizontal ( ou vertical, je confond toujours ).
    C'est vertical (attente VBL). Et les 4/5 fps, c'est une impression "visuelle" : il y a peut-être 500 fps, mais à l'écran, si tu n'en avais que 4 ou 5, ça irait à la même vitesse : les particules ne "bougent" quasiment pas, tu vois mieux ce que je veux dire ? Pour être fluide, c'est fluide... Mais façon "béton en train de sécher" ! ;-)

    Citation Envoyé par Clad3
    Enfin quand aux différents calcul ( je me suis aussi posé la question ; je les ai remplacé par des attribution a des valeurs "fixe" genre 1 . Et ca ne m'a pas fait gagner grand chose en fps . Donc au pire le pb vient des affectation ; mais pas de la valeur qui est affecté .
    Peut-être que tes particules ne se déplacent pas assez vite, ou "vibrent" trop sur elles-même : ça pourrait expliquer la lenteur apparente...

    Citation Envoyé par Clad3
    Ce que je veut faire ? Quelquechose qui me permette de faire ( au final ... j'en suis loin ) de faire des choses comme de la fumée , du feu , une fontaine ect ... Pas seulement en "démo" ; mais pour un jeu . Donc ca doit être fluide ( voila le mot que je cherchais lol ) et jolie
    En général, on utilise l'accélération matérielle, et des trucs comme les fog tables pour ça... Le faire uniquement par soft et espérer avoir quelque chose de fluide, je pense que tu vas avoir du mal... A ta place, je regarderai plutôt du côté de DirectX ou OpenGL pour le côté intégration dans un jeu ou performances pures.
    Après, tu peux aussi avoir envie de voir jusqu'où tu peux aller par soft, c'est compréhensible.

    Citation Envoyé par Clad3
    Tient sinon, je suis entrain de me demander ou j'ai loupé le coche , dans la plusparts des moteurs de particules , le centre des effet ( la ou il y a le + de particules ) sont +- blanc . Et je n'arrive pas a reproduire ca avec du blending ...
    A propos, tu devrais afficher ton effet sur un fond noir plutôt que blanc : ça tue moins les yeux...
    C'est en général fait par accumulation sur un buffer intermédiaire : ton "nuage" étant compris dans une zone rectangulaire, tu commences par le vider (=(0,0,0), couleur noire). On va appeler ça le BI (Bitmap Intermédiaire).
    Ensuite, à chaque "tracé" d'une particule, tu appliques le principe suivant :
    - Déteminer la coordonnée de la particule dans le BI.
    - Tu incrémentes la couleur du pixel correspondant dans le BI, suivant "l'énergie" de la particule. Ca peut être en fonction de sa vitesse, de sa "couleur", de sa direction par rapport à la caméra, etc....
    - Tu obtiens donc un pixel "plus clair" (en composantes grayscale, en tout cas) que précédemment. Bien sûr, il faut saturer sur le blanc, sinon il va y avoir des effets de "tranchage" désagréables.

    Il ne reste plus qu'à afficher le BI sur l'image finale, par exemple en utilisant un masquage simple (=élimination du noir "d'origine").

    OK ?

  7. #7
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Pour la "lenteur" des particules , heu il faut qu'on se mette d'accord sur ce qu'on apelle lent ^^ , je n'ai pas fait des missiles, certe, mais c'est voulus pour le moment ... enfin c'est dur a quantifié, faire la différence entre quelque chose de lent voulu et un probléme de perf, j'ai du mal a voir dans quel cas on se situe la ... car pour moi ca va a une vitesse "normale" .

    edit : tes drivers graphqiue sont à jour? tu as une ptite config? ( on ne sait jamais ^^ )

    Les fog tables je ne connias pas, je vais me renseigner
    Sinon je fait ca en openGL ( je suis pas rodé niveau voc technique mais c'est en hardwarde ca , non ? )

    Quand a la couleur du fond, oui je suis entre temps passez au noir

    Sinon pour le centre "blanc" des effet, si j'ai bien comprit, tu propose du créer un masque qu'on remplie a chaque déplacement d'une particules ...
    hum, autant donner une couleur a chaque particules dans ce cas non ? ( et la modifié a la volée ; par exemple en fonction de la distance au centre d'emission )
    Mais ca m'etonne que ce soit la méthode la plus simple , j'ai examiné 2 code sources, et je n'ai noté ca dans aucun des deux . Et pourtant les 2 présente cette particularité que je n'arrive pas a reproduire :/

    en tout cas, merci,

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Clad3
    car pour moi ca va a une vitesse "normale" .
    Disons que j'ai l'impression de voir une fontaine de slime en apesanteur... ;-)

    Citation Envoyé par Clad3
    edit : tes drivers graphqiue sont à jour? tu as une ptite config? ( on ne sait jamais ^^ )
    Xeon 2.8 HT sur CM bi-proc, V8570 TD et 1 Go de RAM, en général, ça suffit amplement...

    Citation Envoyé par Clad3
    Les fog tables je ne connias pas, je vais me renseigner
    Si ma mémoire est bonne, c'est à peu de choses près l'algo que je t'ai donné au post précédent.

    Citation Envoyé par Clad3
    Sinon je fait ca en openGL ( je suis pas rodé niveau voc technique mais c'est en hardwarde ca , non ? )
    Non, pas tout. L'API OpenGL est très chouette dans le sens où elle marche à 100% tout le temps ou presque, mais rien n'impose d'avoir les fonctions câblées (=hard), ce qui peut parfois provoquer des ralentissement sévères si le matos ne supporte pas en hard une fonction utilisée intensivement.

    Citation Envoyé par Clad3
    Sinon pour le centre "blanc" des effet, si j'ai bien comprit, tu propose du créer un masque qu'on remplie a chaque déplacement d'une particules ...
    Oui, c'est ça. Sauf que ce n'est pas lors du déplacement d'une particule qu'il est recalculé, mais après une étape complète d'animation (=après avoir modifié les positions/structures des 3000 particules).

    Citation Envoyé par Clad3
    hum, autant donner une couleur a chaque particules dans ce cas non ? ( et la modifié a la volée ; par exemple en fonction de la distance au centre d'emission )
    Non : ça ne permet pas de réaliser l'effet que produit une nappe de brume, par exemple : plus les particules sont "tassées", plus la couleur de la brume "ressort", mais individuellement, la couleur des particules est toujours la même... La distance par rapport au centre d'émission ne te permet pas de te prémunir de certains effets de bord, et surtout c'est inapplicable pour un banc de brouillard statique.

    Citation Envoyé par Clad3
    Mais ca m'etonne que ce soit la méthode la plus simple , j'ai examiné 2 code sources, et je n'ai noté ca dans aucun des deux . Et pourtant les 2 présente cette particularité que je n'arrive pas a reproduire :/
    Vérifie qu'il n'y a pas une fonction hard activée... Mon OpenGL est assez rouillé, mais l'activation d'un effet ou pas était parfois liée à un simple paramètre par forcément hyper visible...
    As-tu essayé de recompiler ces exemples, et surtout de les modifier pour voir ce que ça donnait ?

    Citation Envoyé par Clad3
    en tout cas, merci,
    De rien.

  9. #9
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Disons que j'ai l'impression de voir une fontaine de slime en apesanteur...
    Haha c'est vrai :p mais le but n'est pas (encore ! ) d'être jolie, just de tester comment ca marche ^^

    concernant ta méthode , je vient de la relire a tête reosée, et j'ai du mal a voir ca en détail en fait ( le principe ca va, mais l'application ... moins bien )

    Ensuite, à chaque "tracé" d'une particule, tu appliques le principe suivant :
    - Déteminer la coordonnée de la particule dans le BI.
    - Tu incrémentes la couleur du pixel correspondant dans le BI, suivant "l'énergie" de la particule. Ca peut être en fonction de sa vitesse, de sa "couleur", de sa direction par rapport à la caméra, etc....
    - Tu obtiens donc un pixel "plus clair" (en composantes grayscale, en tout cas) que précédemment. Bien sûr, il faut saturer sur le blanc, sinon il va y avoir des effets de "tranchage" désagréables.

    Il ne reste plus qu'à afficher le BI sur l'image finale, par exemple en utilisant un masquage simple (=élimination du noir "d'origine").
    Tu écrit " aprés CHAQUE tracé d'une particule" ... et aprés tu me dit, aprés le tracé de TOUTE les particules ... soit j'ai mal interprété, soit ya un "bunz" .

    ok, ensuite, le BI, concrétement c'est quoi ? ( je n'ai encore jamais utilisé de masquage ) . Ce qui me géne le plus pr la suite c'est ca... je ne vois pas quel forme a ce BI en terme de coding .

    bon allez, une tite douche, et je reveint les idées claires

    edit : voila une partie de mon .cpp ( je précise, que la methode init() est appelé dans le constructeur ; et Draw() est appellée chaque frame .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    /* --------------------------------------------------------------------------------- */
    // Permet d'afficher le Feu a l'écran .
    /* --------------------------------------------------------------------------------- */ 
     
    void cFireTest::Draw() 
    {
    	    if ( AllParticles.size() < NbParticles )
    		{
    			IniParticles() ;
    		}
     
    		glDisable(GL_DEPTH_TEST);	
    		glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 
    		glEnable(GL_TEXTURE_2D) ;
    		glBindTexture (GL_TEXTURE_2D, texture_id);
     
    		for (unsigned int i = 0 ; i < AllParticles.size()  ; i++ )
    		{
    			glBegin(GL_QUADS);
    			glColor4d(255,0,0, AllParticles[i].LifeTime ) ; 
     
    			    glTexCoord2f (0     ,   0); 
    				glVertex2i( (GLint) AllParticles[i].Position.X ,  (GLint) AllParticles[i].Position.Y);
     
    				glTexCoord2f (0     ,   1); 
    				glVertex2i(  (GLint) AllParticles[i].Position.X ,  (GLint) (AllParticles[i].Position.Y + 5)); 
     
    				glTexCoord2f (1     ,   1); 
    				glVertex2i( (GLint) (AllParticles[i].Position.X + 5) ,  (GLint) (AllParticles[i].Position.Y + 5)); 
     
    				glTexCoord2f (1     ,   0); 
    				glVertex2i(  (GLint) (AllParticles[i].Position.X + 5),  (GLint) AllParticles[i].Position.Y); 
     
    			glEnd(); 
    			MajParticle(i) ;
    		}
            glDisable(GL_BLEND);  
    		glDisable(GL_TEXTURE_2D) ;
    }
     
    /* --------------------------------------------------------------------------------- */
    // Initialise tout ce qui doit l'être .
    /* --------------------------------------------------------------------------------- */ 
     
    void cFireTest::Init() 
    {
    	// nombre total de particules
        NbParticles = 6000 ;
     
        // gestion de la fonction random()
    	srand( (unsigned)time( NULL ) );
    	int random_correction = rand() ; // evite la redondance du premier nbre renvoyé par rand() 
     
    	// force gravitaionelle
    	AirGravitation.X = 0 ;
    	AirGravitation.Y = -0.0001 ;
     
    	// chargement de la texture 
    	std::string final_path = "Files/TEMP DESIGN/Particle.bmp" ;
        ILstring fin_path = (ILstring)final_path.c_str() ;
    	ILstring name = "particules" ;
        cTextureManager::GetInstance().load(name,fin_path);
    	texture_id = cTextureManager::GetInstance().get(name); 
    }
     
    /* --------------------------------------------------------------------------------- */
    // Créer une particule .
    /* --------------------------------------------------------------------------------- */ 
     
    cParticles cFireTest::MakeParticle() 
    {
    	cParticles p ;
     
    	p.LifeTime = 1 ;
    	p.FadeTime = 0.0003 + (double) ( 0.0003*rand()/(RAND_MAX+1.0) ) ;
     
    	p.Position.X = 300 + (double) ( 50*rand()/(RAND_MAX+1.0) ) ;
    	p.Position.Y = 100 + (double) ( 20*rand()/(RAND_MAX+1.0) ) ;
     
    	p.Vitesse.X = -0.1 + (double) ( 0.2*rand()/(RAND_MAX+1.0) ) ;
    	p.Vitesse.Y = 0.1 + (double) ( 0.3*rand()/(RAND_MAX+1.0) ) ;
     
    	return p ;
    }
     
    /* --------------------------------------------------------------------------------- */
    // MAJ le status d'une particule .
    /* --------------------------------------------------------------------------------- */ 
     
    void cFireTest::MajParticle(int rang) 
    {
    	// MAJ du LifeTime
    	AllParticles[rang].LifeTime -=  AllParticles[rang].FadeTime ;
    	if (  AllParticles[rang].LifeTime < 0 )
    	{
    		// Renaissance d'une particule .
    		AllParticles[rang].LifeTime = 1 ;
    		AllParticles[rang].Position.X = 300 + (double) ( 50*rand()/(RAND_MAX+1.0) ) ;
    		AllParticles[rang].Position.Y = 100 + (double) ( 20*rand()/(RAND_MAX+1.0) ) ; 
    		AllParticles[rang].Vitesse.X = -0.1 + (double) ( 0.2*rand()/(RAND_MAX+1.0) ) ;
    	    AllParticles[rang].Vitesse.Y = 0.1 + (double) ( 0.3*rand()/(RAND_MAX+1.0) ) ;
    	}
     
    	// MAJ de la position .
    	AllParticles[rang].Position +=  AllParticles[rang].Vitesse ;
    	AllParticles[rang].Vitesse += AirGravitation   ;
    }
     
    /* --------------------------------------------------------------------------------- */
    // Créer X particules, jusqu'à ce que toutes soient créer une fois .
    /* --------------------------------------------------------------------------------- */ 
     
    void cFireTest::IniParticles() 
    {
    	int nb = 2 ; // FadeTime / NbParticles -> nbre de particules a générer / frame .
    	for ( int i = 0 ; i < nb ; i++ )
    	{
    		 AllParticles.push_back( MakeParticle() ) ;
    	}
     
    }

  10. #10
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Je suis entrain de modifié le code pour passer de mon vector a un tableau a taille fixe ... je suis passé de 200 a 275 fps . Enfin bon c'est pas le probléme principale ; mais une fois le pb énoncé plus haut réglé, il va me faloir optimiser ca de toutes facons

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Salut

    Pour le problème de fluidité je crois moi aussi que c'est simplement un problème de lenteur des particules elle même. Elles mettent un temps fou à avancer mais à vue de nez je crois bien qu'on a pourtant beaucoup de frames, c'est très fluide, faut juste leur "dire" d'avancer plus vite.

    Pour ton problème initial : le principe est très simple, un moteur est toujours basé sur des unités de temps réelle. A chaque frame, tu dois savoir combien de temps réel (c'est à dire le temps objectif, celui qui ne dépend pas des perfs de la machine) il s'est passé depuis le dernier frame. Si tu n'as pas cette info commence par là, c'est le premier truc à mettre en place. Un fois que tu as ça, appelons ce temps 'frametime', exprimé en secondes. Appelons n le nombre de particules à afficher toutes les secondes. L'affichage de ces particules doit être réparti dans le temps, c'est pourquoi, à chaque frame, tu vas devoir multiplier ce nombre de particules par ton frametime, de façon à créer uniquement celles qui correspondent à CE frame seulement. Le nombre de particules à afficher à chaque frame est donc : n*frametime.

    Ex : Tu as 3000 particules par exemple, tu es dans un frame qui a duré 0,005 seconde. Tu vas devoir afficher 3000*0,005 = 15 particules. Le frame d'après dure 0,008 seconde, tu dois alors afficher 3000*0,008 = 24 particules, et ainsi de suite.... au final, lorsqu'une seconde entière se sera écoulée, tu auras bien affiché 3000 particules, mais elles seront apparues progressivement.
    Note qu'il s'agit bien d'une multiplication. Ca peut parait bizarre à première vue puisqu'on essaie de réduire le nombre de particules, sauf que la durée d'un frame est nettement inférieure à 1. Si un frame durait plus d'une seconde (sur un 486 dx2 par ex ) on chercherait au contraire à augmenter le nombre de particules affichées à chaque frame. C'est donc bien d'une multiplication qu'il s'agit.

    Pour le coup du blanc là où il y a le plus de particules... la méthode de l'accumulation buffer ne me parait pas utile. Je crois que clad3 parle de l'effet d'éblouissement que l'on constate traditionellement au centre d'un générateur de particules texturées, et qui est tout simplement due à "l'empilement" d'un max de particules au même endroit. Les particules étant le plus souvent affichées en blending (typiquement : [source_alpha, one_minus_source_alpha]), les canaux de couleurs vont saturer (= dépasser la valeur 1), d'où l'effet d'éblouissement constaté. Donc voilà, il faut simplement utiliser ces paramètres de blending, associé à des texture de particules bien pensées (blanc au centre, noir au bord avec tous les niveaux de gris qui vont bien... commence avec des textures choppées dans des jeux qui donnent accès à leurs données, genre Q3, au moins tu sais qu'elles sont efficaces).

    Va voir mon moteur 3D : http://membres.lycos.fr/zengine/ (sorry pour la pub pleine page et merci lycos)
    Le lensflare ainsi que l'éblouissement constaté lorsqu'on se met face au soleil reflète assez bien ce que je viens de dire, bien qu'exploité autrement dans ce cas précis. Sinon, va voir dans le répertoire particles le fichier particle.ptc (c'est celui qui correspond à la fumée du vaisseau si je me souviens bien), ouvre le sous un éditeur de texte (c'est un XML en fait), et fait pointer la texture vers un fichier à toi, comme ça tu pourras peut-être mieux voir l'influence de la texture sur une particule (tous les formats d'image sont acceptés normalement).

    Voilà, en espérant que ça puisse te guider...

    PS : on devrait pas être dans le forum OpenGL là ??

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Clad3
    Tu écrit " aprés CHAQUE tracé d'une particule" ... et aprés tu me dit, aprés le tracé de TOUTE les particules ... soit j'ai mal interprété, soit ya un "bunz" .
    Non, c'est bien ça. Il y a un algo à appliquer à chaque particule (mais on n'a pas encore tracé un seul pixel), puis un autre algo à appliquer à la fin des calculs pour les particules (=c'est là le tracé "réel").

    Citation Envoyé par Clad3
    ok, ensuite, le BI, concrétement c'est quoi ? ( je n'ai encore jamais utilisé de masquage ) . Ce qui me géne le plus pr la suite c'est ca... je ne vois pas quel forme a ce BI en terme de coding .
    Ca, ça dépend de ton API graphique. Sous GDI, c'est un canvas. Sous DirectDraw, ça doit être (de mémoire) un framebuffer. Sous OpenGL, ça peut être une texture... Ca dépend.
    En gros, c'est un bitmap en mémoire (donc pas sur l'écran de tracé) que tu peux "vider" rapidement vers la zone de tracé.

    Citation Envoyé par :Bronsky:
    Si un frame durait plus d'une seconde (sur un 486 dx2 par ex )
    Non, non : j'ai déjà vu des effets de particules sur des 386 DX 40, et donc sans accélération matérielle, tourner à plein régime à 60 fps...

    Citation Envoyé par :Bronsky:
    Pour le coup du blanc là où il y a le plus de particules... la méthode de l'accumulation buffer ne me parait pas utile. <snip>
    C'est pour lui expliquer comment ça se construit : suivant l'implémentation (et surtout, l'accélération matérielle disponible), c'est beaucoup plus rapide qu'un blending.

    Citation Envoyé par :Bronsky:
    PS : on devrait pas être dans le forum OpenGL là ??
    Ouaip, y'a des chances...

  13. #13
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    @ Bronsky , tu as raison, je n'ai aps prit en compte le temps écoulé depuis la derniére frame ( je dispose de cette donnée ) je vais corriger ca
    Concernant le départ de l'anim , je pense que je vais faire comme tu le dit ( je suis revenu a une appartition instantanée, histoire de réduire le pb et de ce concentré sur mon pb de particules + claire au centre ) .

    Pour cet effet de blanc , je vois le pb , j'utilisait du rouge ( 255,0,0 ) donc pas d'effet de saturation possible , j'ai essayer avec du (230,10,10) mais la, TOUTE mes particles deviennent gris/blanc ... je vois aps trop pourquoi d'ailleur ! ( enfin la solution n'est pas loin a priori ).
    edit: avec (255,1,0 ), toutes mes particules deviennet jaune ( 255,255,0), je vois pas trop comment ca se fait ...

    Pour les particules de Q3 , je n'ai pas le jeu donc ...

    Et je vais de ce pas jeter un oeil a ton moteur

    merci a tous ! je vous tient au courant !

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Mac LAK
    Citation Envoyé par :Bronsky:
    Si un frame durait plus d'une seconde (sur un 486 dx2 par ex )
    Non, non : j'ai déjà vu des effets de particules sur des 386 DX 40, et donc sans accélération matérielle, tourner à plein régime à 60 fps...
    Maintenant que tu le dis c'est vrai que j'avais commencé mon moteur de particules sur un 486 dx400 dans ma petite piole d'étudiant et c vrai que ça tournait très bien.

    Clad3 je me suis trompé dans ce que je t'ai dit. Avec un couple [src_alpha, one_minus_src_alpha], par définition tu n'obtiendras jamais une saturation. En effet tu multiplie la sources par alpha et la destination par (1 - alpha). Les valeurs sources, destination et alpha étant comprises entre 0 et 1, tu ne dépassera jamais 1 avec cette formule. Elle est plutôt réservées aux transparentes "naturelle".
    Pour obtenir un éblouissement tu dois faire de l'additif : [one, one]. Là tu feras saturer tes canaux à coup sûr en empilant des particules. Attention toutefois, tu dois avoir au moins un canal non saturé dans ton RGB. Typiquement (255,0,0) ne marchera pas, ton rouge est déjà saturé et le reste est à 0 donc ne saturera jamais (0+0=0). Par contre ton (230,10,10) peut faire l'affaire je pense.

    Question : quelle texture tu utilise ? Contient-elle un alpha ?

  15. #15
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    j'ai testé avec / sans texture ; sinon j'ai testé avec une texture issu d'un autre moteur de particuel, et celle issu du tient . sans effet .

    GL_ONE, GL_ONE , ne semble pas convenir ; car
    1) on perd toute transparence non ?
    2) bah ca ne donne aps l'effet escompté :/

    j'ai souvent vu GL_SCR_ALPHA , GL_ONE ... ca me donne le meem resultat que les autre ( a savoir, toutes mes aprticules prennent la meem couleur ...

    je suis sur qu'il doit s'agir d'un petit truc tout bête ...

  16. #16
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Autant pour moi , le pb était simple , mais je n'y pensais pas:/

    j'utilisais

    glColor4d(255,1,0, AllParticles[i].LifeTime ) ;

    effectivement, sachant que les valeurs doivent etre comprise entre 0 et 1 ...

    D'ailleurs, y a til une facons d'ecrire ses valeurs entre 0-255 ; et l'alpha entre 0,0 et 1,0 ?

    Enfin bon ... il ne me reste plus qua joué avec ca, et a commencer la lonnnnngguuuee phase d'optimisation
    merci les zenfant !!!! ^^

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Pour exprimer tes valeurs entre 0 et 255, tu dois utiliser glColor4i.

    Le couple (one,one) ne fait pas perdre toute transparence. Pour rappel la formule qui te donne le pixel final après un blending est :

    source*paramSource + dest*paramDest

    'source' étant le pixel que tu cherche à afficher, 'destination' celui qui est déjà à l'écran à ce moment là, et 'paramSource' et 'paramDest' les paramètres de ta fonction de blend. Avec (one,one), tu multiplie donc 'source' et 'destination' par 1 : résultat = source+destination. Ca veut dire que tes pixels vont s'additionner, il y aura donc bien transparence, associé à un effet de saturation dans les zones claires puisque ton résultat est compris entre 0 et 2 (il n'y a aucun one_minus_xxx pour équilibrer les 2 côtés de l'addition et limiter le résultat).

    Il faut que tu comprenne bien le fonctionnement de cette formule, elle est relativement simple et si tu ne la comprend pas tu continuera de tatonner indéfiniment sur les même problèmes.

    Pour info ce qui correspond à pas de transparence du tout c'est (one, zero)... c'est le param par défaut. Si tu as compris la formule tu n'aura pas de mal à comprendre sa signification

  18. #18
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Oui je vois, c'est vrai, que je vois le fonctionnement global de la chose ; mais j'ai toujours du mal a choisir entre mes paramétre . Je vais tenter de mémoriser cette formule et de l'apliquer de temps temps, histoire que ca rentre !

    Sinon petit pb , j'ai remis une initialisation de mes particules en fonction du temps écoulé depuis la derniére frame ( je n'ai aps encore inclu cela dans les vitesse mais c'est pour bientot ) .

    par contre ca me fait quelquechose de bizzare .

    Si je fixe le FadeTime ( valeur retranché a LifeTime a chaque frame) , alors tout ce passe bien ; j'ai des gerbe de particules comme on pourait s'y attendre ( car les particules meurent en meme temps ; mais on été émise en continue au départ et par en même temps .)

    Par contre , si je randomize un peu ce fade_time ; de facons a donner une durée de vie différente a toutes mes particules , j'obtient d'abord un jet de particules ... puis une fois le jet "finis", un autre jet, en continue reprend ( c'est que je veut obtenir )...

    je vois pas trop d'ou ca vient !

    /me retourne a ses tests

    EDIT : ca doit venir de mon initialisation ; je cré un nbre de particules egale a ( par frame ) :

    time_elpased * MAX_PARTICLES .


    Il doit surement faloir tenir compte du FadeTime pour obtenir un résultat en continue dés le début ...
    merci

    EDIT2 :

    MAX_PARTICLES * FadeTime = nbre de particules a créer / frame en moyenne ... ca donne une transition assez douce entre la phase d'init et la phase principale ; reste a introduire dans cette formule le time_elpased pour a mon avis obtenir qquchos d'encore plus fluide

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 68
    Points : 52
    Points
    52
    Par défaut
    Pourquoi utiliser un random() à chaque frame ?? Je pense que tu t'y prend dans le mauvais sens. Si j'ai bien compris tu as un lifetime fixe pour toutes les particules, et à chaque frame, tu leur enlève la "vie" que tu dois leur enlever, +/- un nombre aléatoire. Il faut faire l'inverse : dés le début, tu les initialise avec le lifetime fixe +/- un nombre aléatoire. Et à chaque frame tu leur enlevera lifetime*frametime.

    De cette façon tes calculs seront plus simples à comprendre (et donc leurs bugs aussi) et en plus tu gagnes en perfs (un seul random() pour chaque particule et pour tous les frames).

  20. #20
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Ya a méditer la dessus .... ^^ je revient plus tard pr faire un pti rapport
    merci

Discussions similaires

  1. [Projet en cours] SPARK Moteur de particules open source
    Par Frifron dans le forum Projets
    Réponses: 91
    Dernier message: 30/08/2010, 20h09
  2. Moteur de particules
    Par Ikit dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 23/05/2008, 10h11
  3. Moteur a particules.
    Par Moumoutte dans le forum DirectX
    Réponses: 2
    Dernier message: 01/05/2007, 13h48
  4. [win32, GL, GLU] moteur de particules
    Par stardeath dans le forum OpenGL
    Réponses: 9
    Dernier message: 08/05/2006, 15h14
  5. moteur de particules :Dessiner un point
    Par houssa dans le forum OpenGL
    Réponses: 2
    Dernier message: 25/06/2003, 22h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo