Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

06.12.2011, 23:40

Texture Blending mit einem Texture2D-Array

Hi

Ich habe ein Terrain und möchte gerne aus einem Texture2D-Array verschiedene Texturen blenden.
Da kommt es jetzt aber zu dem Problem das man durch die Textur die die Indexe speichert, harte Kanten zwischen Übergängen bekommt, wie man auf dem folgenden Bild gut sehen kann:

(Link)


Jetzt habe ich ein bisschen rumprobiert und durch einen Denkanstoß von BlazeX habe ich mal probiert meine Index-Werte selber zu interpolieren, momentan interpoliere ich dafür zwischen 9 verschiedenen Werten.
Unter bestimmten Umständen sieht das dann auch recht ansehnlich aus, aber wie zum Beispiel auf dem nächsten Screenshot zusehen(mit nur einer Reihe an Werten), wird eine Seite ordentlich interpoliert wohingegen die andere wieder eine harte Kante hat:

(Link)


Vielleicht hat ja jemand von euch noch eine Idee was man machen könnte ;)

Schon mal vielen Dank im voraus
Zero

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

06.12.2011, 23:48

Hmm. Du beschreibst hier maximal schwammig deine Lösung eines Problems, das du ebenfalls nicht näher beschreibst und erwartest jetzt genau was?

3

07.12.2011, 00:05

Okay, dann beschreibe ich das nochmal genauer.
Also ich möchte gerne normales Textur-Blending mit einem Texture2D-Array erreichen.
Wenn man das normal macht hat man ja seine 3 Texturen mit den Weight-Werten und seine 3 Texturen.
Ich habe jetzt aus den 3 Texturen mit den Weight-Werten eine Textur gemacht, diese enthält in den xyz die dementsprechenden Weights, in der w Komponente liegen 3 Index-Werte die jeweils den Index angeben für den aus dem Texture2D-Array gesampled werden.
Beim normalen Blending ohne Texture2D-Array nutzt man ja einen einfachen Sample der Wert aus der Weight-Textur geholt. Dieser Wert ist ja dann bereits billinear oder wie auf immer bereits interpoliert, dadurch kommt es dazu das man keine harten Kanten bekommt. Mit den harten Kannten meine ich das die eine Textur nicht weich in die andere Textur übergeht, sondern das die geblendete Textur abbrubt aufhört. Das ist halt dem zu verschulden das ich bei meiner Version mit dem Texture2D-Array die Funktion Load nehme um den Wert aus der Textur zu holen, dabei gibt es ja logischerweise keine Interpolation.

So und jetzt kommen wir zu meinem Versuch das Teil zu lösen:

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
float GetWeight(int id, float2 uv)
{
              // ausrechnen mit welchen Werten wir interpolieren müssen
    float2 f = frac(uv * 512.f); // 512 ist die Texturgröße
    
              // Hier werden die Daten aus der Textur geladen
    
              // Die Zeilen interpolieren
    float oben = lerp(lerp(t0, t1, f.x), t3, f.x);
    float mitte = lerp(lerp(l0, t2, f.x), tr, f.x);
    float unten = lerp(lerp(l1, br, f.x), br, f.x);

              return lerp(lerp(oben, mitte, f.y), unten, f.y); 
}


So ich hoffe die Funktion ist verständlich, ist ein bisschen eingekürzt aber das wichtigste ist enthalten.
Wie man sieht berechne ich erst mit welchen Stärken in X-Richtung und Y-Richtung interpoliert werden soll.
Dann hole ich die 9 Werte aus der Textur, also einmal alle Werte um die momentane UV-Position und die momentane selbst.
Im letzten Schritt interpoliere ich erst in jede Zeile in X-Richtung mit sich selbst, danach werden dann noch alle in Y-Richtung interpoliert.

Und dieses Resultat wird dann zum blenden benutzt.

Ich hoffe das ist jetzt verständlicher.

drz

Frischling

  • Private Nachricht senden

4

07.12.2011, 02:00

