Domanda

Mi perdona se questo è stato chiesto prima, ho cercato la risposta a questo tutto il giorno e tutto quello che sto arrivando è un aiuto con giochi 2D basati su piastrelle. x ~ x

Sto cercando di creare una GUI Skinnable in Direct3D 9, utilizzando un file XML che ha posizioni per ciascun elemento e un'opzione per allungarsi o piastrelle. Stretching è una procedura abbastanza semplice, ma non sono stato in grado di capire un modo per piastrellare una piccola sezione di una trama. Tradizionalmente per piastrella una consistenza, avrei appena impostato le coordinate UV su> 1.0, ma le coordinate di texture sorgente saranno solo un piccolo sottoinsieme dell'intera consistenza, ad esempio da 0,4 a 0,5.

Ho una sensazione che ho perso qualcosa di veramente ovvio, ma come farei semplicemente piastrellatura invece di stretching? La mia migliore ipotesi è che ha qualcosa a che fare con avere più di una serie di coordinate di consistenza, ma da lì, non sono sicuro di dove andare.

Il progetto utilizza attualmente la pipeline funzione fissa, quindi preferirei una risposta usando quella se possibile, ma non rifiuto una risposta che usa uno shader se è l'unico modo.

È stato utile?

Soluzione

Capisco che vuoi piastrellare solo un sottoinsieme della trama, giusto?Quindi le cose diventano complicate.

Supponiamo che vogliamo tessare u-coord tra i valori U1 e U2, U1

Allora abbiamo bisogno di una funzione f (u), in modo che

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...
.

Una funzione appropriata è f(u) = frac(u) * (u2-u1) + u1

Lo stesso vale per V-Coord, f(v) = frac(v) * (v2-v1) + v1

Si noti che è piastrellatura senza mirroring.Se è necessario un mirroring, la funzione dovrebbe essere una funzione a onda triangolare, che è t(x) = arcsin(sin(pi*(x-0.5)))/pi+0.5 e f(u) = t(u) * (u2-u1) + u1.L'uso di funzioni trigonometriche può essere costoso però.

Non so se è possibile con la tubazione fissa, ma puoi farlo facilmente in pixel shader (codice HLSL):

// 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);
.

o

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

Modifica: Un modo migliore per calcolare la funzione triangolare-onda: t1(x) = abs(2(0.5x-floor(0.5x+0.5))) o t2(x) = abs(2(frac(0.5x+0.5))-1) (non esattamente lo stesso di T1 ma corretto per numeri non negativi).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top