-
Des Bases importantes avant de commencer -
Concernant
les Objets et les Mesh :
Dans la hierarchie d'une scène 3d et de ses objets,
A - On a d’abord le monde 3D avec son origine.
B - On a ensuite l’Objet, ou Game Object, dont les coordonées sont
globales, c’est à dire exprimées par rapport à l’origine du "monde". Il
est représenté par une Bounding Box dont la taille englobe le mesh.
C(a) - Dans le Game Object, il y a le Mesh ou la géométrie, soit
concrètement, les vertex dont les coordonées sont locales, c’est a dire
exprimées par rapport au pivot du Game Object.
C(b) - Dans le Game Object, il peut n'y avoir qu'un script, une IA, ou
bien rien et le Game Object ne sert que de repère, Null.
Concernant
les cycles de rendus
: les infos a calculer sont envoyées par “blocks” au GPU. Un bloc
d’infos correspond en général à un cycle de processeur. De base, on a
une passe/cycle pour le cacul des triangles, une passe d’eclairage, une
passe des texture, etc…
Il faut savoir que le GPU fait plusieurs milliers de cycles par
secondes de manière à pouvoir rendre la scène en temps reel.
Par exemple, par cycle de GPU, Unity envoie, calcule et rend des blocks
de 1000 a 1500 triangles. Il faut savoir qu'un mesh de 100 tris est
tout de même traité en un cycle. Dans Unity, mieux vaut donc rassembler
les petits objets en un seul mesh de taille moyenne(1000-1500 tris) que
d’avoir pleins de petits objets qui seront caculés chacun leur tour,
car, pour caricaturer, un Game Object avec géométrie = un cycle. Mais
il y a des écueils à éviter, si l’objet est sont éclairé en temps
réel par exemple. Ou s'il s'agit d'un autre type de moteur.
Dans Unreal Engine 3, il est fortement déconseillé de rassembler les
petits objets, justement à cause des éclairages temps réel.
Je vais tenter
de traduire et d'annoter une partie des étapes
- Scene/Geometry database traversal : calcul du placement des GameObjects dans
la scène
- Movement of objects, and aiming and movement of view camera
- Animated movement of object models :
calcul d'une possible animation des GameObjects
- Description of the contents of the 3D world
- Object Visibility Check including possible Occlusion Culling : calcul de visibilité, le Game Object est
il dans le champs de la caméra ? Le GameObject est il trop loin pour
être rendu ?
- Select Level of Detail (LOD) :
Selon la distance du Game Object par rapport à la cam, un LOD/mesh est
choisi
Une fois les Game Objects en place, un premier culling et les choix de
LOD effectués, peut alors commencer le traitement de la géométrie.
- Transforms (rotation, translation, scaling) : placement des vertex
- Transform from Model Space to World Space (Direct3D)
- Transform from World Space to View Space
- View Projection
- Trivial Accept/Reject Culling :
la face est elle ou non cachée par d’autres
- Back-Face Culling (can also be done later in Screen Space) : la normale est elle ou non tournée vers
la cam ?
- Lighting : quelle quantité
de lumière est reçue par le vertex - Si un Shader en Per Pixel Lighting
est utilisé, c'est calculé ici. Sur les nouveaux moteurs en deferred
rendering, le calcul de l'éclairage est fait à la rasterization en
utilisant un zbuffer et les normals au vertex.
- Perspective Divide - Transform to Clip Space
- Clipping : les vertexes sont ils
en dehors de la vue ?
- Transform to Screen Space : les
infos en 3D sont projetées sur le plan de l'écran, et deviennent des
informations 2D, exprimés avec des coordonées X,Y
- Slope/Delta Calculations : le calcul des plans des triangles
maintenant que l'on connait les coordonnées des vertex.
- Scan-Line Conversion : jusqu'ici
nous avions des informations de vecteurs, maintenant, ce sont des
pixels.
4.
Rendering / Rasterization
- Shading :
calcule la manière dont la lumière va se diffuser sur cette surface -
Si un Pixel Shader est utilisé, c'est calculé ici.
- Texturing
- Fog
- Alpha Translucency Tests :
calcul des transparences alpha
- Shadowing
- Depth Buffering : méthode old
school de calcul d'ordre des faces par lancé de rayon, aujourd'hui la
GPU le calcule automatiquement avec plus ou moins de précision. L'indice d'ordre de ces faces s'appelle
la Zlist, elle est définie par le Zbuffer.
- Antialiasing
- Display
- Quelque chose d’important pour la suite : le
Zbuffer -
Lorsqu'il est caculé, donne un ordre d’affichage des triangles en
fonction de la distance avec la caméra. Traditionnellement, le calcul
part du fond pour arriver aux objets les plus en avant. L'information
est ensuite inscrite dans le Zbuffer. L'ordre de ces faces est la Zlist.
DONC
:
dans
un moteur traditionnel comme Unity, si une sectorisation n'est pas
effectuée, TOUS les triangles sont calculés, même s’ils sont derrière
un mur et même parfois s'ils sont hors champs, et cela malgré
l'occlusion culling.
Pour caricaturer, la phase de rasterization est la phase ou les
informations des elements 3D sont transformées en pixels 2D affichables
sur l’écran. Ces elements 2D peuvent prendre plusieurs formes. Ils
peuvent indiquer, les normals, les shaders, les ombres, les lumières,
etc... et seront composités.
Les nouveaux moteurs utilisent ce principe avec une technique appelée
Deferred Rendering.
Aujourd’hui, sur les nouvelles plateformes, les nouveaux moteurs
tentent de produire des passes d’information et de les “compositer” en
2d, GI/AmbOcc, shaders, lighting, etc…
Cela est prévu pour Unity 3. Et est deja utilisé dans UE3.
A l'heure actuelle sur Unity, on a une architecture de rendu hybride.
Mal optimisée. Un peu de ppshading ça va, mais trop ça va plus. Pas de
pps, le jeu est trop oldgen… etc… la transition est en cours.