INDICE: it.Of Effects and Shaders
Precedente: Textures Multiple
Prossimo: Vertexshader, i Preparativi
Come promesso in Pixels Adiacenti qui verrà spiegato come concatenare le sfocature orizzontali e verticali per ottenere una morbida sfumatura in entrambe le direzioni.
L'output del renderer Pass1 diventa una texture la cui risoluzione è impostata per essere uguale a quella dell'immagine originale. Questa texture viene quindi usata come input per l'effetto sfocatura verticale in Pass2. In questo modo si può concatenare qualsiasi numero di effetti (hardware in dotazione permettendo).
Facendo così è possibile generare effetti che ri-acquisiscono il loro output come un input texture, generando così un feedback.
Un esempio potrebbe essere Cellular Automata, e tra i più popolari John Horton Conway's "Game of Life".
Più che di un gioco si tratta di una simulazione basata su una griglia di celle (proprio come i pixels in una texture) che possono essere o bianchi (vivi) o neri (morti). Poiché il risultato viene usato come punto di partenza per la successiva generazione della simulazione, viene generato un feedback che permette alla simulazione di essere eseguita all'infinito. Naturalmente c'è bisogno di un punto di partenza iniziale, che è realizzato in questo esempio usando il mouse per aggiungere cellule viventi, vedere la patch relativa del pacchetto of-effects-and-shaders.
Game of Life ha 3 semplici regole:
Nel pixelshader quindi dobbiamo contare per ogni pixel tutti quei pixels adiacenti che sono vivi e stabilire secodo le regole se il pixel sarà ancora vivo o meno alla successiva generazione.
float2 PixelSize; float4 PS(vs2ps In): COLOR { //campiona il pixel attuale float4 center = tex2D(Samp, In.TexCd); //prepara gli offsets dei pixels per x e y float2 offX = float2 (PixelSize.x, 0); float2 offY = float2 (0, PixelSize.y); //campiona i pixels adiacenti e somma i loro stati float alive = 0; alive += tex2D(Samp, In.TexCd - offY).r; alive += tex2D(Samp, In.TexCd - offY - offX).r; alive += tex2D(Samp, In.TexCd - offY + offX).r; alive += tex2D(Samp, In.TexCd + offY).r; alive += tex2D(Samp, In.TexCd + offY - offX).r; alive += tex2D(Samp, In.TexCd + offY + offX).r; alive += tex2D(Samp, In.TexCd - offX).r; alive += tex2D(Samp, In.TexCd + offX).r; //con esattamente tre cellule vive adiacenti diventa una cellula viva (birth). if (center.r == 0 && alive == 3) { center.rgb = 1; } //Una cellula viva con due o tre cellule vive adiacenti rimane viva (survival). else if (center.r == 1 && (alive == 3 || alive == 2)) { center.rgb = 1; } //In tutti gli altri casi la celula muore o rimane morta (overcrowding or loneliness). else { center.rgb = 0; } return center; }
Un'altra cosa importante da notare nell'effetto sono le impostazioni dello stato del campionatore:
sampler Samp = sampler_state //campionatore per il lookup della texture { Texture = (Tex); //applica una texture al campionatore MipFilter = NONE; //stati del campionatore MinFilter = POINT; MagFilter = POINT; };
Nota come tutte le azioni di filtro sia disabilitate. Questo consente di lavorare con pixels unici davvero, non consentendo alla scheda grafica di interpolare tra i pixels, cosa che non avrebbe senso visto che in quest'applicazione un pixel può essere solo bianco o nero, e non una sfumatura di grigio.
anonymous user login
~6d ago
~8d ago
~10d ago
~14d ago
~14d ago
~21d ago
~27d ago
~27d ago
~28d ago
~1mth ago