Avancement du 15/02/2016

Avancement :

  • GI calculée et interpolée dans le temps
  • Objets dynamiques 100% supportés
  • Filmic tone mapping
  • Vignetting
  • Ciel procédural
  • 2 bounces de lumières
  • Correction de pas mal de bugs

 

Actuellement 2 bounces de lumiere en 128×128 prend 500 ms sur une nvidia 650M.

Toujours autant de problèmes d’uv mapping, avec des effets sur les bords de pire en pire lorsque l’on diminue la taille de la texture.. C’est dommage parce qu’une texture 64×64 suffirait et dans ce cas la je calcule les 2 bounces en 13 ms…

Une texture 256×256 permet d’enlever presque tous les effets de bords mais il faut 2 secondes pour calculer la GI.

Capture

Capture

Rendu temps réel avec lumière et objet dynamique. Taille de la texture 128×128

Il semblerait que faire un uv unwrap parfait n’est pas un problème solvable. Il y a énormément de cas très compliqués (par exemple un quad plus petitequ’un pixel de la texture sur un axe et extremement grand sur un autre axe). La création de notre uv unwrapper nous a prit environs 50% du temps sur le projet, et je ne pense pas pouvoir l’améliorer en une semaine.

Du coup je pense que l’on va commencer le rapport et faire une petite GUI pour pouvoir modifier les paramètres de la scene pour la démo.

Avancement du 11/02/2016

Avancement :

  • PCF Shadow mapping
  • Anti aliasing par FFXA II
  • Amélioration de la GI

A faire :

  • GI temps réel (actuellement calculé en ~1sec, doit être répartit dans le temps)
  • Essayer de récuperer le rendu d’illumination directe depuis la caméra et de l’envoyer directement dans l’entrée de la GI
  • Multiple bounce
  • Camera freefly
  • Une vrai scène
  • Une petite GUI pour faire varier les différents réglages

Capture2

Capture

Avancement du 04/02/2016

Avancement de la semaine

Correction de certains problèmes et amélioration de l’existant :

  • Modification des UV de la lightmap pour avoir des zones carrées (moins de perte de place dans la texture donc plus de calcul de rendu)
  • Ajout d’un geometry shader pour résoudre le problème de conservative rasterization
  • Changement de la manière de faire le calcul de nos buffers (tous calculés en une fois au lieu de plusieurs fois)
  • Introduction d’un compute shader pour le calcul de l’ambiant occlusion permettant de se passer d’une phase de rasterisation inutile

 

Without_Conservative_Rasterization

Rendu sans conservative rasterization

With_Conservative_Rasterization

Rendu avec conservative rasterization

 

Avancement du 01/02/2016

Notre ligne directrice est désormais limpide.

 

Résumé de la semaine

Correction de certains problèmes de création d’uv lightmap pack :

  • Ajout d’une bordure entre chaque rectangle. Il n’y a plus de problème lorsque l’on sample la texture en nearest.
  • Il reste un problème de sampling de bordure en linear.
  • Il est très difficile de trouver des informations sur la génération de lightmap. Heureusement archive.org permet de remonter dans le temps sur le web et d’accéder à de vieux articles à l’époque où c’était très utilisé (quake 2/3, half life 1, …)

 

Génération de nos buffers de surfels :

  • Grâce à notre génération d’uv lightmap, on peut maintenant dessiner nos objets directement dans l’espace de notre texture de lightmap.
  • Par conséquent, à l’aide de simple pixel shader, on peut écrire deux textures qui contiendront les informations de nos surfels.

 

Notre première texture contient la position des surfels dans l’espace monde ainsi qu’un masque alpha précisant si l’on se trouve bien sur un surfel ou si l’on se trouve sur une bordure ou dans le fond de la texture.

0

 

Notre deuxième texture contient la direction de nos surfels (a.k.a les normales aux faces), ainsi que l’aire de nos surfels (sachant que dans notre cas, nos surfels ont tous la même aire, on pourrait sûrement se passer de cette donnée)

1

Un gros avantage de pouvoir dessiner nos objets directement dans nos textures est, pour un objet est dynamique, de ne mettre à jour seulement la partie des textures le concernant. Sans recalculer les surfels correspondant à nos objets statiques.

Le support d’objet dynamique est donc totalement envisageable et très peu coûteux.

Problème : Nos textures sont de très petites tailles (128×128). OpenGL admet qu’un pixel appartient à un triangle que l’on dessine, si et seulement si le triangle remplit plus de X% de l’espace de ce pixel. En dessinant dans nos petites textures ce n’est souvent pas le cas, et les pixels sont donc zappés.

42_conservative_01

Dans la figure ci-dessus, (a) montre ce que fait OpenGL, (b) montre ce que nous voulons faire.

