DirectXCat
Guia de programació DirectX11
10.4. Tesselation + Displacement mapping
L’últim efecte que
explicarem és el que fa referència a una novetat molt remarcable de Directx11.
En el capítol referent als shaders es
parla de l’efecte tessellation. Allà
s’explica que és possible subdividir les malles de la manera que vulguem i en la quantitat de
subdivisions que vulguem a una velocitat molt elevada. Si aquest es
combina amb el displacement mapping
es crea un efecte de relleu 3d molt realista i espectacular. I el millor de tot
és que és molt menys costós que dissenyar directament una geometria amb relleu.
Així doncs l’exemple
adjunt intenta aclarir i mostrar del que és capaç aquesta tècnica. Aquest cop
està extret de la pàgina web d’Nvidia(en
anglès). L’exemple s’anomena Terrain Tessellation, i com bé s’explica, utilitza
tessellation per hardware, de manera
que accelera molt els càlculs. També hi ha un whitepaper que aclareix els processos de càlcul que es fan en el
codi adjunt.
Per a descarregar-lo fes click a aquest enllaç.
Per a descarregar-lo fes click a aquest enllaç.
10.3. Transparència (Alpha Blending)
L’Alpha Blending és
una tècnica de gràfics per ordinador que permet fer transparent la nostra
geometria. En algunes ocasions ens serà útil per a fer aparèixer geometria o
fer-la desaparèixer segons ens convingui.
A Directx3D s'usa una equació per a
crear la il·lusió de la transparència. Per
entendre-la, primer detallem la llegenda d’ítems que surten a l’equació:
- (FC) – Color Final
- (SP) - Píxel Origen
- (DP) – Píxel Destí
- (SBF) - Factor de barreja origen
- (DBF) - Factor de barreja destí
- (FA) – Alfa Final
- (SA) – Alfa Origen
- (DA) – Alfa Destí
- (+) - Operador Binari descrit a continuació
- (X) – Matrius de Multiplicació creuada.
Les dues operacions
que generen transparència a Directx11 són les següents:
- (FC) = (SP) (X) (SBF) (+) (DP) (X) (DPF)
- (FA) = (SA)(SBF) (+) (DA)(DBF)
La primera equació
serveix per a calcular el color de la transparència i la segona per a calcular
el seu valor alfa.
Pel que fa a
l’operador binari pot ser una de les instruccions següents:
Jugar amb ells ens
dóna una idea del que fan, tot i que el nom és molt aclaridor. Bàsicament, cadascun
ens proporcionarà un efecte bàsic diferent sobre la transparència.
El factor de
barreja (D3D11_BLEND) ens proporciona
diferents efectes avançats sobre la transparència. A continuació es llisten
cadascun d’ells.
Al següent enllaç
es descriuen cadascun d’ells:
Per
a poder crear transparència és necessari crear un descriptor de barreja (D3D11_BLEND_DESC).
Al
següent enllaç s’expliquen els diferents paràmetres a usar en aquesta estructura:
10.3.1. Problemes amb la transparència en Directx11
A continuació s’expliquen problemes referents amb la transparència en
Directx11. Aquests ocorren quan es tenen diversos objectes transparents a
l’escena i van lligats a l’ordre en que es renderitzen.
És important renderitzar primer tots els objectes visibles (no transparents)
de l’escena primer, i a continuació renderitzar els transparents. Si no es fes
així, el càlcul del color de la transparència es faria
només amb alguns dels objectes de l’escena no transparents, i no tots, de
manera que el resultat final seria fals, fins i tot quedaria poc realista.
Quan es tenen molts objectes a l’escena 3D, més d’un de transparent i més
d’un de sòlid, el millor per evitar problemes de
color de transparència és crear un vector segons la profunditat de l’escena,
des del punt més proper al punt més llunyà segons l’eix de profunditat, i
renderitzar els objectes en aquest ordre, alhora que primer els sòlids i a
continuació els transparents.
10.3.2. Exemple de transparència
El següent exemple
mostrarà amb transparència les capses de l’exemple del capítol 8, el
d’il·luminació.
El primer que cal
fer un cop generat el projecte on treballarem, serà definir les variables
globals. Definim l’estat de la nostra geometria, i dues variables per mantenir
els dos estats de rasterizació, en direcció a les agulles del rellotge i al
revés, això ho entendrem més endavant.
ID3D11BlendState* Transparency;
ID3D11RasterizerState* CCWcullMode;
ID3D11RasterizerState* CWcullMode;
A continuació creem
una funció per a netejar tots els elements usats en el projecte.
Tenint a mà
l’exemple d’il·luminació, ja comentat abans, sota de la funció init cal afegir les funcions referents
a la transparència.
Per a poder veure
la part del darrere de les capses un cop siguin transparents i evitar així un
error que podria donar l’alpha blending,
afegim aquest codi que bàsicament canvia la forma de representar els
objectes segons on siguin, de manera que la seva visualització sigui sempre
l’adient. Això dependrà de l’escena, en el cas d’aquest exemple, interessa
fer-ho.
La funció de pintat
(DrawScene) quedaria amb aquest aspecte:
Es pot entendre
molt millor al codi font adjunt, el qual conté comentaris de que es fa en cada
cas. Cal apreciar, però, que s’han afegit funcions respecte l’exemple d’on
partim, el d’il·luminació, que fan referència a la transparència i a la manera
de rasterizar la geometria.
Les primeres línies
referents a la transparència són les següents:
La primera fa
referència a quanta opacitat volem de cada color. Aquí marquem que la volem un
75% invisible pels colors RGB i totalment per l’alfa.
La segona línia
decideix si està actiu o no l’estat de blending.
Ara mateix està actiu. Es pot desactivar tornant a cridar la instrucció
canviant els dos primers paràmetres per NULL i el tercer deixant-lo així 0xffffffff.
La darrera línia
mescla l’estat de blending creat per
nosaltres amb el del pipeline gràfic
de manera que la nostra creació tingui efecte a l’escena final.
10.2. Boira
L’efecte de boira
en Directx11 no és res més que el que el seu nom indica. L’efecte pretén imitar
la boira que es crea quan baixa la temperatura i fa que no hi veiem més enllà
d’un llindar que pot ser molt llunyà o molt proper.
La boira, a
Directx11 es pot representar mitjançant tres tipus d’equacions diferents:
- Boira lineal = (FiBoira – DistànciaViewport) / (FiBoira - IniciBoira)
- Boira Exponencial (tipus 1)= 1.0 /2.71828 elevat a (DistànciaViewport * DensitatBoira)
- Boira Exponencial (tipus 2) = 1.0/2.71828 elevat a ((DistànciaViewport * DenistatBoira) * (DistànciaViewport * DensitatBoira))
La Boira lineal
afegeix l’efecte linealment en relació a la distància entre la càmera i
l’objecte emboirat.
La Boira
exponencial de tipus 1 afegeix, respecte la boira lineal, una quantitat de
boira exponencialment decreixent (o creixent si es mira al revés) entre el punt
central de la boira i el punt de la càmera.
La Boira
exponencial de tipus 2 fa el mateix que la de tipus 1, però donant més realisme
i una aparença de boira més real a canvi de ser més costosa en el càlcul.
Un cop calculada la
boira, triant una de les 3 equacions, es crea el FactorBoira. Per aplicar
aquest factor a la textura d’un objecte, i produir el color final de la
textura, s’usa l’equació següent:
- ColorBoiraFinal = FactorBoira * ColorTextura + (1.0 - FactorBoira) * ColorBoiraOriginal
A continuació
s’explica un exemple relacionat amb l’efecte Boira.
10.2.1. Exemple de boira
El següent exemple pretén generar el FactorBoira en un vèrtex shader i calcular a continuació el
colorBoiraFinal en un píxel shader.
L’exemple està
format per 8 classes. La majoria d’elles són per organitzar la informació de
l’exemple de manera lògica sent el main de l’aplicació el que crida les
funcions necessàries per executar el codi final. La classe important és la que
s'anomena fogshaderclass. Aquesta
s’encarrega de cridar als shaders que
creen l’efecte boira de manera adient. A continuació els expliquem.
Per crear l’efecte
boira utilitzem dos shaders, un
vèrtex shader i un píxel shader, com ja hem comentat al principi.
Codi del vertex shader:
Codi del pixel shader:
Un cop creats
aquests shaders només cal
enllaçar-los correctament al projecte i cridar-los de manera igual que fem i
hem estat fent durant tots els exemples usant les funcions de shaders des de fora d’aquests.
10.1. Introducció
Fent ús d’algunes
funcions de DirectX11 és possible dotar a les escenes 3D o 2D d’efectes especials
amb l’objectiu de mostrar més realisme i espectacularitat. A continuació
n’expliquem alguns, l’efecte boira, l’efecte transparència i un efecte conjunt
usant les tècniques de tessellation i
displacement mapping.
5.4. Depth buffer & Stencil buffer
A DirectX11, el depth buffer (anomenat també Z buffer) és usat
per enregistrar la profunditat a la que es troba cada píxel que mostrem. Quan
més d’un píxel es troben en posicions similars, el depth buffer ens ajuda a
determinar quin píxel es mostra i quin no.
El rang de valors del
depth buffer va de 0.0f a 1.0f, on el punt situat al 0.0f es troba just davant
del z-near i el 1.0f es troba just abans del z-far (les propietats z-near i z-far són
explicades en el capítol 4).
Per a tenir un
bon funcionament del depth buffer a l’hora de pintar la nostra geometria
necessitarem fer ús de l'stencil buffer, el qual s’usa per limitar l’àrea del
renderitzat.
Treballar amb la combinació d'aquests dos buffers és una tècnica molt útil per la creació d’ombres i per la creació
de reflexions.
Per a poder usar-los primer de tot cal crear-los en l’ inicialització del programa. A continuació tenim un
exemple:
Al final del programa, s’hauran d’alliberar:
5.3. Vertex buffer & Index buffer
Per explicar el vertex buffer farem ús de
la següent imatge:
Un cop definida l'estructura, es cridarà la funció CreateBuffer de DirectX la qual ens crearà el buffer. A continuació es mostra l'estructura de la funció CreateBuffer:
Figura 1. Representació d'una esfera 3D.
Una esfera com la mostrada, està formada per
centenars de petits triangles, cadascun d’aquests triangles es defineixen a
partir de l’unió de tres punts (els seus vèrtexs). Així que per a poder pintar
aquest cercle en el nostre programa, necessitem posar tots aquests vèrtexs en un
array “especial” el qual li direm vertex buffer.
En el cas de l'index buffer (el qual està molt
relacionat amb el vertex buffer), el seu propòsit és enregistrar la
localització de cada vèrtex de la geometria que es troba emmagatzemada en el
vertex buffer. La GPU usa l’índex buffer per a trobar ràpidament algun vèrtex
específic que es trobi al vertex buffer. El concepte de l'index buffer és
similar al índex d’un llibre, t’ajuda a trobar el tema que busques amb molta
més rapidesa.
Per a crear el vèrtex buffer o l’índex buffer
s’usarà la següent estructura de Directx:
On:
ByteWidth
és l’espai que ocupa el buffer (en bytes).
Usage és un valor que especifica com s’escriurà i
llegirà l’estructura a memòria, normalment el seu valor és
D3D11_USAGE_DEFAULT, (per a més informació visitar: http://msdn.microsoft.com/en-us/library/windows/desktop/ff476259(v=vs.85).aspx
).
BindFlags especifica quin tipus de buffer s’usarà, en
el cas del vertex buffer usarem D3D11_BIND_VERTEX_BUFFER.
CPUAccessFlags són canvis d’estat per especificar els
tipus d’accés a la CPU (Usar el valor 0 si no es requereix la CPU) , si no
volem cap en especial, per defecte usarem el D3D11_CPU_ACCESS_WRITE. Tots els seus valors es poden trobar en la
següent direcció http://msdn.microsoft.com/en-us/library/windows/desktop/ff476106(v=vs.85).aspx
.
MiscFlags són canvis d’estat que permeten activar els
recursos menys comuns. Normalment aquest valor valdrà 0. Per a més informació
visitar: http://msdn.microsoft.com/en-us/library/windows/desktop/ff476203(v=vs.85).aspx
StructureByteStride especifica l’espai que
ocupa cada element quan es treballa amb buffers estructurats. Normalment aquest valor valdrà 0.
Aquesta funció demana tres paràmetres, el primer és l’estructura
definida anteriorment, el segon camp és un punter a una estructura
D311_SUBRESOURCE_DATA, la qual descriu la inicialització de les dades; i
finalment, el tercer camp és una adreça d’un punter per on obtindrem el buffer
ja creat.
A continuació tenim un exemple on es mostra la creació del vertex
buffer i de l'index buffer:
Al final del programa, s’hauran d’alliberar aquests buffers:
Suscribirse a:
Entradas (Atom)