Das Problem im ersten Bild kommt mir bekannt vor. Offensichtlich benutzt du keinen Filter für deine Alphamap bzw wird er nicht angewendet. (MIN_MAG_MIP_LINEAR) Hatte das selbe Problem, weil ich keine MipMaps beim Erstellen im Texture2d Array erzeugt habe. Vielleicht solltest du dich dort mal versuchen.

MfG drz

5

07.12.2011, 10:38

Ja du hast Recht das ich keine Filterung für die Alphamap(bei mir Weight-Texture genannt^^), aber meine Weight-Texture liegt ja auch nicht in dem Texture Array drinnen, da liegen nur die Texturen drin die ich samplen möchte.
Die Weight-Texture ist wie oben beschrieben eine Textur die aus 4 floats besteht, auf diese greife ich mit Load zu, weil sonst würde er mir auch noch die Indices in der W-Komponente auch interpolieren und das will ich ja aber nicht.

stwe

Frischling

  • Private Nachricht senden

6

07.12.2011, 11:05

Also ich weiss nicht genau, ob der Beitrag hilft oder an Deinem Problem vorbeigeht: http://www.riemers.net/eng/Tutorials/XNA…titexturing.php . Das ist zwar in C#, aber lässt sich einfach in C++ umsetzen.

Einfach vier Texturen Deiner Wahl nehmen. Dann erhält die VertexStruktur ein zusätzliches XMFLOAT4, welches den Pixelanteil der jeweiligen Texturen je nach Höhe speichert. Alles ab in den Shader und siehe da....schöne Übergänge.

drz

Frischling

  • Private Nachricht senden

7

07.12.2011, 16:18

Wenn du keinen Filter für deine Weighttexture benutzt, muss ja eigentlich so ein Ergebnis raus kommen. Vielleicht solltest du etwas mehr Code zeigen, den kompletten Shader damit dir geholfen werden kann.

Edit. 4 x Floats pro Texel. Ist das nicht sehr viel? Oder verstehe ich dich da falsch.

8

07.12.2011, 18:02

4 Floats pro Pixel auf der Textur mit den Daten zum Blenden und diese Textur ist 1024x1024 groß.

Ja na klar, es kommt ja auch so das richtige Ergebnis raus, mein Problem ist einfach nur das die Übergänge zu hart sind, hier mal ein Screenshot dazu:


(Link)


Und wenn ich jetzt meine Interpolation(wie in meinem 2ten Posting beschrieben) anwende kommt dies raus:


(Link)


Das sieht ja schon mal recht gut aus, aber unter bestimmten Umständen(wie zum Beispiel auf meinem 2ten Bild im ersten Posting zu sehen ist) funktioniert das nicht so wie es soll.

drz

Frischling

  • Private Nachricht senden

9

07.12.2011, 18:16

4 Floats pro Pixel ist meiner Meinung nach zu viel. Ich mache das selbe mit 4 Byte pro Pixel in der Weightmap. Also eine ganz normale rgba Texture bei der jeder Farbkanal + Alpha für für eine Oberflächentextur steht. Das Ergebnis sollte dann das zweite Bild in deinem zweiten Posting sein. Woher der Schnittcut des zweiten Bildes im ersten Posting kommt, wird dir keiner genau sagen können, ohne zu sehen, wie du alle deine Daten bereit stellst. Dieser Fehler sieht aber nach einem Problem mit dem Weightmap-Filter aus.

10

07.12.2011, 18:25

Ja ich nutze aber nur 3 Floats für die Weight, das 4te Float ist für die Indices.
Wie gesagt ich nutze ein Texture2D-Array was alle Texturen hat die geblendet werden können.
Meine Weight-Texture existiert nur einmal, ich kann also gleichzeitig 3 verschiedene Texturen blenden.
Die Weigt-Werte kommen dabei aus xyz und in der W-Komponente stecken die 3 Indices um die Textur in dem Texture2D-Array auszuwählen.

@WeightMap-Filter: Wie gesagt ich nutze die Funktion "Load", diese Funktion holt die Daten ohne einen Filter aus der Textur, das weiß ich und das will ich auch, weil sonst meine W-Komponente auch interpoliert werden würde und ich so nicht die 3 richtigen Indices bekommen würde.

Werbeanzeige