Comment animer la texture de l'eau abstraite 2d de haut en bas?

24

J'implémente actuellement un jeu avec une vue de haut en bas de l'océan. J'utilise ce qui suit, une petite texture abstraite:entrez la description de l'image ici

La texture réelle est transparente, j'ai ajouté la couleur verte pour plus de clarté.

Le problème que j'ai maintenant, c'est que je ne sais pas comment animer cette texture pour que l'eau soit belle. J'ai essayé de déplacer la texture avec une vague de péché texture.y += sin(angle). Bien sûr, maintenant toute la texture bouge, ce qui semble irréaliste. La prochaine chose que j'ai essayée est d'ajouter un autre calque et d'implémenter un effet de parallaxe. De sorte que les réflexions sous la surface de l'eau se déplaceraient également, mais beaucoup plus lentement. Ça a l'air un peu mieux mais toujours pas ... assez sympa.

Je pense que la meilleure animation serait, si les cellules individuelles se dilataient et se contractaient, un peu comme une toile ou un morceau de tissu. Imaginez que quelqu'un tire légèrement sur un sommet de ces cellules et que la cellule voisine se dilate et que la cellule vers laquelle je tire (ou pousse) se contracte. Un peu comme un réseau de ressorts (?). Mais je ne sais pas comment implémenter quelque chose comme ça:

  • Quel est le modèle mathématique pour cela? Quelque chose avec des ressorts, où les forces poussent / tirent?
  • Et si oui, comment mapper ce modèle à la texture donnée? Garder toutes les courbes et quoi non ...

(Je suis également ouvert à différentes idées / réponses sur la façon d'animer la texture donnée. Le réalisme n'est pas le point ici, juste une belle eau comme des mouvements ...)

Solution de DMGregory

J'ai posté un exemple de libgdx dans ce post: l'animation de l'eau 2D est irrégulière et non fluide (voir la réponse sur le filtrage des textures)

morpheus05
la source

Réponses:

41

Une méthode courante consiste à utiliser une recherche de texture indirecte dans le shader pour déformer la texture d'affichage:

Gif animé montrant l'animation de l'eau

Ici, j'utilise une texture avec un peu de bruit de couleur à basse fréquence (mosaïque de taches lisses de couleurs aléatoires) et je la fais défiler sur la géométrie de l'affichage au fil du temps.

entrez la description de l'image ici

Au lieu de dessiner les couleurs de cette texture, je prends plutôt les canaux rouge et vert et je les soustrais 0.5fpour les transformer en un vecteur 2D pseudo-aléatoire qui change en douceur dans le temps et l'espace.

Je peux ensuite ajouter un petit multiple de ce vecteur à mes coordonnées UV, avant d'échantillonner à partir de la texture principale de l'eau. Cela déplace la partie de la texture que nous lisons et affichons, la déformant.

En faisant la moyenne de deux échantillons de ce bruit, en faisant défiler dans des directions opposées, nous pouvons masquer la direction du mouvement pour qu'elle ressemble à un ballottement sans but.

Dans Unity, le shader ressemblerait à ceci - il devrait être assez simple pour traduire dans la langue du shader de votre choix:

