Wasserberechnung



  • Hallo zusammen
    Ich bin gerade dabei, einen Wassershader zu schreiben und mir ist da etwas aufgefallen. Ich verwende Wellen sowie eine mehrschichtige Normalmap. Im Moment mache ich es noch so, dass ich im Pixelshader, den Normalenvektor des Vertex (Abhängig von der Welle) mit den verschiedenen Normalmaps addiere und am Ende normalisiere, um den entgültigen Normalenvektor eines Pixels zu bestimmen. Ausgehend von diesem berechne ich schlisslich die Wasserreflexionen sowie die komplette Beleuchtung.

    Leider ist mir aufgefallen, dass bereits bei einem minimalen Wellengang (Amplitude < 0.1f) die reflektierte Umgebung auf dem Wasser bis zur Unkenntlichkeit verzerrt wird, was auch Sinn macht, wenn ich an einen gewölbten Spiegel denke. Ich habe nun mal versuchsweise für die Reflexionsberechnung den Normalen des Vertex nicht dazuaddiert und siehe da. Das Wasser sieht prächtig aus, zumindest solange ich keine hohen Wellen habe, denn ansonsten spiegelt er mir natürlich Dinge, die da gar nicht sein dürften. Wie machen denn das die Profis?


  • Mod

    wir machen es so 😉
    (hab ich vor 5jahren oder so mal geschrieben im FXComposer)

    es ist schon ok wenn es zerstreut ist, aber da gibt es viele wege das zu berechnen.
    wie schauen denn deine zwei moeglichkeiten bisher aus? (bild!)



  • @Rapso
    Hehe, dein Shader sieht ja super aus! 🙂 Ich persönlich möchte von meinem erst Bilder Posten, wenn ich mit dem Resultat zufrieden sein werde :p

    Das mit dem Tangetspace habe ich möglicherweise nicht richtig verstanden. Ich schreibe jetzt einfach mal meine Gedanken und Erfahrungen dazu auf, dann kannst du mir gegebenenfalls beim einen oder anderen Punkt wiedersprechen:

    Also, der Tangentspace beschreibt IMHO ein Koordinatensystem, welches die Basisvektoren Tangent und Binornmal auf den Tangenten eines einzelnen Vertices in Betrachtnahme sämtlicher benachbarten Vertices hat. Der Normalenvektor wird schliesslich aus dem Kreuzprodukt jener zwei Vektoren. Wenn ich das richtig verstanden habe, dann hat demzufolge jeder Vertex einen anderen Tangentspace (ausser es handelt sich um eine Eben oder einen Würfel od. ähnliches)

    Für das PerPixelLighting und benachbahrte Technologien wird nun für jeden Vertex berechnet, wohin die Basisvektoren des Tangentspace im Objectspace hinzeigen, was eine 3x3 Transformationsmatrix ergibt. Bei meinem Wassershader müssen die Tangenten nun in jedem Frame neu berechnet werden, weil sich ja deren Positionen im Raum laufend verändern. Nun übergebe ich Basisvektoren des Tangentspace im Worldspace mittels Texturkoordinaten dem Pixelshader. Aufgrund der Tatsache, dass Texturkoordinaten interpoliert werden, gehe ich davon aus, dass schliesslich jeder einzelne Pixel seinen eigenen Tangentspace hat.

    Und nun kommt meine Frage: Wieso soll ich nun die Lichter und Camera und alles in den Tangentspace umrechnen? Ist es nicht besser, jeden einzelnen Pixel in den Objectspace umzurechnen?

    Mfg Samuel

    P.S.
    Sehe ich das richtig, dass die Basisvektoren des Tangentspace bei einer Plane mit der des Objectspace identisch sind, also die Identitätsmatrix ergeben?
    Und der Normalenvektor des Tangentspace auf der Unterseite des Planes würde im Objectspace nach -1.0f zeigen oder?

    Etwas beschäftigt mich auch noch: Ich sehe immer folgende Matrix in den Büchern:

    |Tx,Bx,Nx|
    |Ty,By,Ny|
    |Ty,By,Ny|

    Also ich sehe das schon richtig, dass diese in Direct3D ein wenig anders aussieht?

    |Tx,Nx,Bx|
    |Ty,Ny,By|
    |Ty,Ny,By|

    Wie gesagt, ich habe das jetzt einfach mal alles so aufgeschrieben, wie ich es verstanden habe, was möglicherweise mehr oder weniger falsch sein kann, also bitte nicht böse sein! 😃



  • Wieso soll ich nun die Lichter und Camera und alles in den Tangentspace umrechnen? Ist es nicht besser, jeden einzelnen Pixel in den Objectspace umzurechnen?

    Anstatt *pro Pixel* jeden Normalenvektor (der im Tangenten-Raum gegeben ist) zu transformieren, ist es performanter die anderen Vektoren *pro Vertex* in den Tangenten-Raum zu uebertragen.
    Diese Vorgehensweise stammt aber auch aus einer Zeit wo 3 Dot-Produkte im Pixelshader was Heftiges waren.


Anmelden zum Antworten