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 ?