notJustCode.it
 
\\ Home : Articoli
Rendering su Cubemap
Di RobyDx (del 05/08/2007 @ 16:34:57, in Direct3D10, linkato 3980 volte)

Le cubemap sono particolari rappresentazioni di texture esistenti in DirectX ormai da molte versioni. Come dice il nome, una cubemap è una texture che contiene al sue interno 6 superfici quadrate disposte a cubo.

Il motivo per cui queste sono state create è sostanzialmente per simulare riflessioni dell'ambiente circostante gli oggetti (il cosidetto environment mapping). Come ripeto spesso nei miei tutorial, ogni volta che si renderizza un oggetto questo non può sapere cosa c'è intorno e l'unico modo per un oggetto di vedere ciò che c'è intorno a se è quello di renderizzare su una texture da utilizzare successivamente.

 

 

 

La comodità delle cubemap è che al momento dell'utilizzo all'interno dello shader utilizzerete come coordinata texture un vettore direzione che rappresenta la direzione dal centro della cubemap verso il pixel che vogliamo leggere. Si capisce facilmente che in questo modo basterà calcolare in ogni pixel l'angolo di riflessione ed utilizzarlo in fase di lettura delle texture per ottenere il punto esatto della cubemap.

Come nelle precedenti versioni di DirectX, la cubemap si può utilizzare sia leggendola da file (avrete bisogno di un programma come dxTex per generarle) oppure, cosa più comoda, come render target.

In directX9 si creava una cubemap e poi si renderizzava la scena 6 volte, una volta per ogni faccia, cambiando l'angolo della telecamera.

Se avete letto il precedente tutorial però avrete notato la bellissima funzionalità esistente in DirectX10, quella di poter utilizzare render target indicizzabili su cui mandare in rendering la grafica. Questo è proprio uno dei casi ideali.

Il geometry shader restituirà 6 triangoli per ogni triangolo in entrata, ognuno orientato verso una delle faccie.

A questo punto basterà passare 6 matrici transform allo shader in modo da inquadrare la scena dal centro dell'oggetto che deve riflettere verso i 6 lati ed avrete in un solo pass il rendering di 6 facce (risparmierete quindi l'esecuzione di 5 vertex shader, che non è poco).

L'unica differenza sarà la viewMatrix che sarà generata in quasto modo in base all'indice della faccia.


switch(faceIndex)
{
    case 0:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(1,0,0),&D3DXVECTOR3(0,1,0));
        break;
    case 1:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(-1,0,0),&D3DXVECTOR3(0,1,0));
        break;
    case 2:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0),&D3DXVECTOR3(0,0,-1));
        break;
    case 3:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,-1,0),&D3DXVECTOR3(0,0,1));
        break;
    case 4:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,0,1),&D3DXVECTOR3(0,1,0));
        break;
case 5:
        D3DXMatrixLookAtLH(&view,&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,0,-1),&D3DXVECTOR3(0,1,0));
        break;
}

In questa porzione di codice la scena è inquadrata rispetto al centro. Basterà sommare la posizione dell'oggetto a ViewAt e ViewTo per spostare il centro.

 

 Per creare un render target che rappresenti una cubemap basterà settare il flags in questo modo

per D3D10_SHADER_RESOURCE_VIEW_DESC

ViewDimension = D3D10_SRV_DIMENSION_TEXTURECUBE;
TextureCube.MostDetailedMip = 0;
TextureCube.MipLevels = 1;

 

e per D3D10_TEXTURE2D_DESC durante la creazione del depth stencil buffer

MiscFlags=D3D10_RESOURCE_MISC_TEXTURECUBE;

Il resto rimane invariato a quanto visto per la creazione degli array di render target.

Nello shader la texture andrà dichiarata come TextureCube e in fase di lettura passare alla istruzione Sample un float3.

Qui potete vedere un esempio di geometry shader per renderizzare su una cubemap

 

struct GS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 normal:NORMAL;
    float3 worldPos:WORLDPOSITION;
    float2 tex:TEXCOORD;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 normal:NORMAL;
    float3 worldPos:WORLDPOSITION;
    float2 tex:TEXCOORD;
    uint RTIndex : SV_RenderTargetArrayIndex;
};

[maxvertexcount(24)]
void GS_CUBE( triangle GS_INPUT input[3], inout TriangleStream CubeMapStream )
    {
    for( int f = 0; f < 6; ++f )
    {
        PS_INPUT output;
        output.RTIndex = f;
        for( int v = 0; v < 3; v++ )
        {
            output.Pos = mul( input[v].Pos, transformMatrixArr[f] );
            output.worldPos=input[v].worldPos;
            output.tex = input[v].tex;
            output.normal = input[v].normal;
            CubeMapStream.Append( output );
        }
        CubeMapStream.RestartStrip();
    }
}

 

transformMatrixArr è un array di 6 transform matrix.

Le cubemap sono utili oltre che per le riflessioni sugli oggetti anche per rappresentare il cielo, le parti di una scena intorno all'osservatore e via dicendo.

 

Vi lascio al demo

Demo

Articolo Articolo  Storico Storico Stampa Stampa
I commenti sono disabilitati.
"Il vero problema non è se le macchine pensano, ma se gli uomini lo fanno."

B. F. Skinner


Cerca per parola chiave
 

Titolo
Articoli (4)
C++ (4)
Direct3D10 (30)
Direct3D11 (20)
DirectX9 (82)
DotNet (10)
English (9)
FanGames (22)
ManagedDX11 (2)
Materiale Utile (4)
News (39)
Shader Library (12)
SharpDX (1)
Software (25)
Tecnologia (19)
Varie (9)

Gli interventi più cliccati

Ultimi commenti:
If you wish to retai...
23/05/2013 @ 13:07:45
Di chanel outlet
You deficit of self-...
23/05/2013 @ 13:07:13
Di cartier watches uk
Reinforce your own l...
23/05/2013 @ 13:06:37
Di replica watches
Whenever you"re shiv...
23/05/2013 @ 13:06:11
Di swiss replica watches
It's likely you have...
23/05/2013 @ 13:05:02
Di chanel handbags
Cheap automobile ins...
23/05/2013 @ 13:04:28
Di replica watches

Titolo
Con quale tecnologia state realizzando o avete intenzione di realizzare i vostri progetti?

 DirectX11
 DirectX10
 DirectX9
 XNA
 DirectX8 o Precedenti
 OpenGL
 Motori grafici già pronti
 Altro

Titolo
Umorismo (17)

Le fotografie più cliccate



Ci sono 290 persone collegate
Sono state visualizzate  pagine

03/12/2024 @ 21:52:29
script eseguito in 42 ms