Cela s’appelle la conservative rasterization. C’est un problème très récent, qui n’a pas encore de solution clef en main. Il existe des extensions Intel et Nvidia mais elles sont encore très peu supportées. Cela sera sûrement ajouté à la prochaine version d’OpenGL (ou de Vulkan). En attendant, il y a cet article présentant deux méthodes à l’aide de geometry shader pour corriger ce problème.

 

Une fois que l’on a nos deux textures d’informations, on peut appliquer une formule d’occlusion d’un surfel sur un autre :

14_ambient_occlusion_03

Il n’y a pas de formule magique ici, il suffit de trouver un facteur d’occlusion d’un surfel Emetteur sur un surfel Receveur en prenant en compte leur aire, leur distance, et leur orientation l’un par rapport à l’autre.

Exemple d’une formule d’occlusion :
ch14_eqn002

 

On peut ainsi générer notre texture d’occlusion ambiante :

ao

 

De là, obtenir l’illumination globale devient facile. En effet, il nous suffit de générer une troisième texture contenant l’illumination directe de nos faces (modèle d’illumination de Phong ainsi que la couleur de nos objets sera un bon début). Une fois cette troisième texture obtenue, il suffit d’appliquer une formule similaire à celle de l’occlusion ambiante permettant de définir la quantité de lumière qu’un surfel reçoit des autres.

 

A faire cette semaine

  • Régler ce problème majeur qu’est la Conservative Rastérization
  • Corriger le problème d’uv mapping en sampling linéaire
  • Il est difficile de stocker de manière intelligente des triangles dans une texture, on va donc passer en quad pour le moment. On perd beaucoup de temps sur cette génération d’uv lightmap. Peut être que l’on aurait pu passer par blender (ou autre) pour le faire, mais ça marche presque !
  • Créer un compute shader intelligent pour les transferts de lumière et d’occlusion entre surfels (par exemple répartir les calculs sur plusieurs frames)

 

Note

Cet article contient sûrement des explications obscures mais notre rapport sera plus clair.

Avancement du 26/01/2016

Choix d’implémentation

Nous avons décidés d’implémenter l’algorithme avec la lightmap puisque nous voulons pouvoir profiter de la possibilité de faire du bounces feedback. De plus, nous pensons que cette technique nous permettra de gagner du temps par rapport à l’autre technique puisque l’on fait moins de calculs d’illumination indirecte.

Taches réalisées

  • Pipeline gamma correct
  • Camera trackball
  • UV Unwrap
  • Texture packing
Capture

Test du lightmapping : chaque rectangle de la texture de droite correspond a une face sur Suzanne

Notes

Beaucoup de difficultés sur le packing de texture. On sample parfois 1 pixel à côté lorsque la texture est petite.. Problèmes de précisions.

 

Ligne directrice

Première option

  1. Créer un surfel pour chaque face
  2. Calculer l’illumination directe pour chaque surfel (et donc chaque face)
  3. Utiliser ces surfels pour calculer  l’illumination indirecte pour chaque pixel visible à l’écran
  4. Accélération du calcul par le calcul de l’illumination indirecte en demi résolution et en utilisant une reprojection spatiale dans le temps

Avantage

  • On ne perd aucun détail par rapport à la géométrie
  • Illumination indirecte calculée pour chaque pixel de l’écran
  • Géométrie dynamique sans problème

Inconvénient

  • Lent
  • L’illumination indirecte étant basse fréquence, est-il vraiment nécessaire de la calculer pour chaque pixel de l’écran ?
  • Impossible d’avoir plusieurs rebonds de la lumière

Deuxième option

  1. Créer une lightmap générale pour tous les meshs
  2. Calculer l’illumination directe pour chaque point de cette lightmap
  3. Calculer l’illumination indirecte pour chaque point de la lightmap
    1. Possibilité de trouver les points de la lightmap visible dans le frustum pour être plus rapide
    2. Si calcul de l’illumination indirecte rapide pour toute la lightmap, possibilité de calculer un autre rebond de la lumière dans le temps (bounces feedback !)

Avantage

  • Devrait être plus rapide que la première méthode
  • Bounces feedback
  • Nombre de lumières quasi-infini (un pixel de la lightmap qui est allumé émet, ça veut dire possibilité d’avoir de la GI pour des particules sans problèmes)

Inconvénient

  • Génération d’une lightmap cohérente difficile
  • Difficile de mettre a jour les coordonnées de texture en temps réel pour des objets dynamiques
  • Possibilité de perte de détails de la géométrie selon la taille de la lightmap (mais on s’en fiche ?)

Note

Le calcul de l’illumination directe pour toute la géométrie est un problème crucial car très coûteux. Enlighten de Geomerics se simplifie grandement la vie à ce niveau en ne prenant comme illumination directe que les points en screenspace; mais c’est vraiment de la triche !

 

Design a site like this with WordPress.com
Get started