Il rastering è il processo che partendo dalla descrizione dei poligoni (in DirectX solo di tipo triangolare), genera a video i triangoli. Nei precedenti tutorial è già stato spiegato in teoria come funziona il processo: il vertex shader valorizza i vertici, il rasterizer calcola tutti i pixel necessari per riempire il triangolo e per ognuno di questi fa una media pesata tra i 3 vertici in base alla posizione mandando il risultato al pixel shader.
Su questo processo è possibile intervenire. A differenza di DirectX9, in DirectX10 tali settaggi vengono fatti da codice shader (anche se vi mostrerò come poterlo fare comunque da codice).
I settaggi vengono contenuti in una variabile RasterizerState nel codice HLSL e passati tramite l’istruzione SetRasterizerState all’interno del pass.
RasterizerState rsWireframe { FillMode = WireFrame; };
technique10
{
pass p1
{
....
SetRasterizerState( rsWireframe );
}
}
Come potete vedere il rasterizer viene inizializzato impostando i vari valori (nel nostro caso il fillmode è stato impostato come wireframe). Le variabili non impostate saranno valorizzate con il valore di default. I campi da utilizzare sono i sequenti
- FILLMODE : indica come andranno riempite le primitive. Le opzioni sono SOLID (il settaggio di default) che riempie normalmente il triangolo e WIREFRAME che visualizza solamente le linee, lasciando vuoto il centro
- CULLMODE : specifica se i poligoni saranno invisibili se inquadrati da davanti (FRONT), da dietro (BACK) o in entrambi i casi (NONE).
- FRONTCOUNTERCLOCKWISE : specifica la direzione considerata frontale per i triangoli. Con TRUE il triangolo sarà frontale se i vertici sono disposti in senso antiorario, con false in senso orario
- DEPTHBIAS : è un valore intero di profondità che viene aggiunto ai pixel. Su scene molto grandi può capitare che oggetti a profondità molto vicine abbiano degli artefatti dovuti alla limitata precisione dello ZBUFFER. Anche su scene piccole se 2 oggetti hanno la stessa profondità (2 cubi coincidenti ad esempio) si verificherà che in alcuni punti il primo copre il secondo, in altri il secondo copre il primo. Con questo settaggio lo zbuffer viene valorizzato con un valore diverso da quello calcolato e potrete dare priorità agli oggetti.
- DEPTHBIASCLAMP : è un float che indica il valore massimo di profondità inseribile sullo Zbuffer. Farà in modo che oggetti oltre una certa distanza abbiano profondità uguale
- SLOPESCALEDDEPTHBIAS : permette di scalare i settaggi del bias (ad esempio lasciare i primi invariati ed usare questo in base alla distanza dalla camera)
- ZCLIPENABLE : se impostato a TRUE (default) fa in modo che nulla oltre lo ZFAR impostato nella projection matrix sia visibile (un grande risparmio in tempo di elaborazione per oggetti che oltre una certa distanza non sarebbero comunque visibile).
- SCISSORENABLE : attiva gli scissor, rettangoli che impediscono il rendering dei pixel fuori di essi.
- MULTISAMPLEENABLE : attiva il multisample (per utilizzare l’antialiasing, richiede una superficie creata con multisample attivato)
- ANTIALIASEDLINEENABLE : attiva il line antialiasing, un sistema che migliora il rendering delle linee. Si può attivare solo se il multisample è impostato a false e l’oggetto è una linelist o linestrip
Per impostare gli scissor si utilizza l’istruzione RSSetScissorRects, che permette di passare n rettangoli. In questo caso ne è stato passato solo 1 che limiterà a 640 x 480 la scena. Gli scissor sono utilissimi
D3D10_RECT rects[1];
rects[0].left = 0;
rects[0].right = 640;
rects[0].top = 0;
rects[0].bottom = 480;
D3DDevice->RSSetScissorRects( 1, rects );
Come dicevo è possibile impostare il RasteringState da Device (quindi senza usare shader).
ID3D10RasterizerState * rasterState;
D3D10_RASTERIZER_DESC rasterizerState;
rasterizerState.FillMode = D3D10_FILL_SOLID;
rasterizerState.CullMode = D3D10_CULL_FRONT;
rasterizerState.FrontCounterClockwise = true;
rasterizerState.DepthBias = false;
rasterizerState.DepthBiasClamp = 0;
rasterizerState.SlopeScaledDepthBias = 0;
rasterizerState.DepthClipEnable = true;
rasterizerState.ScissorEnable = true;
rasterizerState.MultisampleEnable = false;
rasterizerState.AntialiasedLineEnable = false;
HRESULT hr = device->CreateRasterizerState( &rasterizerState, &rasterState);
Queste istruzioni creano un rasterizerState che passate al device tramite istruzione RSSetState
device->RSSetState(rasterState);
Passando NULL il settaggio tornerà al default di DirectX10
device->RSSetState(NULL);
Controllate che hr sia uguale ad S_OK prima di usare rasterState. In caso contrario il settaggio non sarà valido e quindi non potrete usarlo.
Vi lascio al demo
Demo
I commenti sono disabilitati.