» it.Tutorial Effects - Textures Multiple
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

it.Tutorial Effects - Textures Multiple

English | Mandarin | Japanese

INDICE: it.Of Effects and Shaders
Precedente: Pixels Adiacenti
Prossimo: Passaggi Multipli


Textures e Campionatori

Come già detto nel capitolo Coordinate delle Texture, una texture è sempre associata ad un campionatore, sampler. Infatti la texture in sé non è di alcuna utilità se non viene inserita in un campionatore. Infatti nel nostro codice

  1. texture Tex <string uiname="Texture";>;
  2. sampler Samp = sampler_state    //Campionatore per il lookup della texture
  3. {
  4.     Texture   = (Tex);          //applica una texture al campionatore
  5.     MipFilter = LINEAR;         //stati del campionatore
  6.     MinFilter = LINEAR;
  7.     MagFilter = LINEAR;
  8. };

alla riga 2 viene specificata una variabile di tipo texture chiamata Tex. L'annotazione tra <...> specifica come il corrispondente pin texture sul nodo apparirà come Texture. Di seguito troviamo il blocco del campionatore chiamato Samp a cui è associata la texture Tex come si vede nella riga 5.
Le altre voci sono ulteriori stati del campionatore. Per una lista di tutti gli stati possibili, visitare Effect States (Direct3D 9).

Pins per Textures Multiple

Con i pins texture sugli shaders non è possibile accedere alle slices per effettuare lo spread, avendo un solo pixelshader. Per farlo, è necessario specificare più variabili di tipo texture ed i rispettivi campionatori. Si dovrà quindi copiare il blocco di codice qui sopra per ogni texture in più ed assicurarsi di assegnare nomi unici alle variabili texture e sampler ed alle annotazioni, oltre ad assegnare ad ogni sampler una texture diversa. Per motivi hardware, non è possibile inserire più di 16 texture input pins in un effetto.

Dissolvenza tra due Textures.

Un tipico esempio dell'uso di più textures in un pixelshader è la dissolvenza. Dopo aver duplicato il codice come descritto sopra, il codice per miscelare le textures potrebbe assomigliare a questo:

float Fade = 0.5;
float4 PS(vs2ps In): COLOR
{
    float4 colA = tex2D(SampA, In.TexCd);
    float4 colB = tex2D(SampB, In.TexCd);
 
    return lerp(colA, colB, Fade);
}

dove la funzione lerp() esegue esattamente questa interpolazione lineare:

 colB * Fade + colA * (1 - Fade)

Usare una Maschera per Miscelare due Textures

Un altro caso comune è quello in cui si hanno due textures ed una maschera in scala di grigi che definisce le parti da miscelare delle due textures. Per ciascun pixel bianco della maschera sarà visibile il corrispondente pixel della texture A, per quelli neri i corrispondenti della texture B, e per ogni gradazione intermedia i pixels delle due textures miscelati.

Definisci una terza texture col nome di Mask , assegnale un campionatore SampMask ed il pixelshader apparirebbe così:

float4 PS(vs2ps In): COLOR
{
    float4 colA = tex2D(SampA, In.TexCd);
    float4 colB = tex2D(SampB, In.TexCd);
    float4 mask = tex2D(SampMask, In.TexCd);
 
    return lerp(colA, colB, mask.r);
}

Posto che la texture maschera debba essere in scala di grigi, si può accedere a tutti i canali del colore come valori di dissolvenza/miscelazione (nell'esempio viene usato il canale, componente, rosso tramite .r). Nota come si possa semplicemente usare anche la funzione lerp(), in cui ora il terzo parametro può essere un valore differente per pixel, mentre prima veniva usata una costante, che era la stessa per tutta la texture, attraverso il parametro Fade.

Displacement di una texture tramite un'altra.

Nel capitolo Coordinate delle Texture è stato mostrato come modificare via codice le coordinate di una texture prima di campionare un pixel per ottenere vari effetti di displacement.

Invece che inserire un offset nel pixelshader si possono interpretare i valori dei colori di una texture ed usarli come offset per le coordinate di un'altra. Così si può generare più intuitivamente la texture per l'offset lavorando nella patch. Ecco come ottenere l'effetto di disturbo qui sotto:

float4 PS(vs2ps In): COLOR
{
    float4 offset = tex2D(SampOff, In.TexCd) - 0.5;
    float4 col = tex2D(SampA, float2(In.TexCd.x + offset.r, In.TexCd.y));
    return col;
}

In questo esempio si genera un nuovo input per una texture e lo si assegna ad un campionatore SampOff. Come si vede dal codice, questo campionatore per l'offset prima viene campionato e solo dopo il valore (che sappiamo restare nell'intervallo 0...1) offset.r (posto che l'offset che cerchiamo si trovi nel canale rosso della texture da usare per il displacement) viene usato come offset per la componente x delle coordinate della texture in ingresso. Il -0.5 si usa per far sì che il valore di offset che sta tra 0 e 1 si attesti intorno allo 0 così da poter ottenere offsets di .x positivi e negativi.

Nella patch viene usato un nodo DynamicTexture (EX9.Texture Value) con il pin Width impostato su 1 ed il pin Height impostato per corrispondere alla texture per la quale vogliamo l'effetto disturbo. Questo fa sì che l'effetto operi per linee. Connettendo uno spread di valori casuali al pin Red del nodo DynamicTexture (EX9.Texture Value) diventa facile impostare gli offsets per linea.

Un Filtro per la Texture

Diciamo a questo punto che non si vuole un effetto così definito, e che vogliamo solo 10 offsets. Impostando il pin Height a 10 nel nodo DynamicTexture (EX9.Texture Value) ed assegnandogli 10 valori casuali, avremmo questo risultato:

Succede questo: la texture usata come offset, ora di soli 10 px in altezza, viene comunque campionata 512 volte (l'altezza della texture da deformare). Per campionare 10 valori 512 volte deve essere applicato qualche algoritmo di interpolazione/ricampionamento per decidere quale dei 10 valori viene campionato in corrispondenza di ciascuno dei 512 pixels dell'altra texture. Questo algoritmo può essere impostato usando lo stato MagFilter per il campionatore. Immettete POINT ed osservate la differenza.

texture Off <string uiname="Offset Texture";>;
sampler SampOff = sampler_state    //campionatore per il lookup della texture
{
    Texture   = (Off);          //applica una texture al campionatore
    MipFilter = LINEAR;         //stati del campionatore
    MinFilter = LINEAR;
    MagFilter = POINT;
};

Prossimo: Passaggi Multipli
Precedente: Pixels Adiacenti
INDICE: it.Of Effects and Shaders

anonymous user login

Shoutbox

~59min ago

~6h ago

colorsound: Hi guys some poc of laser and projection ;D https://vimeo.com/colorsound/laser-projection-interaction

~20h ago

mediadog: @metrowave I just saw the Wilfred Lumia exhibit in DC - I wept. Pics/videos do it no justice, analog = infinite resolution!

~3d ago

udo2013: BeatDetector(bass)not working.ErrorCode from red node:"PLUGINS \BassSound dll BassSound Data BeatDetectorNode" is missing.WhatToDo?

~6d ago

skyliner: the vcard page is assembled by personal settings + user page