|
@@ -1,3 +1,9 @@
|
|
|
+Financé par un concours d'innovation, VideoLabs avait démarré un projet de
|
|
|
+cinéma virtuel dans VLC, avec notamment le support multiplate-forme de plusieurs
|
|
|
+casques de réalité virtuelle. J'ai eu l'occasion d'y participer afin d'améliorer
|
|
|
+le moteur de rendu, maintenir le code et tenter d'optimiser le moteur de rendu
|
|
|
+pour le faire fonctionner sur des laptops sans chipset graphique dédié.
|
|
|
+
|
|
|
\section{Fonctionnement}
|
|
|
|
|
|
Le cinéma 3D est fait pour fonctionner dans un contexte de réalité virtuelle, la
|
|
@@ -30,8 +36,80 @@ Le fragment shader s'exécute pour chaque pixel à afficher et peut définir des
|
|
|
règles d'interpolation sur les paramètres qu'il récupère depuis le vertex
|
|
|
shader.
|
|
|
|
|
|
-Dans le fichier \texttt{modules/video\_output/opengl/fragment\_shader.c}, on peut
|
|
|
-retrouver le fragment shader.
|
|
|
+On peut retrouver le code du fragment shader dans
|
|
|
+\texttt{modules/video\_output/opengl/fragment\_shader.c}, tandis que le code du
|
|
|
+vertex shader sera dans \texttt{modules/video\_output/opengl/vout\_helper.c}.
|
|
|
+
|
|
|
+Le travail d'amélioration du rendu a consisté à modifier le fragment shader, le
|
|
|
+vertex shader ansi que le code générant les commandes de dessin pour le GPU.
|
|
|
+
|
|
|
+L'algorithme d'illumination qui a été implémenté est Blinn-Phong, pris depuis le
|
|
|
+livre \textit{More Opengl Game Programming}\cite{Karayanis:2005:MOG:1051376}. En
|
|
|
+particulier, il s'agissait ici d'un algorithme de Forward rendering en une seule
|
|
|
+passe, c'est-à-dire que l'ensemble des lumières était rendues dans le fragment
|
|
|
+shader pour chaque objet affiché.
|
|
|
+
|
|
|
+La caractéristique de Blinn-Phong est de prendre en compte des directions
|
|
|
+supplémentaires pendant le rendu: ici il n'est pas complet, la contribution
|
|
|
+spéculaire étant absente.
|
|
|
+
|
|
|
+\begin{code}{c}{Extrait du fragment shader concernant Blinn-Phong}
|
|
|
+result = vec4(ambient * SceneAmbient, 1.f);
|
|
|
+for(int i=0; i<5; ++i) {
|
|
|
+ vec3 light_pos_world= Lights.Position[i];
|
|
|
+
|
|
|
+ vec3 light_to_object = Position_world - light_pos_world;
|
|
|
+ vec3 spot_dir = normalize(Lights.Direction[i]);
|
|
|
+
|
|
|
+ float distance = length(light_to_object);
|
|
|
+ float attenuation = Lights.Kq[i] * distance * distance;
|
|
|
+
|
|
|
+ vec3 light_dir = light_to_object / distance;
|
|
|
+ vec3 light_diffuse = Lights.Diffuse[i];
|
|
|
+ float light_spot_dot = dot(light_dir, spot_dir);
|
|
|
+
|
|
|
+ vec3 light_contribution =
|
|
|
+ 1 + max(0, dot(-light_dir, normal_world))
|
|
|
+ * light_diffuse * diffuse / attenuation;
|
|
|
+
|
|
|
+ result.xyz += light_spot_dot * light_contribution/2;
|
|
|
+}
|
|
|
+\end{code}
|
|
|
+
|
|
|
+\section{Amélioration des performances}
|
|
|
+
|
|
|
+La modification précédente a eu un impact très négatif sur les performances pour
|
|
|
+les laptops les moins équipés. Sur mon ordinateur de travail, je suis ainsi
|
|
|
+passé de 200 images par secondes à seulement une quinzaine.
|
|
|
+
|
|
|
+J'ai alors utilisé \inltype{apitrace} pour mieux mesurer ce qui posait problème,
|
|
|
+révélant sans surprise qu'il s'agissait du fragment shader. Un simple
|
|
|
+redimensionnement de l'écran permet ainsi de gagner en performance.
|
|
|
+
|
|
|
+J'ai donc essayé plusieurs techniques, chacune n'apportant que peu de bénéfice
|
|
|
+
|
|
|
+\begin{itemize}
|
|
|
+
|
|
|
+ \item L'ajout d'algorithmes de frustrum culling,
|
|
|
+ \cite{Lengyel:2011:MGP:2031513} qui n'a pas eu que très peu
|
|
|
+ d'impact. En effet, les fragments en dehors de l'écran ne sont déjà pas pris
|
|
|
+ en compte par le fragment shader, mais cela confirme que l'ensemble des
|
|
|
+ ressources est monopolisé par ce fragment shader.
|
|
|
+
|
|
|
+ \item L'utilisation d'étape de early depth, où la géométrie est rendue sans
|
|
|
+ texture pour remplir le tampon de profondeur, puis la scène réelle est
|
|
|
+ rendue en éliminant directement les fragments ne validant pas le test de
|
|
|
+ profondeur.
|
|
|
+
|
|
|
+ \item Un début de tentative de rendu déféré, ayant les mêmes avantages que
|
|
|
+ le early depth, mais annulé devant le manque de gain de performance avec la
|
|
|
+ méthode précédente.
|
|
|
+
|
|
|
+\end{itemize}
|
|
|
+
|
|
|
+Malheureusement aucune n'a permis de résoudre le problème de performance, bien
|
|
|
+qu'il soit déjà intuitivement difficile de faire fonctionner un affichage de
|
|
|
+réalité virtuelle sur une station mal équipée.
|
|
|
|
|
|
% TODO: expliquer chargement de texture comme paramètre pour le fragment shader
|
|
|
% TODO: expliquer Blinn-Phong
|