Texturesplatting on programmable GPU (HLSL)

Dev²
Verfügbare Informationen zu "Texturesplatting on programmable GPU (HLSL)"

  • Qualität des Beitrags: 0 Sterne
  • Beteiligte Poster: melwyn
  • Forum: Dev²
  • Forenbeschreibung: -= Code Games Or Die Trying =-
  • aus dem Unterforum: Snipplets und Beispielcode
  • Antworten: 1
  • Forum gestartet am: Dienstag 22.05.2007
  • Sprache: deutsch
  • Link zum Originaltopic: Texturesplatting on programmable GPU (HLSL)
  • Letzte Antwort: vor 16 Jahren, 10 Monaten, 18 Tagen, 19 Stunden, 1 Minute
  • Alle Beiträge und Antworten zu "Texturesplatting on programmable GPU (HLSL)"

    Re: Texturesplatting on programmable GPU (HLSL)

    melwyn - 29.05.2007, 11:12

    Texturesplatting on programmable GPU (HLSL)
    Ich dachte ich offenbare mal kurz eine Texture Splatting Methode, so wie ich sie mir momentan erarbeitet habe... Kein Wunder oder Hexenerk, sondern ziemlich simpel und noch ausbaubedürftig....

    Also man nehme ein Stück einer Landschaft und stelle sich vor, man möchte auf diesem mehrere Texturen mit einer hübschen Transition dazwischen anzeigen. Wir geht man vor. Man nehme x Texturen, die auf dem Stück vorkommen und bindet sie in das Projekt ein. Wobei X bei meinem Beispiel bisher auf 5 limitiert ist. Danach erstellt man Alphamaps (erstmal starr, später per code oder durch mapeditor generiert). Diese sollten nicht alzu gross ausfallen (ca 64x64 pixel). Alphamaps sind einfach nur Bilder in Grautönen. Eine normale Texture (Rot, Grün, Blau, Alpha) kann also zusätlich zum Alphakanal noch Rot Grün Blau abspeichern, die wir in dem Falle von Alphablending ja garnicht benötigen. Da HLSL aber die Möglichkeit beherbergt die einzelnen Kanäle abzufragen, können wir einfach den RGB Kanal für weitere Alphamaps missbrauchen. Wir können also 4 Alphamaps in eine Textur packen und sparen dadurch enormen Speicherplatz. Auch die Übergabe der Texturen an den Pixelshader ist wesentlich geringer und daher schneller! Supi! Also... Alphatextur, mit 4 verschiedenen Alphatexturen, 5 normale Texturen und ein hübsches Mesh, welches das Terrain darstellt.

    Nehmen wir an das Terrain Teil Mesh ist 17x17 Vertecies gross (Entspricht als TriangleStrip einem Spielfeld von 16x16 Felder). Dann müssen wir es schaffen die Alphatexture EINMAL komplett über das ganze Mesh zu ziehen. Speich Vertecie 0,0 hat die UV Coordinaten von 0,0 wobei Vertecie 17,17 die UV Coordinaten von 1,1 hat. Sprich alle UV Coords dazwischen werden einfach errechnet mit VertexX durch AnzahlGesamtVertecies (in unserem Fall hätte dann Vertex 5,10 die UV Coordinaten 0.29411, 0.58233 (5:17, 10:17).

    Soo... Da unsere anderen Texturen aber nicht einmal komplett über das Mesh gezogen werden sollen, sondern besser mehrfach (weil mehr details). Müssen wir für diese eigene UV Coordinaten übergeben. Bei 5 verschiedenen Texturen wären das 5 UV Coords, was viel zu viel ist, also beschränken wir das ganze auf eine UV Coord für alle 5 Texturen. Wenn die Texturen alle gleich gross sind (Bsp: 256x256), sieht das ganze recht vernünftig aus. Leider bringt XNA kein Vertexformat mit sich, was zwei UVCoords unterstützt, deshalb wird man kaum drum rumkommen, sich ein eigenes zu erstellen.

    So das heisst wir übergeben dem Shader später 6 Texturen, ViewProjection Matrix, World Matrix und nen haufen Vertecies mit jeweils 2 UV Coords.

    Die 6 Texturen kommen folgendermaßen zusammen:
    Texture 1: ist die Grundtextur... die kommt einfach überall drauf (Beispielsweise Wiese)
    Texture 2-5: Alphageblendeten Texturen (Stein, Matsch, Sand, Schnee)
    Texture 6: Die Alphatextur wobei Kanal R (Rot) die Alphawerte für Texture 2 enthält, Kanal G die Alphawerte für Texture 3, Kanal B die Alphawerte für Texture 4 und Kanal A die Alphawerte für Texture 5 beinhaltet.

    Soweit noch alles gut. Das ganze schicken wir an den Pixelshader, der dann folgendes daraus macht!

    Code:
    PixelToFrame Output = (PixelToFrame)0;   
             
    vector BaseColor = tex2D(Tex1Sampler, PSIn.TexCoords0);
    vector Tex1Color = tex2D(Tex2Sampler, PSIn.TexCoords0);
    vector Tex2Color = tex2D(Tex3Sampler, PSIn.TexCoords0);
    vector Tex3Color = tex2D(Tex4Sampler, PSIn.TexCoords0);
    vector Tex4Color = tex2D(Tex5Sampler, PSIn.TexCoords0);
    vector Alpha = tex2D(AlphaSampler, PSIn.TexCoords1);
       
    vector l = Alpha.r * Tex1Color + (1.0 - Alpha.r) * BaseColor;
    l = Alpha.g * Tex2Color + (1.0 - Alpha.g) * l;
    l = Alpha.b * Tex3Color + (1.0 - Alpha.b) * l;
    l = Alpha.a * Tex4Color + (1.0 - Alpha.a) * l;
    Output.Color = l;               

    return Output;


    Das wars... Bilder folgen, und ich werd auch nochmal nen ganzen noch verständlicheres und ausführlicheres Tutorial darüber schreiben, aber im Endeffekt wird es nichts anderes beschreiben, was nicht schon Bloom, Glasser und Riemer beschrieben haben. Das Ergebnis sieht aufjedenfall schon ganz sehenswert aus und ist sicherlich als gutes Fundament für ein Multitextured 3d Terrain geeignet!



    Mit folgendem Code, können Sie den Beitrag ganz bequem auf ihrer Homepage verlinken



    Weitere Beiträge aus dem Forum Dev²



    Ähnliche Beiträge wie "Texturesplatting on programmable GPU (HLSL)"