Etranges ondulations oscillantes dans ma mise en œuvre en eau peu profonde

J’ai essayé d’implémenter les équations pour eaux peu profondes dans Unity, mais j’ai rencontré un bug étrange. Je reçois ces étranges ondulations oscillantes dans mon eau. J’ai fait une capture d’écran:

entrez la description de l'image icientrez la description de l'image ici

Et une vidéo que vous pouvez trouver ici: https://www.youtube.com/watch?v=crXLrvETdjA

J’ai basé mon code sur le document Simulation d’érosion hydraulique rapide et visualisation sur GPU de Xing Mei. Et vous pouvez trouver le code complet du solveur ici: http://pastebin.com/JktpizHW (ou voir ci-dessous.) Chaque fois que j’utilise une formule tirée du document, j’ai ajouté son numéro sous forme de commentaire.

J’ai essayé différents pas de temps, pour la vidéo que j’ai utilisée 0,02, le baisser l’a simplement fait osciller plus lentement. J’ai aussi essayé une grid plus grande (la vidéo utilise 100, j’ai essayé 200 mais ensuite les ondulations étaient plus petites.) J’ai vérifié toutes les formules plusieurs fois et je ne trouvais aucune erreur.

Quelqu’un ici peut-il comprendre ce qui ne va pas?

Informaitons supplémentaires:

Comme vous pouvez le voir sur la pâte, je l’ai programmée en c #. J’ai utilisé Unity comme moteur de visualisation et je n’utilise qu’un maillage de grid pour visualiser l’eau. Je modifie la composante sumt du maillage pour qu’elle corresponde à la hauteur calculée.

La méthode DoUpdate obtient un paramètre float[][] lowerLayersHeight , qui correspond en gros à la hauteur du terrain sous l’eau. Dans la vidéo, tout est 0 .

 public override void DoUpdate(float dt, float dx, float[][] lowerLayersHeight) { int x, y; float totalHeight, dhL, dhR, dhT, dhB; float dt_A_g_l = dt * _A * g / dx; //all constants for equation 2 float K; // scaling factor for the outflow flux float dV; for (x=1 ; x <= N ; x++ ) { for (y=1 ; y  0) { K = Mathf.Min(1.0f, _height[x][y] * dx * dx / totalFlux / dt); //(4) _tempFlux[x][y].left = K * _tempFlux[x][y].left; //(5) _tempFlux[x][y].right = K * _tempFlux[x][y].right; _tempFlux[x][y].top = K * _tempFlux[x][y].top; _tempFlux[x][y].bottom = K * _tempFlux[x][y].bottom; } //swap temp and the real one after the for-loops // // 3.2.2 Water Surface // ---------------------------------------------------------------------------------------- dV = dt * ( //sum in _tempFlux[x-1][y].right + _tempFlux[x][y-1].top + _tempFlux[x+1][y].left + _tempFlux[x][y+1].bottom //minus sum out - _tempFlux[x][y].right - _tempFlux[x][y].top - _tempFlux[x][y].left - _tempFlux[x][y].bottom ); //(6) _tempHeight[x][y] = _height[x][y] + dV / (dx*dx); //(7) //swap temp and the real one after the for-loops } } Helpers.Swap(ref _tempFlux, ref _stream); Helpers.Swap(ref _tempHeight, ref _height); } 

Je l’ai réparé moi-même! Bien que tout en conduisant à un ami. Le problème est assez simple, ce que je fais dans le code avec un bug est que pour chaque cellule (ou grid-point) calculer le stream, puis la hauteur et ensuite je vais à la cellule suivante. Ce que je devrais faire, c’est d’abord calculer le stream pour toutes les cellules, puis itérer une seconde fois sur toutes les cellules et calculer leur hauteur. Alors le code devient:

 for (x=1 ; x <= N ; x++ ) { for (y=1 ; y <= N ; y++ ) { // // 3.2.1 Outflow Flux Computation // -------------------------------------------------------------- *** } } for (x=1 ; x <= N ; x++ ) { for (y=1 ; y <= N ; y++ ) { // // 3.2.2 Water Surface // --------------------------------------------------------------------------- *** } } Helpers.Swap(ref _tempFlux, ref _flux); Helpers.Swap(ref _tempHeight, ref _height); 

(Bien sûr, *** devient le code correspondant de la question ci-dessus.)

Maintenant, j'ai une simulation de travail de l'eau.