M2-images
TP1 - openGL 4.3 et compute shaders
Partie 1 : aider le matériel
Modifiez votre tp précédent, l'objectif est de vérifier que l'on
peut dessiner les régions visibles de manière un peu plus efficace.
1. Activez le ztest hiérarchique.
constatez vous une différence ? dans quel cas ?
2. Afficher les régions en fonction de la distance à la camera.
L'idée est de remplir le zbuffer en dessinant des objets proches de
la camera avant de dessiner des objets plus éloignés.
Il suffit de modifer l'ordre dans lequel l'application parcours les
régions pour les dessiner.
Vous pouvez tester en triant les régions en fonction de la distance
(euclidienne) de leur centre à la camera.
Il est aussi possible d'utiliser une distance
"bloc" au lieu d'utiliser la distance euclidienne classique et
de parcourir les regions en anneaux autour de la camera (sans faire
de tri...)
constatez vous une différence ?
3. éliminez les cubes qui ne peuvent pas etre visibles.
Selon la pente du terrain, certains versants sont orientés vers la
camera et sont a priori visibles. Les autres versants (la normale du
terrain n'est pas orientée vers la camera) ne peuvent pas l'etre
(puisque la surface du terrain est sans trous). Utilisez un compute
shader pour construire la liste des cubes à dessiner, cf multi
draw indirect et tuto_mdi_count.
Vous pouvez continuer à utiliser un draw instancié pour dessiner une
region du terrain en modifiant la liste des instances à dessiner.
Mais il faut connaitre, dans l'application, le nombre d'instances à
dessiner. Il suffit d'utiliser un glDrawArraysIndirect() ou un
glMultiDrawArraysIndirect(). Le shader qui réalise les tests
d'orientation pourra comptabiliser le nombre de cubes à dessiner et
remplir lui-meme le parametre instance_count de la structure, cf tuto
MultiDraw. L'autre solution consiste à remplacer chaque
instance par une commande et à les dessiner en utilisant
glDrawArraysIndirectCountARB(), cf tuto
MultiDraw.
constatez vous une différence ? quelle solution est a priori la plus
interressante ? en pratique ?
4. et pour les ombres ?
quels sont les versants nécessaires au rendu des ombres ?
Le dessin de la géométrie pour les ombres n'a pas besoin de calculer
de couleur par fragment, éliminez le fragment shader du shader
program. que constatez-vous ?
indication : toutes les
cartes graphiques actuelles ont un fonctionnement optimisé dans ce
cas particulier, qui permet de remplir le zbuffer plus vite que
lorsqu'un fragment shader peut perturber la profondeur d'un fragment
(cf discard, ou modification directe de gl_FragDepth). cf rendu
différé / direct
bonus
: est-il possible et/ou interressant de tenir compte des
2 points de vues pour éliminer la géométrie à la fois pour les
ombres et pour le soleil ? (et de n'exécuter qu'une seule fois le
compute shader)
bonus : serait-il
interressant d'ajouter toute la batterie de tests de visibilité ?
Partie 2 (au choix) : beaucoup de lumière
Comment éclairer efficacement votre terrain avec plusieurs centaines
(ou quelques milliers) de sources de lumière ponctuelles ?
(à quoi cela peut-il bien servir ?)
Le principe est simple : éviter les calculs inutiles (et les
lectures/écritures de données inutiles)
Une source de lumière n'influence que les objets suffisamment
proches : comment déterminer le rayon d'influence d'une source
ponctuelle ?
indication : quel est le
flux reçut par un point à une distance d d'une source ponctuelle ?
L'idée consiste à déterminer, dans une première étape, pour chaque
bloc de pixels de l'image, quelles sources peuvent
influencer/éclairer la géométrie dessinée sur les pixels des blocs.
La deuxième étape calcule la couleur complète de chaque pixel, en
fonction des sources de lumières pouvant influencer son bloc.
indication
: commencez par la solution simple et directe : évaluez
toutes les sources pour chaque pixel et utilisez une seule brdf
pour décrire la matière des objets de la scène. Cette version de
base vous permettra de mesurer l'interet / la performance des
versions plus efficaces.
Il y a plusieurs solutions techniques :
un fragment shader et du rendu direct,
un fragment shader et du rendu différé,
un compute shader et du rendu differe.
comment construire la liste de sources de
lumière par bloc ?
est-il possible de réduire un bloc à 1 seul
pixel ? existe-t-il un interet à cette solution ?
Quel est l'interet de chaque categorie de solution ?
indication : combien de fois est lue
la liste de sources de lumière dans chaque cas ? quelle est
l'influence de la taille du bloc de l'image ?
Une vraie scène est composée plusieurs types de source de lumières
et de plusieurs types de brdfs (il faudra probablement des shaders
différents pour les évaluer, ou pas...).
Quelles sont les conséquences pour votre solution ?
pour les curieux : détails
sur la solution d'Unity.
Partie 3 (au choix) : beaucoup de pénombre
Comment calculer efficacement l'éclairage ambiant / ambient
occlusion. La solution directe nécessite un lancer de rayons pour
estimer la visibilité du ciel uniforme dans chaque direction.
Les approximations courantes n'utilisent que le zbuffer pour
réaliser ce calculs. Quels sont les défauts de ces approximations
?
Même les méthodes efficaces sont souvent trop longues à calculer,
l'éclairage ambiant varie souvent assez lentement dans l'image, ce
qui permet d'éviter de le calculer sur tous les pixels et
d'interpoler rapidement le résultat pour les autres.
Quelques propriétés doivent avoir les filtres utilisés pour
interpoler l'éclairage ambiant ?
Comment fonctionne le filtrage temporel ? trouvez la méthode
actuellement utilisée dans tous les moteurs. comment
fonctionne-t-elle ?
Quel est l'interet du filtrage temporel dans ce cas ?