Frage

Verzeihen Sie mir, wenn diese Frage schon einmal gestellt wurde. Ich habe den ganzen Tag nach einer Antwort darauf gesucht und alles, was mir einfällt, ist Hilfe bei kachelbasierten 2D-Spielen.x~x

Ich versuche, eine Skin-fähige GUI in Direct3D 9 zu erstellen, indem ich eine XML-Datei verwende, die Positionen für jedes Element und eine Option zum Strecken oder Kacheln dieser Elemente enthält.Das Dehnen ist ein recht einfacher Vorgang, aber ich konnte keinen Weg finden, einen kleinen Abschnitt einer Textur zu kacheln.Um eine Textur zu kacheln, würde ich traditionell einfach die UV-Koordinaten auf > 1,0 einstellen, aber die Quelltexturkoordinaten werden nur eine kleine Teilmenge der gesamten Textur sein, z. B. 0,4 bis 0,5.

Ich habe das Gefühl, dass ich etwas wirklich Offensichtliches übersehen habe, aber wie soll ich vorgehen, indem ich einfach Kacheln anordne, statt sie zu dehnen?Ich gehe davon aus, dass es etwas damit zu tun hat, dass es mehr als einen Satz Texturkoordinaten gibt, aber von da an bin ich mir nicht sicher, wohin ich gehen soll.

Das Projekt verwendet derzeit die Pipeline mit festen Funktionen, daher würde ich nach Möglichkeit eine Antwort bevorzugen, die diese verwendet, aber ich würde eine Antwort, die einen Shader verwendet, nicht ablehnen, wenn dies die einzige Möglichkeit wäre.

War es hilfreich?

Lösung

Ich verstehe, dass Sie nur eine Teilmenge der Textur kacheln möchten, oder?Dann wird es kompliziert.

Angenommen, wir möchten die U-Koordinate zwischen den Werten u1 und u2 kacheln, u1 < u2.

Dann brauchen wir eine Funktion f(u), damit

f(0.0) = u1
f(0.5) = (u1+u2)/2
f(0.9999) = u2
f(1.0) = u1
f(1.5) = (u1+u2)/2
f(1.9999) = u2
f(2.0) = u1
and so on...

Eine entsprechende Funktion ist f(u) = frac(u) * (u2-u1) + u1

Das Gleiche gilt für die V-Koordinate, f(v) = frac(v) * (v2-v1) + v1

Beachten Sie, dass es sich um eine Kachelung ohne Spiegelung handelt.Wenn Sie eine Spiegelung benötigen, sollte die Funktion eine Dreieckswellenfunktion sein t(x) = arcsin(sin(pi*(x-0.5)))/pi+0.5 Und f(u) = t(u) * (u2-u1) + u1.Die Verwendung trigonometrischer Funktionen kann jedoch teuer sein.

Ich weiß nicht, ob es mit einer festen Pipeline möglich ist, aber Sie können es problemlos im Pixel-Shader (HLSL-Code) machen:

// float2 tex_coord -> (u,v) from vertex shader, in [0,n] range,
//                     n - number of repetitions
// float2 tex1, tex2 -> constants, subrange of [0,1] coords that will be tiled

// no mirroring
float4 color = tex2D(sampler, frac(tex_coord) * (tex2-tex1) + tex1);

oder

// mirroring, t(x) = arcsin(sin(pi*(x-0.5)))/pi+0.5
float4 color = tex2D(sampler, t(tex_coord) * (tex2-tex1) + tex1);

BEARBEITEN:Eine bessere Methode zur Berechnung der Dreieckswellenfunktion: t1(x) = abs(2(0.5x-floor(0.5x+0.5))) oder t2(x) = abs(2(frac(0.5x+0.5))-1) (nicht genau dasselbe wie t1, aber korrekt für nicht negative Zahlen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top