fixed4 frag (v2f i) : SV_Target
{               
    float2 waveUV = i.uv * _NoiseScale;
    float2 travel = _NoiseScrollVelocity * _Time.x;

    float2 uv = i.uv;
    uv += _Distortion * (tex2D(_Noise, waveUV + travel).rg - 0.5f);
    waveUV += 0.2f; // Force an offset between the two samples.
    uv += _Distortion * (tex2D(_Noise, waveUV - travel).rg - 0.5f);

    // Sample the main texture from the distorted UV coordinates.
    fixed4 col = tex2D(_MainTex, uv);

    return col;
}
DMGregory
la source
1
Cela a l'air vraiment sympa. Je ne suis pas sûr de comprendre tous les attributs: _NoseScale = scalaire pour mettre à l'échelle la "carte de bruit". _NoiseScrollVelocity = Vector2 à quelle vitesse nous nous déplaçons à travers la carte du bruit. _Noise =?. _Distorsion = scalaire que je choisis comme facteur de distorsion? v2f = sommet nous déterminons la couleur. i =?
morpheus05
_Noiseest [un échantillonneur de texture qui lit] la petite texture aléatoire blobby ci-dessus. v2f iLes données sont interpolées à partir du vertex shader - nous utilisons principalement pour obtenir les coordonnées de texture pour le pixel , nous nous inspirons, i.uv. Et vous avez exactement raison pour tout le reste.
DMGregory
J'ai implémenté le shader et, d'une manière ou d'une autre, cela ne fonctionne pas (il ne bouge pas ou la distorsion est trop importante), je suppose que je n'ai pas correctement défini les valeurs. time = la différence de la dernière trame en ms. noise_scale = 1 (j'utilise votre texture, répétition du mode wrap) noise_scroll_velocity = [0,01, 0,01] distorsion = 0,02
morpheus05
Notez que la variable est appelée Time, pas DeltaTime. Si vous utilisez une différence de temps et que votre fréquence d'images est cohérente, vous obtiendrez toujours le même nombre et vous réexécuterez le shader avec les mêmes entrées, obtenant la même sortie (rien ne bouge). Pire encore, si votre fréquence d'images est incohérente, vous obtiendrez des vibrations de va-et-vient. Vous voulez le temps total écoulé, pas le temps delta.
DMGregory
Aussitôt que j'ai frappé envoyer j'ai réalisé que et maintenant ça fonctionne presque. L'animation semble produire des vagues dans le coin inférieur droit et après environ 10 secondes, elle s'estompe, comme des vagues qui s'arrêtent. Quelle pourrait en être la raison?
morpheus05
6

C'est ce qu'on appelle un effet caustique, et la génération de ces effets au moment de l'exécution prend assez de temps, donc cela se fait traditionnellement avec une animation image par image pré-rendue. Il existe des outils qui généreront des images d'animation caustiques pour vous, comme Caustics Generator , qui a une version gratuite pour une utilisation non commerciale. Il existe également des modèles prédéfinis que vous pouvez acheter pour beaucoup moins cher que la version professionnelle de l'outil que j'ai mentionnée.

Notez que les effets caustiques sont également généralement un effet appliqué comme un cookie léger sur un terrain sous-marin ou sur la surface sous-marine. Autrement dit, le mettre à la surface de l'eau tout en regardant vers le bas n'est pas normalement à quoi ressemble l'eau.

Ed Marty
la source
C'est très intéressant, je vais aussi jeter un oeil à ce générateur (bien que j'essaierai la variante du shader si je le comprends ...)
morpheus05
4

Cela ressemble à une texture que vous pourriez générer à partir d'un graphique voronoi, par exemple:

entrez la description de l'image ici

Vous pouvez apporter de petits ajustements fluides au graphique en déplaçant les points; redessiner le graphique chaque image serait assez cher, vous voudrez donc probablement pré-rendre l'animation.

FacticiusVir
la source
4
J'ai déjà rendu des caustiques de cette façon dans un shader dans le passé. Ce n'est pas nécessairement aussi cher que vous pourriez le penser ( voici un exemple de rendu des bords de Voronoi en temps réel dans un shader WebGL ), bien que l'obtention de la bonne forme lisse sur les bords - plutôt que des polygones pointus - puisse être difficile.
DMGregory
Oooh, c'est très bien; J'ai des générateurs de terrain pour lesquels ce serait très pratique.
FacticiusVir
0

Il existe une méthode oldschool, impliquant une couche de texture inférieure et deux demi-textures transparentes pour la réflexion sur le dessus.

Si vous voulez aller jusqu'au bout et que l'eau ne semble pas pleine de vagues clonées ou de cartes de flux de soupe bleu samish, c'est le but.

https://steamcdn-a.akamaihd.net/apps/valve/2010/siggraph2010_vlachos_waterflow.pdf

Pica
la source
3
Bien que les liens puissent aider, ils ne donnent jamais de bonnes réponses. Pourriez-vous développer ces deux méthodes? Comment procéder pour la mettre en œuvre?
Vaillancourt
La première méthode est fondamentalement une très ancienne méthode utilisée pour animer l'eau - vous prenez une texture d'eau de couche de base dont les coordonnées UVW sont décalées dans la direction de votre choix. Maintenant, vous appliquez en plus une carte / bump-map normale que vous déplacez dans une autre direction - si c'est bien fait, cela semble convaincant pour les petites rivières. C'est très limité cependant pour les grandes étendues d'eau, car tout ce qui ressemble à des vagues aura un effet moiré. Le lien explique l'utilisation des organigrammes bien mieux que je ne pourrais.
Pica
Veuillez utiliser la fonction d'édition pour améliorer la question avec ce que vous avez ajouté ici :) Les gens sont habitués à chercher des réponses dans le message, pas dans les commentaires.
Vaillancourt