2D Wasseroberflächenprofil

9

Ich versuche, den Effekt der Wasseroberflächendicke mit einem Vertex-Fragment-Shader zu erzeugen.

Ich bin in einer 3D-Spielumgebung, aber es ist eine Bildlaufansicht, also eine "2D" -Ansicht. Hier ist ein gutes Tutorial zum Erstellen eines solchen Effekts in echtem 2D mit dem Fragment-Shader.
Aber das kann in meinem Fall nicht verwendet werden, denke ich. Im Moment habe ich nur ein Flugzeug, auf dem ich die Brechung anwende.

Brechung

Und ich möchte den Wasserdickeneffekt anwenden. Aber ich weiß nicht, wie ich es machen soll.
Ich versuche im Moment nicht, eine Wasserverformung / -verschiebung mithilfe des Scheitelpunkts zu erzeugen. Dies ist nicht der Punkt.

Ich weiß nicht, ob es mit einem einfachen Quad möglich ist, sollte ich vielleicht ein Objekt wie dieses verwenden.

System

Hier sind einige Beispiele.

1 2 4 Rayman

Ich habe keine Ahnung, wie ich diesen Effekt erzeugen soll.

Vielen Dank !

[ BEARBEITEN ] Rayman-Wassereffekt hinzugefügt, um eine bessere Referenz des Effekts zu erhalten.

Matte
quelle
Wie machst du deinen Wassereffekt aktuell? Wenn der erste Screenshot im Beitrag Ihnen gehört, zeichnen Sie anscheinend ein 2D-Quad über die Szene mit einem Shader, der sie verzerrt. Wenn dies korrekt ist, warum können Sie dann nicht den Anweisungen im Lernprogramm folgen, das auch auf der Verwendung einer verzerrten 2D-Textur basiert?
Nathan Reed
Ich habe ein 3D-Quad mit einem Vertex-Fragment-Shader, der den Hintergrund verzerrt (der Hintergrund wird von der Unity GrabPass-Funktionalität erfasst). Ich denke nicht, dass die Verwendung einer 2D-Textur eine gute Idee ist. Ich dachte an etwas Allgemeineres mit anpassbaren Parametern, aber es scheint, dass es keinen anderen Weg gibt ... und es wäre langsamer, nein?
MaT

Antworten:

1

Geben Sie im Shader einen Wert an, der die Nässe angibt. Kleiner als 0 bedeutet Luft, größer als 1 bedeutet Wasser und dazwischen bedeutet Meniskus.

Hier ist ein Pseudocode:

vec2 uv2 = bigWaves(uv); // modify the texture coords to create a wavy water effect
float wetness = (uv2.y - 0.1) * 100;

if( wetness<0.0 )
{
    gl_Fragment = texture2D(screen_texture,uv); // is air - no refraction or effect
}
else if( wetness>1.0 )
{
    vec2 uv3 = smallWaves(uv2); // modify the texture coords to create a ripply water effect
    gl_Fragment = texture2D(screen_texture,uv3); // is water - with refraction
}
else
{
    gl_Fragment = vec4(1,1,1,1); // solid white meniscus
}

Dies ist das einfachste, was ich machen kann. Wenn ich es wäre, würde ich etwas komplizierteres tun, um den Meniskus zu antialisieren und dort mehr Brechung anzuwenden oder so, aber ich kann Ihnen nicht sagen, was, weil es ästhetische Iterationen erfordern würde. Außerdem würde ich die Wasserprobe tönen und verwischen. Aber das alles überlasse ich dir.

DaleyPaley
quelle
Ja, das ist eine gute Idee! Ich bin völlig einverstanden mit Unschärfe und Farbton. Ich füge auch einen Tiefengradienten (Y) hinzu (möglicherweise einen anderen Tiefengradienten (Z)). Ich sollte auch in der Meniskuszone einen anderen Brechungseffekt hinzufügen, aber im Moment versuche ich, einen Welleneffekt wie bei Rayman zu erzielen. Aber ich weiß nicht wie. Vielleicht sollte ich verschiedene Texturen für den Meniskus verwenden, um diesen doppelten Effekt zu erzielen. Ich weiß nicht, ob du weißt, was ich meine.
MaT