Télécharger la version PDF

Transcription

Télécharger la version PDF
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Objets et rendu
Leçon n°3 :définition d'objets élémentaires
et rendu élémentaire.
Année universitaire
2004-2005
Pascal Mignot
[email protected]
Couleurs et alpha
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Lors de l'écriture d'un programme DirectX, les couleurs sont déclarées
sous forme d'un quadruplet (alpha, rouge, vert, bleu).
Types associés:
D3DCOLOR (DWORD, 32 bits au format A8R8G8B8)
Utilisation: dans le format des sommets, textures, rasterization.
D3DCOLORVALUE (structure de 4 floats dont les champs sont r,g,b,a)
Utilisation: définition des matériaux, des lampes (ambiante excepté).
Qu'est-ce-que le alpha?
paramètre supplémentaire pouvant être utilisé pour mélanger des couleurs
(dans les étages de texture, à la rasterization).
Utilisation classique: comme facteur de transparence (ex: mélange d’une
couleur C1 avec une couleur (α,C2) : couleur résultat = (1-α).C1 + α.C2 ).
Désignation d'une couleur
Utiliser les macros suivantes pour construire une D3DCOLOR:
D3DCOLOR_ARGB(a,r,g,b) où r,g,b,a sont des UCHARs (0 à 255).
D3DCOLOR_XRGB(r,g,b) où r,g,b sont des UCHARs (0 à 255).
D3DCOLOR_COLORVALUE(r,g,b,a) où r,g,b,a sont des floats (0 à 1).
Orientation des normales
et culling
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
L'ordre dans lesquels les sommets d’une facette sont déclarés a un
impact important car il détermine la direction de sa normale.
Orientation D3DCULL_CCW
0
2
1
sens inverse des
aiguilles d'une montre.
Orientation D3DCULL_CW
0
1
2
sens des aiguilles
d'une montre.
On appelle backface-culling l'action d'effectuer un rejet trivial sur les facettes
non visibles (normale non orientée vers l'observateur).
Remarque: il est important d'activer le culling si possible (en moyenne, on se
débarasse de 50% des facettes).
Mode par défaut : D3DCULL_CCW
Désactivation: D3DCULL_NONE (les deux faces sont visibles).
Comment le changer: avec la méthode SetRenderState du Device
exemple: pDEV->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)
Objets élémentaires
U N IVERSIT É
D E R EIMS
définis dans DirectX
C H AMP AGN E-A RD EN N E
Trois types d'objets élémentaires:
• le point (ou sommet)
• le segment (ou arête entre deux sommets)
• la facette (ou triangle = surface délimitée par 3 sommets + 3 segments).
Deux familles d'objets 3D:
• Les maillages (meshes) = ensemble de facettes.
• Les surfaces de type Bézier ou patches (facettisées pour le pipeline).
Ces objets sont basés sur des sommets, et peuvent définis de manière
indexée.
Exemple: le trièdre.
P3
Définition non indexée:
Liste des faces = { {P0, P2, P1}, {P0, P1, P3}, {P1, P2, P3} , {P2, P0, P3 } }
P0
P2
P1
Définition indexée:
Liste des sommets = {P0, P1, P2, P3 }
Liste indexée des faces = {{0,2,1} , {0,1,3}, {1,2,3}, {2,0,3}}
Rendu d'objets
U N IVERSIT É
D E R EIMS
sous DirectX
C H AMP AGN E-A RD EN N E
Afin de donner un aspect réaliste aux objets géométriques ou les animer, il
faut leurs ajouter des propriétés supplémentaires (couleur, coordonnées
dans l’espace de la texture, …).
Ces propriétés supplémentaires sont:
• attachées aux sommets.
• interpolées sur le reste de la facette à partir des valeurs aux sommets.
Exemple: couleur d'une facette
obtenue par interpolation des
couleurs aux sommets.
P0
Exemple: définition d'un trièdre indexé avec
propriété de couleur:
Liste des sommets = { (P0, vert),
(P1, rouge),
(P2, bleu),
(P3, blanc) }
Liste indexée des faces = {{0,2,1} , {0,1,3}, {1,2,3}, {2,0,3}}
P2
P1
Propriétés d'une facette
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
locale ou globale?
Pour des raisons d'efficacité, on souhaiterait:
• si une propriété est constante sur un groupe de facette,
– à l'initialisation, ne pas attacher la propriété à chaque sommet.
– lors du rendu, on fixe la propriété. Le rendu de toutes les facettes qui suivent
se fera avec cette propriété.
•
si la propriété est locale à chaque facette,
– à l'initialisation, on définit la propriété en chaque sommet de chaque facette.
– lors du rendu, les valeurs dans chaque facette sont interpolées à partir des
sommets.
Exemple: pour la
couleur d'une
facette.
Approche globale
Initialisation:
définition des facettes.
Rendu:
fixer couleur 1.
dessiner le groupe 1 de facettes.
fixer couleur 2.
dessiner le groupe 2 de facettes.
…
Approche locale
Initialisation:
définition des facettes.
pour chaque sommet, définir la couleur.
Rendu:
dessiner le groupe 1 de facettes.
dessiner le groupe 2 de facettes.
…
Ces deux approches sont possibles (et non exclusive)!
Format de sommet flexible
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
•
•
•
Justification
suivant les cas, les différentes propriétés des facettes sont chacune soit
locales, soit globales.
si une propriété globale est stocké comme une propriété locale, on perd
(un peu) de la place mémoire et (un peu) de la bande passante.
il n'est pas pratique de gérer une propriété locale de la même façon d'une
propriété globale.
Conclusion: il est donc intéressant de disposer d'un format de sommet qui
soit exactement adapté au contexte.
Avantages: pratique, performance, stockage.
Ce principe porte le nom de FVF (flexible vertex format).
REMARQUE: Il reste possible avec DirectX de ne pas utiliser les propriétés
locales même si elles sont définies (et donc d'utiliser des propriétés
globales).
NOTE : il existe une autre façon de déclarer les formats des sommets (avec
des déclarations), mais leurs pleines possibilités n’est utilisable qu’avec
des shaders. Les déclarations seront étudiées à ce moment.
Format de sommet flexible
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
comment le définir
Phase d'initialisation:
• créer une structure (au sens struct du C) contenant
l'ensemble des propriétés à définir.
définit le format utilisé pour stocker les sommets.
• définir un masque contenant exactement les champs définis
dans cette structure (aussi appelé type du sommet).
permet aux fonctions DirectX qui utilisent ce format de savoir
quelles sont les propriétés disponibles et où aller les chercher.
• disposer de la taille de la structure (au sens sizeof du C).
permet aux fonctions de connaître la taille d'un sommet.
Phase de rendu:
• définir le format de rendu (méthode SetFVF de
IDirect3DDevice9).
• il est possible de changer de format de rendu au cours
d'une même phase de rendu (en général: lent).
Format de sommet flexible
composition de la structure
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Commentaires:
•
Position:
position du sommet.
•
RWH:
inverse de la coordonnée W
(homogène) du sommet
(1/W).
•
Blending Weight Data:
poids pour mélanger les
transformations sur les
sommets.
•
Vertex Normal:
normale au sommet (nécessaire
pour lumières).
•
Diffuse Color:
couleur du sommet ou couleur
diffuses si lumière.
•
Specular Color:
couleurs spéculaire (si lumière).
•
Texture Coordinate Set x:
coordonnées du sommet dans
l'espace de la texture.
Format de sommet flexible
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
contraintes sur la structure et exemple
Contraintes sur la construction de la structure:
1. Le champ position est obligatoire.
2. Tous les champs doivent apparaître exactement dans cet ordre.
3. Le type des champs doit absolument être respecté aux équivalences
de type près*. Par contre, les noms utilisés pour les champs n'ont
aucune importance.
4. Le champs "RHW" est incompatible avec le champ "Vertex Normal".
5. Le champs "Vertex Normal" est nécessaire lors de l'utilisation de
lumières.
Exemples: deux formats de sommets strictement équivalent pour
DirectX (il est impossible d'intervertir deux lignes sinon la contrainte 2
n'est plus respectée).
struct {
float
float
float
DWORD
float
} VERTEX;
x,y,z;
b1,b2;
nx,ny,nz;
diffuse;
tu,tv;
struct {
D3DXVECTOR3
float
D3DXVECTOR3
D3DCOLOR
float
} VERTEX;
p;
b1,b2;
n;
diffus;
tu,tv;
* Par exemple: 3 floats = D3DXVECTOR3, DWORD = D3DCOLOR, 4 floats (Position+RWH) = D3DVECTOR4.
U N IVERSIT É
D E R EIMS
Format de sommet flexible
élément du masque définissant le contenu de la structure VERTEX.
C H AMP AGN E-A RD EN N E
Couleur
Géométrie du sommet
D3DFVF_DIFFUSE
couleur diffuse
D3DFVF_XYZ
Position
D3DFVF_SPECULAR
couleur spéculaire
D3DFVF_XYZRHW
Position + RHW
D3DFVF_NORMAL
Normale
Autre
D3DFVF_PSIZE
Taille du sommet (particules)
Transformation des sommets
D3DFVF_XYZBn
n=1..5 floats utilisés pour le vertex blending.
D3DFVF_LASTBETA_UBYTE4
le dernier de ces floats est utilisé comme un tableau de 4 uchar.
Textures
D3DFVF_TEXn (où n=1…8)
nombre de textures utilisées pour ce sommet.
D3DFVF_TEXCOORDSIZEn(p) (où n=1…8, p=1…4)
pour la nème texture, utiliser p coordonnées
(défaut=2).
Exemple (masque et taille associées à l'exemple précédent):
VERTEXfmt = D3DFVF_XYZ|D3DFVF_XYZB2|D3DFVF_NORMAL| D3DFVF_DIFFUSE|D3DFVF_TEX1;
VERTEXsiz = sizeof(VERTEX);
Rendu d'une primitive
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Tableau de sommets
et principe d'utilisation
Les primitives ou les maillages sont définis par:
•
un tableau de sommets (+ un tableau de numéros d'index dans le cas indexé).
•
une option de la fonction de rendu indiquant comment "assembler" ce(s)
tableau(x).
En pratique,
• une zone mémoire est définie dans
la mémoire gérée par le
périphérique graphique pour
contenir ce(s) tableau(x).
• cette zone mémoire est insérée
dans le flux de sommets pour être
traitée par le périphérique
graphique.
• une fonction de rendu traite alors
ce flux avec les options spécifiées.
Rendu d'une primitive
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Gestion d'un tableau de sommets
(VertexBuffer)
Création: d'un objet IDirect3DVertexBuffer9 contenant un tableau de N
sommets (méthode de IDirect3DDevice):
CreateVertexBuffer(mlen, use, fmt, muse, pptr, NULL)
mlen : mémoire à réserver (typiquement N*sizeof(VERTEX)).
use: 0 ou flag indiquant que ce buffer est utilisé de façon particulière (cf doc.)
fmt: format du FVF.
muse: gestion mémoire de la ressource. D3DPOOL_MANAGED ou cf page suivante.
pptr: adresse du pointeur contenant le pointeur sur l'objet IDirect3DVertexBuffer9 crée.
Méthodes principales de manipulation d'un objet VertexBuffer:
•
l'écriture ou la lecture (memcpy) doivent se faire "sous protection", car son
emplacement mémoire peut changer.
Lock(offset,size,pptr,ltype): verrouille la zone mémoire indiquée.
offset: décalage (en octets) depuis le début du VertexBuffer.
size: taille (en octets) à verrouiller (0 verrouille la totalité).
pptr: adresse mémoire à laquelle écriture/lecture seront possibles (position temporaire).
ltype: type du verrou: 0 ou cf doc.
Unlock(): déverrouille la zone précédement vérrouillé.
•
tout VertexBuffer crée doit être libéré lorsqu'il n'est plus utilisé et attaché à un
flux.
Release(): libération des ressources attribuées aux VertexBuffer.
Gestion mémoire des ressources
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
où sont stocké mes objets?
Utilisation de la mémoire
Les données VertexBuffer, IndexBuffer, Texture, Mesh et PMesh sont créés avec un flag
de type D3DPOOL_x qui indique dans quelle partie de la mémoire ils doivent être
placés.
DEFAULT : utiliser la mémoire de type la plus appropriée pour la donnée (en général la
mémoire vidéo = mémoire vidéo locale + mémoire AGP).
En cas de perte du Device, tous les objets créés dans ce mode doivent être libéré avant le
Reset, puis recréés.
MANAGED : les données seront automatiquement placées dans la mémoire appropriée
lorsque cela sera nécessaire. Mode automatique conseillé.
En cas de perte du Device, rien à faire (gestion automatique).
SYSTEMMEM : les données sont placés dans la mémoire du système (non accessible par
un Device 3D).
La perte du Device n’a aucun impact sur ces données.
Note: certains autres objets (StencilDepthBuffer, RenderTarget) sont nécessairement créés avec le flag
D3DPOOL_DEFAULT (perte du Device à gérer nécessairement à la main).
Utilisation générale
D3DUSAGE_DYNAMIC : à préciser dans l’usage si le vertex/index buffer doit être remis à
jour.
Rendu d'une primitive
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
2
3
4
1
0
5
D3DPT_POINTLIST
2
3
4
1
0
5
utilisation de la primitive lors du rendu
En deux étapes (méthode de
IDirect3DDevice9),
• On indique au flux de sommets
l'ensemble des VertexBuffers à charger
pour le rendu suivant:
SetStreamSource(num,pVB,offset,vsize)
num: place dans le flux (en général 0).
pVB: pointeur sur un VertexBuffer.
offset: décalage (en octets) depuis le début du
tableau de sommets.
vsize (=sizeof(VERTEX)) taille de la structure
FVF utilisée par le VertexBuffer.
D3DPT_LINELIST
2
4
0
5
D3DPT_LINESTRIP
DrawPrimitive(type,first,nb)
type: comment traiter le flux (D3DPT_?)
first: numéro d'ordre du premier sommet à
traiter.
nb: nombre total de primitives à dessiner.
3
4
1
0
5
D3DPT_TRIANGLELIST
4
5
2
3
1
0
D3DPT_TRIANGLESTRIP
• On dessine la primitive (traitement du
flux) en spécifiant le mode de rendu.
3
1
2
2
3
4
1
0
5
D3DPT_TRIANGLEFAN
Rendu d'une primitive
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
exemple du trièdre
// Définition FVF
struct { D3DXVECTOR3 p; } VERT;
const int Vfmt = D3DFVF_XYZ;
const int Vsiz = sizeof(VERT);
// Variables
LPDIRECT3DDEVICE9 pDEV; // initialiser
LPDIRECT3DVERTEXBUFFER9 pVB=NULL;
// Lors de l'initialisation géométrique (pDEV déjà initialisé)
VERT P0={1,1,0}, P1={-1,1,0}, P2={0,-1,0}, P3={0,0,1};
VERT obj[12]={P0,P2,P1, P0,P1,P3, P1,P2,P3, P2,P0,P3};
pDEV->CreateVertexBuffer(12*Vsiz,0,Vfmt,D3DPOOL_MANAGED,&pVB,NULL);
void *ptr;
pVB->Lock(0,12*Vsiz,&ptr,0);
memcpy(ptr,obj,12*Vsiz);
pVB->Unlock();
// Lors du rendu
pDEV->SetFVF(Vfmt);
pDEV->SetStreamSource(0,pVB,0,Vsiz);
pDEV->DrawPrimitive(D3DPT_TRIANGLELIST,0,4);
// 4 faces
Rendu d'une primitive indexée
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Gestion d'un tableau d'index (IndexBuffer)
Création: d'un tableau d'index de taille P avec l'aide de la méthode
de IDirect3DDevice:
CreateIndexBuffer(mlen, use, fmt, muse, pptr, NULL)
mlen : mémoire à réserver (typiquement P*sizeof(DWORD)).
use: 0 ou flag indiquant que ce buffer est utilisé de façon particulière (cf doc.)
fmt: D3DFMT_INDEX16 pour un index 16 bits (short unsigned int) ou
D3DFMT_INDEX32 pour un index 32 bits (unsigned int) [capacité à
vérifier].
muse: gestion de la mémoire. D3DPOOL_MANAGED ou cf doc.
pptr: adresse du pointeur contenant le Direct3DIndexBuffer9 créé.
Méthodes principales de manipulation d'un IndexBuffer:
• comme pour le VertexBuffer, l'écriture ou la lecture doivent se
faire "sous protection".
Même noms de méthodes (Lock et Unlock) et même arguments que
pour VertexBuffer.
• tout IndexBuffer créé doit être libéré. Utiliser Release().
Rendu d'une primitive indexée
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
utilisation de la primitive lors du rendu
En trois étapes (méthode de IDirect3DDevice9),
• On indique au flux l'ensemble des VertexBuffers à charger pour le rendu suivant
avec SetStreamSource.
• On indique au flux l'IndexBuffer à utiliser pour le rendu indexé suivant avec
SetIndices (commun à toutes les sources):
SetIndices(pIB)
pIB: pointeur sur un IndexBuffer.
•
On dessine la primitive indexée en spécifiant le mode de rendu.
DrawIndexedPrimitive(type,ioffset,imin,nvert,ifirst,nb)
type: comment traiter le flux (D3DPT_?)
ioffset: tous les indices sont relatifs à ce décalage (possiblement négatif).
imin: valeur du plus petit indice qui sera utilisé.
nvert: nombre de sommets utilisés lors de l'appel.
ifirst: numéro d'ordre du premier indice à utiliser.
nb: nombre total de primitives à dessiner.
ensemble des sommets utilisés = ioffset + imin + {0, …, nvert-1}
ensemble des indices utilisés = ifirst + {0, …, 3.nb-1} (cas TRIANGLELIST)
ATTENTION: cette méthode lance le calcul des transformations sur l’ensemble des
sommets dans l’ensemble des indices utilisés. Il faut donc éviter si possible
d’appliquer plusieurs fois la même transformation sur un sommet, notamment en:
–
–
limitant autant que possible l’intervalle dans l’IndexBuffer
évitant les entrelacements d’objets dans un même VertexBuffer.
Rendu d'une primitive indexée
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
exemple du trièdre
// Lors de l'initialisation géométrique (pDEV déjà initialisé)
VERT obj[4]={{1,1,0},{-1,1,0},{0,-1,0},{0,0,1}};
short unsigned int ind[12]={0,2,1,0,1,3,1,2,3,2,0,3};
void *ptr;
pDEV->CreateVertexBuffer(4*Vsiz,0,Vfmt,D3DPOOL_MANAGED,&pVB,NULL);
pVB->Lock(0,4*Vsiz,&ptr,0);
memcpy(ptr,obj,4*Vsiz);
pVB->Unlock();
pDEV->CreateIndexBuffer(sizeof(ind),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pIB,NULL);
pIB->Lock(0,sizeof(ind),&ptr,0);
memcpy(ptr,ind,sizeof(ind));
// Variables
pIB->Unlock();
LPDIRECT3DDEVICE9 pDEV; // à initialiser
LPDIRECT3DVERTEXBUFFER9 pVB=NULL;
// Lors du rendu
LPDIRECT3DINDEXBUFFER9 pIB=NULL;
pDEV->SetFVF(Vfmt);
pDEV->SetStreamSource(0,pVB,0,Vsiz);
pDEV->SetIndices(pIB);
pDEV->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,4);
Illumination
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
principe
Sous DirectX, le calcul d'illumination d'un objet nécessite:
• un modèle de rendu (à pipeline graphique fixe, celui de Phong).
• la définition de sources de lumière et de leurs propriétés.
• la définition des propriétés géométriques et matérielles locales à la surface
de l'objet (paramètres du modèle ou issus des textures).
Le modèle permet de calculer le résultat de l'interaction entre la lumière et la
matière de l'objet.
En pratique sous DirectX:
• la gestion des sources de lumière doit être activée, et au moins une source de
lumière définie (minimum = la lumière ambiante).
• la normale à la surface DOIT être intégrée au FVF.
• TOUJOURS normaliser les normales placées dans le FVF.
• les paramètres matériels de la surface doivent être définis.
Remarque: s’il est nécessaire de placer des normales non normalisées dans
le FVF, on peut activer la normalisation automatique en changeant l’état
D3DRS_NORMALIZENORMALS (TRUE/FALSE) avec la méthode
SetRenderState du Device.
Illumination
U N IVERSIT É
D E R EIMS
modèle de rendu
C H AMP AGN E-A RD EN N E
Le modèle de rendu par défaut utilisé par DirectX est une variation classique
du modèle de Phong. La luminance réfléchie LR par la surface se calcule
comme:
LR = {
LE + Ca .La + ∑i
123
émission
ambiant
r r
r r n
s
Ca .L + Cd .L .( N .Li ) + Cs .Li .( N .H i ) s
3
123 142
4 43
4 144244
ambiant
diffus
1
44444
4
42444spéculaire
4444
3
a
i
d
i
pour chaque source de lumière
Pour simplifier, on n'a pas inclut ni le terme d'atténuation, ni le terme de
contrôle du lobe (cas du spot).
Paramètres (non géométriques) de ce modèle:
LE , Ca , Cd , Cs , ns
paramètres matériels de la surface
Lai , Ldi , Lsi
luminance de la ième source.
La
luminance ambiante.
Illumination
réflexion spéculaire
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Deux options de SetRenderState (méthode du Device)
permettent de contrôler la réflexion spéculaire:
• D3DRS_SPECULARENABLE (défaut = FALSE)
La réflexion spéculaire doit donc être spécifiquement activée, et si
possible, seulement lorsqu'elle est utilisée.
• D3DRS_LOCALVIEWER (défaut = TRUE)
La formule de calcul du vecteur Hi est:
(
)
r
r r r r
H i = Li + V / Li + V
V
z
– TRUE: V = direction de l'observateur (cas
classique, cf figure de gauche).
– FALSE: V = parallèle à l'axe z (correct si la
projection est orthogonale, approximatif mais
plus rapide sinon, cf figure de droite).
V
z
Propriétés matérielles d'une surface
structure D3DMATERIAL9
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Les propriétés matérielles associées à la surface sont décrites dans
la structure D3DMATERIAL9 dont les champs sont:
Notation
Champs
Nom
Signification
LE
Emissive
couleur émissive
intensité lumineuse de la surface si celle-ci
est une source de lumière.
Ca
Ambiant
couleur ambiante
en général, égale à la couleur diffuse ou
gris (scotopique).
Cd
Diffuse
couleur diffuse
couleur propre de l’objet (sous une lumière
blanche)
Cs
Specular
couleur spéculaire
couleur des reflets spéculaires (plastique =
blanc, métal = couleur de l’éclat métallique).
Power
exposant
spéculaire
largeur de la tache spéculaire (1 = tache
large, 30=tache moyenne, 200 = tache
ponctuelle).
ns
Remarques: si la gestion des sources n'est pas active, la définition d’un matériau
est sans effet sur la couleur d’un objet (dans ce cas, la couleur utilisée est celle
contenue dans le FVF).
Propriétés matérielles d'une surface
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
•
création et mise à disposition d'une matière
cas local:
seuls 2 paramètres (Diffuse, Specular) peuvent être intégrés au FVF, la valeur
par défaut de tous les autres paramètres est 0 (ou noir).
•
cas global:
en deux étapes:
1.
création d'une variable de type D3DMATERIAL9 et remplissage de
cette structure.
2. mise à disposition: avec la méthode SetMaterial du Device.
Exemple: // Lors de l'initialisation
D3DMATERIAL9 mat1;
memset(&mat1,sizeof(D3DMATERIAL9),0); // tout à zéro
mat1.Diffuse = D3DCOLORVALUE(1,0,0,1);
mat1.Specular = D3DCOLORVALUE(1,1,1,1);
mat1.Power = 20.0f;
// Lors du rendu (avant un Draw).
pDEV->SetRenderState(D3DRS_SPECULARENABLE,TRUE);
pDEV->SetMaterial(&mat1);
Propriétés matérielles d'une surface
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
gestion locale et globale
Le mode de gestion se règle avec SetRenderState (méthode de Device):
• Par défault, la gestion des matériaux est locale (par sommet).
D3DRS_COLORVERTEX (défaut = TRUE)
TRUE = gestion par sommet (FVF).
FALSE = gestion globale (SetMaterial, valeurs FVF ignorés).
•
Gestion plus fine: pour chaque caractéristique matérielle d’un objet, on
choisit si sa valeur est lue dans le FVF ou dans le matériau actuellement
défini:
D3DRS_DIFFUSEMATERIALSOURCE
définir comment on obtient la couleur diffuse (défaut = D3DMCS_COLOR1).
D3DRS_SPECULARMATERIALSOURCE
définir comment on obtient la couleur spéculaire (défaut = D3DMCS_COLOR2).
D3DRS_AMBIENTMATERIALSOURCE
définir comment on obtient la couleur ambiante (défaut = D3DMCS_MATERIAL).
D3DRS_EMISSIVEMATERIALSOURCE
définir comment on obtient la couleur émissive (défaut = D3DMCS_MATERIAL).
en spécifiant la source parmi:
D3DMCS_MATERIAL = la lire dans le matériau courant.
D3DMCS_COLOR1 = la lire dans la couleur diffuse du FVF.
D3DMCS_COLOR2 = la lire dans la couleur spéculaire du FVF.
Illumination
Généralité
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
DirectX gère:
• pour les sources directes:
(en provenance d'une source
ponctuelle lointaine)
sources
directionnelles
sources ponctuelles
spot
• pour les sources indirectes: la lumière ambiante.
Remarque: les textures, notamment les cartes de
luminance (lightmaps) ou les cartes de réflexion
(reflexion maps), permettent d'améliorer le modèle de
rendu.
Illumination
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
activation et lumière ambiante
La méthode SetRenderState du Device permet:
• D3DRS_LIGHTING (défault=TRUE)
d'activer ou de désactiver complètement les calculs
d'illumination.
note: pour des raisons de performance, l'activation ne doit être
faite que lorsqu'elle est nécessaire au rendu.
• D3DRS_AMBIENT (défaut=(0,0,0,0))
fixer la couleur de la lumière ambiante (qui est son seul et
unique paramètre).
Exemple:
// Lors de l'initialisation
pDEV->SetRenderState(D3DRS_AMBIENT,
D3DCOLOR_COLORVALUE(0.2,0.2,0.2,1.0));
Illumination
structure D3DLIGHT9
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
La structure de données unique D3DLIGHT9 permet de stocker les caractéristiques
d'une source indépendamment de son type. L'ensemble des champs sont
toujours définis, qu'ils soient ou non utiles:
champs
\ type
directionnelle
ponctuelle
spot
Type
D3DLIGHT_DIRECTIONAL
D3DLIGHT_POINT
D3DLIGHT_SPOT
Diffuse,
Specular,
Ambient
9
9
9
Position
8
9
9
Direction
9
8
9
Range
8
9
9
Attenuation0,
Attenuation1,
Attenuation2
8
9
9
Falloff, Theta,
Phi
8
8
9
Illumination
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
contenu de la structure D3DLIGHT9
• Diffuse, Specular, Ambient
Il est possible de régler indépendament les couleurs diffuse,
spéculaire et ambiante (bien que cela soit physiquement
absurde).
• Position (ponctuel, spot)
Attention, la position d'une source est donnée dans le repère
global.
Les transformation sur le repère global sont sans effet sur la
position d'une source.
• Direction (directionnelle, spot)
Comme pour la position, la direction est donnée dans le repére
global et est invariante par transformation.
• Range (ponctuel, spot)
Distance maximale à laquelle la source est visible.
Illumination
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
•
contenu de la structure D3DLIGHT9
Atténuation (ponctuel, spot): la fonction d'atténuation utilisée est:
f (d ) =
1
a0 + a1.d + a2 .d 2
où a0, a1 et a2 sont les 3 paramètres d'atténuation
(Attenuation0, Attenuation1, Attenuation2).
Attention: les 3 valeurs par défaut de ces paramètres sont 0, donc f(d)=0, et la
source paraîtra inactive. Il est donc absolument nécessaire d'initialiser correctement
ces paramètres (exemple: choisir a0=1, a1=0 et a2=0, pour ne pas avoir d’atténuation).
•
Paramètres du spot (spot)
ٛϕ
θٛ
La luminance:
– est enchangée (x1) si on se trouve dans le cône
d'ouverture Theta.
– est nulle (x0) si on est à l'extérieur du cône
d'ouverture Phi.
– varie continuement (avec la loi pFalloff) lorsque l'on
passe du cône intérieur au cône extérieur (voir cicontre).
1
p0.25
p
p4
0
1
Illumination
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
création d'une lumière
En trois étapes:
1. Créer une structure D3DLIGHT9 et initialiser ses champs en
fonction du type de source souhaité.
2. Affecter la source à un numéro d'index avec la méthode SetLight
du Device.
SetLight(ind,pLight)
ind: numéro d'index affecté à cette source. Ce numéro est compris entre 0 et le
nombre maximal de sources gérable par le Device (cf
DevCaps.MaxActiveLights, en général 8).
pLight: un pointeur sur la structure D3DLIGHT9 initialisée.
Si ce numéro est déjà affecté à une source, la nouvelle source remplace la
source existante.
Si la caractéristique de la lumière change (position, couleur, …), il faut refaire
un SetLight.
3.
Activer la source avec la méthode LightEnable du Device.
LightEnable(ind,bool)
ind: numéro d'index de la source à activer/désactiver.
bool: TRUE pour l'activer (FALSE pour la désactiver).
Attention, si ind n'est affecté à aucune source, une source directionnelle
blanche de direction z est crée.
Lampes et matériaux
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
accès mémoires aux structures
ATTENTION :
lorsqu’un SetMaterial(&mat) ou un SetLight(n,&light) est effectué,
DirectX continue à faire référence aux structures (mat et light)
passées.
Conséquences:
• n’utiliser qu’une seule structure par matériau ou par lampe (i.e. ne
pas réutiliser la même structure pour deux objets différents).
• les structures doivent rester un permanence accessibles tant que le
matériau ou la lampe associé reste utilisé dans la boucle de rendu,
même si son état ne change pas.
Notes:
• le non-respect de ces règles entraîne des comportements anormaux qui dépendent
de la carte graphique utilisée.
• ATTENTION: la modification de la structure ne suffit pas pour changer les propriétés
de l’objet correspondant et DOIT être suivi du SetMaterial ou SetLight adéquat.
• une façon simple de respecter ces règles est de passer toutes les structures
concernées en global.
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Illumination
Exemple
Définition de:
• la lumière ambiante.
• une source de lumière directionnelle,
de couleur blanche, et diffuse.
• une source de lumière ponctuelle,
sans atténuation, de couleur rouge.
Le calcul d'illumination est supposé
être nécessaire pour tous les objets.
// Lors de l'initialisation des sources
D3DLIGHT9 light1,light2;
D3DCOLORVALUE Lcolor={1.f,1.f,1.f,1.f};
// source directionnelle
memset(&light1,sizeof(D3DLIGHT9),0);
D3DVECTOR Ldir={0.f,0.f,1.f};
light1.Type = D3DLIGHT_DIRECTIONAL;
light1.Diffuse = Lcolor;
light1.Direction =Ldir;
// source ponctuelle
memset(&light2,sizeof(D3DLIGHT9),0);
D3DVECTOR Lpos={10.f,10.f,10.f};
light2.Type = D3DLIGHT_POINT;
light2.Position =Lpos;
light2.Diffuse = Lcolor;
light2.Specular = light2.Diffuse;
light2.Range = 100.f;
light2.Attenuation0 = 1.f;
// Phase de pré-rendu
pDEV->SetRenderState(D3DRS_AMBIENT,
D3DCOLOR_COLORVALUE(0.2f,0.2f,0.2f,1.0f));
pDEV->SetRenderState(D3DRS_SPECULARENABLE,TRUE);
pDEV->SetRenderState(D3DRS_LIGHTING,TRUE);
pDEV->SetLight(0,&light1);
pDEV->SetLight(1,&light2);
pDEV->LightEnable(0,TRUE);
pDEV->LightEnable(1,TRUE);
Lectures et codes
U N IVERSIT É
D E R EIMS
C H AMP AGN E-A RD EN N E
Livres:
Testud : chapitre 11 et 13
Dempski : chapitre 8,10, et 11.
Codes:
SDK:
Tut02_Vertices
Tut04_Lights
CodeSampler:
cube.cpp
Vertex_Buffer.cpp
dx9_primitive_types
dx9_Lighting
dx9_Material

Documents pareils