<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C++, Qt et GPU &#187; Techniques</title>
	<atom:link href="https://blog.developpez.com/gpu/?cat=4&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/gpu</link>
	<description></description>
	<lastBuildDate>Fri, 24 May 2013 17:02:21 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Compléments sur l&#8217;article &#171;&#160;implémenter un Voxel Cone Tracing&#160;&#187;</title>
		<link>https://blog.developpez.com/gpu/?p=214</link>
		<comments>https://blog.developpez.com/gpu/?p=214#comments</comments>
		<pubDate>Sun, 12 May 2013 20:45:59 +0000</pubDate>
		<dc:creator><![CDATA[gbdivers]]></dc:creator>
				<category><![CDATA[Intermédiaire]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Techniques]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/gpu/?p=214</guid>
		<description><![CDATA[J&#8217;ai récement traduit l&#8217;article Implémenter un Voxel Cone Tracing, qui présente quelques difficultés techniques pour ceux qui ne sont pas habitués avec les concepts présentés dans cet article. Ce billet de blog à pour objectif de présenter ces concepts. Quelques &#8230; <a href="https://blog.developpez.com/gpu/?p=214">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>J&rsquo;ai récement traduit l&rsquo;article <a href="http://simonstechblog.blogspot.fr/2013/01/implementing-voxel-cone-tracing.html">Implémenter un Voxel Cone Tracing</a>, qui présente quelques difficultés techniques pour ceux qui ne sont pas habitués avec les concepts présentés dans cet article. Ce billet de blog à pour objectif de présenter ces concepts.<br />
<span id="more-214"></span></p>
<h1>Quelques définitions</h1>
<h2>Illumination globale</h2>
<p>Les techniques d&rsquo;illuminations globales (GI) visent à améliorer le rendu d&rsquo;une scène 3D, en prenant en compte aussi bien la lumière directe (les sources de lumières qui éclairent les objets) que la lumière indirecte (réflexion de la lumière sur les objets, qui éclaire d&rsquo;autres objets). Ces techniques permettent d&rsquo;obtenir des rendus réalistes, au prix d&rsquo;un temps de calcul relativement long (parfois trop pour être compatible avec du rendu en temps réel). Un domaine de la recherche actuelle vise à développer de nouveaux algorithmes d&rsquo;illumination globale compatible avec le temps réel (jeux 3D).</p>
<p style="text-align: center"><img src="http://upload.wikimedia.org/wikipedia/commons/0/0d/Global_illumination.JPG" alt="Exemple d'une scène rendu avec l'illumination globale" /></p>
<p style="text-align: center">(source : <a href="http://fr.wikipedia.org/wiki/Illumination_globale">Wikipédia &#8211; Illumination globale</a>)</p>
<h3>Illumination indirecte</h3>
<p>Dans l&rsquo;illumination directe (à gauche sur l&rsquo;illustration suivante), la lumière provenant d&rsquo;une source est directement réfléchie sur une surface, puis renvoyé vers la caméra. C&rsquo;est le modèle classique de calcul de la lumière en 3D, que l&rsquo;on retrouve par exemple dans le <a href="http://cpp.developpez.com/redaction/data/pages/users/gbdivers/qtopengl/?page=opengl#L5-A">modèle de Phong</a>. La lumière est alors décomposée en plusieurs composantes : la lumière ambiante (qui représente une illumination globale constante), la lumière diffuse (qui représente une diffusion de la lumière sur la surface) et la lumière spéculaire (qui représente une réflexion sur la surface).</p>
<p style="text-align: center"><img src="http://www.cgg-journal.com/2010-1/02/files/VPLs.png" alt="Principe de l'illumination indirecte" /></p>
<p style="text-align: center">(Source : <a href="http://www.cgg-journal.com/2010-1/02/index.html">Real-Time Global Illumination for Point Cloud Scenes</a>)</p>
<p>Dans l&rsquo;illumination indirecte, on considère que chaque surface qui reçoit de la lumière va à son tour en renvoyer. Il n&rsquo;y a donc plus qu&rsquo;une seule source de lumière, mais une infinité, correspondant à chaque surface qui renvoie de la lumière. Pour réaliser le rendu d&rsquo;une scène, il faut donc procéder de la façon suivante :</p>
<ol>
<li>pour chaque surface S1 visible par la caméra ;</li>
<li>pour chaque surface S2 visible depuis la surface S1 ;</li>
<li>calculer la lumière reçue par la surface S2 provenant de la source ;</li>
<li>calculer la lumière renvoyée par la surface S2 vers la surface S1 ;</li>
<li>calculer la lumière reçue par la surface S1 provenant de la surface S2 ;</li>
<li>calculer la lumière totale renvoyée par la surface S1 vers la caméra.</li>
</ol>
<p>Chaque étape doit prendre en compte plusieurs paramètres. Pour (3), il faut par exemple prendre en compte la distance entre la source et la surface S2 et l&rsquo;atténuation de la lumière en fonction de la distance. Pour (4), il faut prendre en compte les caractéristiques de la surface et sa capacité à réfléchir la lumière. Pour (5), il faut prendre en compte la distance entre les surfaces S1 et S2 et l&rsquo;angle d&rsquo;incidence. Pour (6), les capacités de réflexion de la surface S1 et la distance entre la surface S1 et la caméra.</p>
<p>Cette première approche simple peut largement être améliorée (et complexifiée), en prenant en compte par exemple que la lumière peut se réfléchir plusieurs fois sur des surfaces avant d&rsquo;atteindre la caméra (particulièrement important lorsque les surfaces sont très réfléchissantes, comme du verre ou du métal poli), de la diffusion de la lumière dans le brouillard ou la poussière (<a href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html">lumière volumétrique</a>, <a href="http://http.developer.nvidia.com/GPUGems/gpugems_ch21.html">éclat lumineux</a>), la présence de plusieurs sources lumineuses (voir des milliers de sources lumineuses dans le cas de particules incandescentes).</p>
<h3>Lancé de rayons</h3>
<p>Il existe plusieurs techniques de &laquo;&nbsp;lancés&nbsp;&raquo;. Elles reposent sur l&rsquo;idée que la lumière est constituée de rayons qui vont partir de des sources lumineuses, se réfléchir, diffuser et réfracter sur les différentes surfaces (chaque surface pouvant renvoyer plusieurs rayons), puis atteindre la caméra. Dans les techniques de photon mapping, on part des sources lumineuses, on émet des rayons et on les suit jusqu&rsquo;à la caméra (cette technique est décrite dans un autre <a href="http://simonstechblog.blogspot.fr/2012/06/photon-mapping-part-1.html">article du blog de Simon</a> et fera l&rsquo;objet d&rsquo;une traduction). Dans les techniques de lancé de rayons, on part de la caméra, on lance un rayon pour chaque pixel de l&rsquo;image finale et l&rsquo;on remonte jusqu&rsquo;aux sources de lumière (illustration suivante).</p>
<p style="text-align: center"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Ray_trace_diagram.svg/300px-Ray_trace_diagram.svg.png" alt="Principe du lancé de rayons" /></p>
<p style="text-align: center">(Source : <a href="http://en.wikipedia.org/wiki/Ray_tracing_(graphics)">Wikipédia &#8211; Raytracing</a>)</p>
<p>Dans la technique du lancé de cônes (Cone Tracing), présentée dans l&rsquo;article traduit, on remplace simplement les rayons par des cônes pour le calcul de l&rsquo;illumination.</p>
<h3>Occlusion ambiante</h3>
<p>Cette technique fera également l&rsquo;objet de <a href="http://simonstechblog.blogspot.fr/2011/06/ssao-using-line-integrals.html">plusieurs</a> <a href="http://simonstechblog.blogspot.fr/2012/10/angle-based-ssao.html">traductions</a> du blog de Simon, je la détaillerai à ce moment là.</p>
<p>Simplement pour comprendre l&rsquo;idée générale : lorsque deux surfaces sont proches (dans une fissure, un trou), la lumière indirecte diminue fortement et l&rsquo;on observe des ombres douces. Plus les surfaces sont proches et fermées, plus l&rsquo;ombrage sera important. L&rsquo;illustration suivante représente la même scène sans (en haut) et avec l&rsquo;occlusion ambiante (en bas). Remarquez en particulier l&rsquo;ombre dans l&rsquo;angle du mur et du sol et entre la sphère dans l&rsquo;image du bas.</p>
<p style="text-align: center"><img src="http://blog.developpez.com/gpu/files/2013/02/ambient-occlusion-2.png" /></p>
<p>Cette technique améliore fortement la qualité du rendu et commence à être très utilisée dans les jeux. Un de ses points forts est que pour un objet statique (ou peu dynamique), l&rsquo;occlusion ambiante ne varie pas (ou peu) et il est possible de la pré-calculer, le résultat étant mis dans une texture. Il suffit ensuite d&rsquo;appliquer la texture sur l&rsquo;objet lors du rendu, comme n&rsquo;importe quelle autre texture.</p>
<p>Il existe plusieurs algorithmes de calcul de l&rsquo;occlusion ambiante, mais pour comprendre le principe, voyons un exemple simple représenté dans l&rsquo;illustration suivante. Pour chaque point d&rsquo;une surface, on va lancer un nombre fixé de rayons qui vont parcourir une distance fixée aussi dans toutes les directions. On compte ensuite le nombre de rayons qui ne rencontrent pas une autre surface et on calcul le rapport entre le nombre de rayons ayant rencontrés une surface et le nombre de rayons lancés. Ainsi, dans l&rsquo;illustration suivante, pour le point A, sur les six rayons lancés, aucun ne rencontre de surfaces, le rapport est de 0/6 = 0 %. Pour le point B, seul quatre rayons ne rencontrent pas de surfaces sur les six lancés, le rapport est de 4/6 = 66 %. Pour le point C, deux rayons ne rencontrent pas de surfaces, le rapport est de 2/6 = 33 %.</p>
<p style="text-align: center"><img src="http://blog.developpez.com/gpu/files/2013/02/ambient-occlusion.png" /></p>
<p>Il suffit ensuite d&rsquo;atténuer la lumière pour chaque point en fonction du rapport calculé. Plus le rapport est proche de 0 %, plus la surface sera sombre et plus le rapport est proche de 100 %, plus la surface est claire.</p>
<p>Pour obtenir un bon rendu, on pourra augmenter le nombre de point et le nombre de rayons lancés, mais l&rsquo;impact sur les performances sera important.</p>
<h2>Partitionnement de l&rsquo;espace</h2>
<h3>Voxel</h3>
<p>Le principe des voxels est relativement simple : ils sont l&rsquo;équivalent en 3D des pixels pour la 2D. Un exemple bien connu d&rsquo;utilisation des voxels est le jeu Minecraft, dans lequel chaque élément (terrain, objets) sont représentés par des cubes.</p>
<p style="text-align: center"><img src="http://upload.wikimedia.org/wikipedia/en/7/74/Minecraft_city_hall.png" alt="Un exemple d'utilisation des voxels bien connu : Minecraft" /></p>
<p style="text-align: center">(Source : <a href="http://en.wikipedia.org/wiki/Minecraft">Wikiépdia &#8211; Minecraft</a>)</p>
<p>Les voxels sont particulièrement gourmand en termes de performances et sont encore peu utilisés pour les jeux vidéos. Ils sont particulièrement adaptés pour le rendu de volumes transparents (verre, liquide, fumée, nuage) ou de géométries très complexes (pour le rendu d&rsquo;un mesh complexe, une approche utilisant une version <a href="http://en.wikipedia.org/wiki/Low_poly">low poly</a> du mesh et une texture des <a href="http://fr.wikipedia.org/wiki/Displacement_mapping">Displacement</a>/<a href="http://fr.wikipedia.org/wiki/Normal_mapping">Normal</a>/<a href="http://fr.wikipedia.org/wiki/Bump_mapping">Bump</a> mapping).</p>
<h3>Octree</h3>
<p>Un octree est une structure permettant de partitionner l&rsquo;espace dans un arbre, permettant par exemple de faciliter la recherche d&rsquo;un élément par rapport à sa position 3D. La construction d&rsquo;un tel arbre est simple : à chaque itération, le cube représentant une partie de l&rsquo;espace est divisé en 8 cubes.</p>
<p style="text-align: center"><img src="http://http.developer.nvidia.com/GPUGems2/elementLinks/37_octree_03.jpg" alt="Division de l'espace avec un octree" /></p>
<p style="text-align: center">(Source : <a href="http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter37.html">GPU Gems 2 &#8211; Octree Textures on the GPU</a>)</p>
<p>L&rsquo;intérêt des octrees avec les voxels est que l&rsquo;on va pouvoir utiliser une structure &laquo;&nbsp;creuse&nbsp;&raquo; : les zones qui sont vides ne seront pas divisées en cubes plus petits, simplifiant ainsi les algorithmes de recherche et la mémoire.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction aux geometry shaders</title>
		<link>https://blog.developpez.com/gpu/?p=1</link>
		<comments>https://blog.developpez.com/gpu/?p=1#comments</comments>
		<pubDate>Thu, 12 Apr 2012 08:14:02 +0000</pubDate>
		<dc:creator><![CDATA[gbdivers]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Facile]]></category>
		<category><![CDATA[Geometry shaders]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[A la demande de LittleWhite, mon premier bloc technique est consacré à l&#8217;utilisation des geometry shader. Il n&#8217;y a rien de tres compliqué donc je présente un exemple simple apres quelques rappels. Pour ceux qui ne connaissent pas du tout &#8230; <a href="https://blog.developpez.com/gpu/?p=1">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A la demande de LittleWhite, mon premier bloc technique est consacré à l&rsquo;utilisation des geometry shader. Il n&rsquo;y a rien de tres compliqué donc je présente un exemple simple apres quelques rappels. Pour ceux qui ne connaissent pas du tout les geometry shaders, je ferais un article plus detaille sur ce sujet.<br />
Pour faire au plus simple, j&rsquo;utilise Qt et en particulier QShaderProgram, qui gère les geometry shaders depuis Qt 4.7.<br />
<span id="more-1"></span></p>
<p><em><strong>Quelques rappels</strong></em><br />
Les geometry shaders sont optionnels et s&rsquo;intercalent entre les vertex shaders et les fragment shaders. Ils travaillent sur des primitives (triangle, ligne, points, avec un maximum de 6 vertices) et permettent de générer d&rsquo;autres primitives. Ils sont disponibles dans le Core depuis OpenGL 3.2 / GLSL 1.5 ou avant avec l&rsquo;extension GL_ARB_geometry_shader4 (en ajoutant le code #extension GL_EXT_geometry_shader4 : enable dans le geometry shader).</p>
<div class="codecolorer-container cpp blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #666666;">// Rechercher la présence de GL_EXT_geometry_shader4 pour &nbsp; </span><br />
&nbsp; &nbsp; <span style="color: #666666;">// tester si les geometry shaderssont pris en charge </span><br />
&nbsp; &nbsp; glGetString<span style="color: #008000;">&#40;</span>GL_EXTENSIONS<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> &nbsp;<br />
&nbsp; &nbsp; glGetStringi<span style="color: #008000;">&#40;</span>GL_EXTENSIONS, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// GL 3.2 </span><br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Créer un geometry shader </span><br />
&nbsp; &nbsp; glCreateShader<span style="color: #008000;">&#40;</span>GL_GEOMETRY_SHADER<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; QGLShader shader<span style="color: #008000;">&#40;</span>QGLShader<span style="color: #008080;">::</span><span style="color: #007788;">Geometry</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Qt 4.7 </span><br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Gérer les informations de position </span><br />
&nbsp; &nbsp; gl_PositionIn<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// position du vertex i en entrée </span><br />
&nbsp; &nbsp; gl_Position<span style="color: #008080;">;</span> <span style="color: #666666;">// position du nouveau vertex émis </span><br />
&nbsp; &nbsp; gl_in<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">gl_Position</span><span style="color: #008080;">;</span> <span style="color: #666666;">// GLSL &gt; 330 </span><br />
&nbsp; &nbsp; gl_in.<span style="color: #007788;">length</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// GLSL &gt; 330, nombre de vertices en entrée </span><br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Générer des vertices et primitives (GLSL) </span><br />
&nbsp; &nbsp; EmitVertex<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; EndPrimitive<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Spécifier le type de primitives en entrée et sortie </span><br />
&nbsp; &nbsp; <span style="color: #666666;">// (GLSL) </span><br />
&nbsp; &nbsp; layout <span style="color: #008000;">&#40;</span>triangles<span style="color: #008000;">&#41;</span> in<span style="color: #008080;">;</span> <span style="color: #666666;">// points, lines, triangles, lines_adjacency ou triangles_adjacency </span><br />
&nbsp; &nbsp; layout <span style="color: #008000;">&#40;</span>triangle_strip<span style="color: #008000;">&#41;</span> out<span style="color: #008080;">;</span> <span style="color: #666666;">// points, line_strip ou triangle_strip </span><br />
&nbsp; &nbsp; layout <span style="color: #008000;">&#40;</span>max_vertices <span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span> out<span style="color: #008080;">;</span> <span style="color: #666666;">// maximum = GL_MAX_GEOMETRY_OUTPUT_VERTICES </span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// (Qt) </span><br />
&nbsp; &nbsp; program_shader.<span style="color: #007788;">setGeometryInputType</span><span style="color: #008000;">&#40;</span>GL_TRIANGLES<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; program_shader.<span style="color: #007788;">setGeometryOutputType</span><span style="color: #008000;">&#40;</span>GL_LINE_STRIP<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; program_shader.<span style="color: #007788;">setGeometryOutputVertexCount</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">6</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>Lors de l&rsquo;appel à glDrawArray ou glDrawElement, il faut que le type spécifié corresponde au type d&rsquo;entrée du geometry shader. Les correspondances autorisées sont :</p>
<ol>
<li>points : GL_POINTS</li>
<li>lines : GL_LINES, GL_LINE_LOOP ou GL_LINE_STRIP</li>
<li>triangles : GL_TRIANGLES, GL_TRIANGLE_FAN ou GL_TRIANGLE_STRIP</li>
<li>lines_adjacency : GL_LINES_ADJACENCY</li>
<li>triangles_adjacency : GL_TRIANGLES_ADJACENCY</li>
</ol>
<p>Les nouveaux types ADJACENCY (GL_LINES_ADJACENCY, GL_LINE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY et GL_TRIANGLE_STRIP_ADJACENCY) permettent d&rsquo;accéder aux vertices des primitives voisines de la primitive en cours de traitement.</p>
<p><img src="http://gbelz.developpez.com/blog/geometry-shader.png" alt="Exemple d'affichage des vecteurs normaux" title="Exemple d'affichage des vecteurs normaux" /></p>
<p><strong><em>Un exemple simple</em></strong><br />
L&rsquo;exemple choisit est tres tres classique. Il permet d&rsquo;afficher le mailage d&rsquo;un mesh, les vecteurs normaux des faces et de calculer les vecteurs normaux de chaque face (flat mode). Cet exemple me permet également d&rsquo;introduire quelques classes simples, pour lire un fichier .obj (version simplifiee), calculer les vecteurs normaux, initialiser un contexte GL avec Qt.</p>
<p>Pour l&rsquo;affichage des vecteurs normaux et des triangles, on a besoin des positions et des normales, que l&rsquo;on passent donc aux shaders en attributs. </p>
<p>Pour afficher les vecteurs normaux dans le geometry shader, on prend un seul vertex en entree (input = points) et l&rsquo;on retourne une ligne (output = lignes, size = 2), dont le premier point est la position du vertex et le second point est la position du vertex auquel on ajoute le vecteur normal (multiplie par une constante, passee comme uniform, pour modifier la longueur du vecteur)</p>
<p>Pour afficher les triangles, on recupere un triangle en entree (input = triangles) et l&rsquo;on retourne 3 lignes (output = lignes, size = 6). Chaque points correspond a la position d&rsquo;un vertex decale legerement par le vecteur normal (pour que les lignes soient bien visibles et ne soient pas cachees par les triangles).</p>
<p><a href="http://gbelz.developpez.com/blog/geometry-shader.zip">Télécharger le projet d&rsquo;exemple</a></p>
<p><strong><em>A suivre&#8230;</em></strong></p>
<ol>
<li><a href="http://www.google.fr/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=4&amp;cts=1331312136494&amp;ved=0CEwQFjAD&amp;url=http%3A%2F%2Fweb.engr.oregonstate.edu%2F~mjb%2Fcs519%2FHandouts%2Fgeometry_shaders.1pp.pdf&amp;ei=ATZaT6zoFIiz8QPy3IXPDg&amp;usg=AFQjCNG9d-4Lpr0TbpuvK0iQrvmRVXKaMw&amp;sig2=zf5Oc9N-aIUMtgqDR-FXqw">Shrink, explosion, subdivision, silhouette, hedgehog</a></li>
<li><a href="http://www.twodee.org/blog/?p=805">Explosion, cheveux</a></li>
<li><a href="http://bat710.univ-lyon1.fr/~jpfarrug/Geometry.pdf">Instanciation et culling</a></li>
<li><a href="http://bat710.univ-lyon1.fr/~jciehl/Public/educ/M2PROIMA/2011/opengl_cm4.pdf">Instanciation et culling</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La technique d&#8217;instanciation</title>
		<link>https://blog.developpez.com/gpu/?p=3</link>
		<comments>https://blog.developpez.com/gpu/?p=3#comments</comments>
		<pubDate>Wed, 11 Apr 2012 12:01:48 +0000</pubDate>
		<dc:creator><![CDATA[gbdivers]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Facile]]></category>
		<category><![CDATA[Instanciation]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[L&#8217;instanciation est une technique permettant de dessiner plusieurs copies du même objet. Cette technique sera intéressante dans des scènes contenant des objets similaires : une forêt d&#8217;arbre, le feuillage d&#8217;un arbre, une foule, l&#8217;herbe d&#8217;une pelouse. L&#8217;instanciation Lorsque l&#8217;on souhaite &#8230; <a href="https://blog.developpez.com/gpu/?p=3">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>L&rsquo;instanciation est une technique permettant de dessiner plusieurs copies du même objet. Cette technique sera intéressante dans des scènes contenant des objets similaires : une forêt d&rsquo;arbre, le feuillage d&rsquo;un arbre, une foule, l&rsquo;herbe d&rsquo;une pelouse.<br />
<span id="more-3"></span></p>
<p><strong><em>L&rsquo;instanciation</em></strong><br />
Lorsque l&rsquo;on souhaite afficher de nombreux objets, la première approche pourrait être de faire plusieurs appels à glDrawArrays et glDrawElements. Le nombre d&rsquo;appels aux fonctions de dessin peut cependant diminuer fortement les performances. Une optimisation possible est d&rsquo;utiliser glMultiDrawArrays ou glMultiDrawElements, qui prennent des tableaux de données et permettent donc de faire qu&rsquo;un seul appel. Cependant, il est nécessaire d&rsquo;envoyer les données correspondantes à tous les objets que l&rsquo;on souhaite créer, ce qui peut saturer la bande passante du GPU.</p>
<div class="codecolorer-container cpp blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #666666;">// Extension GL_ARB_draw_instanced pour DrawArraysInstanced() et glDrawElementsInstanced() </span><br />
&nbsp; &nbsp; <span style="color: #666666;">// Extension GL_ARB_instanced_arrays pour VertexAttribDivisor() </span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Pour dessiner plusieurs objets </span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> glMultiDrawArrays<span style="color: #008000;">&#40;</span>GLenum mode, GLint <span style="color: #000040;">*</span>first, GLsizei <span style="color: #000040;">*</span>count, GLsizei primcount<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> glMultiDrawElements<span style="color: #008000;">&#40;</span>GLenum mode, GLsizei <span style="color: #000040;">*</span>count, GLenum type, GLvoid <span style="color: #000040;">**</span>indices, GLsizei primcount<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>L&rsquo;instanciation proprement dite permet de créer plusieurs instances d&rsquo;un objet. On envoie les données que pour un seul objet, ce qui réduit la bande passante.</p>
<p>Pour personnaliser chaque instance, on fournit un tableau de données (Instanced Array), chaque élément du tableau correspondant à une instance. On pourra passer ainsi modifier la position des instances, les paramètres de texture pour personnaliser les instances, ajouter du bruit, etc. Le paramètre <em>divisor</em> permet de spécifier quand on passe à l&rsquo;élément suivant dans un buffer. Pour <em>divisor</em> = 0, chaque vertex lit un nouvel élément dans le buffer. Avec <em>divisor</em> = 1, chaque instance lit un nouvel élément. Avec <em>divisor</em> = 2, un nouvel élément est lu toutes les 2 instances, etc.</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; // Création de plusieurs instances d'un objet <br />
&nbsp; &nbsp; void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount); <br />
&nbsp; &nbsp; void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); <br />
&nbsp;<br />
&nbsp; &nbsp; // Pour connaître l'identifiant de l'instance (GLSL) <br />
&nbsp; &nbsp; gl_InstanceID; // entre 0 et primcount-1 <br />
&nbsp;<br />
&nbsp; &nbsp; // Définir le mode de lecture des buffers <br />
&nbsp; &nbsp;glVertexAttribDivisor(location, divisor)</div></td></tr></tbody></table></div>
<p><em><strong>Un exemple simple</strong></em><br />
Le code d&rsquo;exemple affiche des cubes en utilisant glDrawElementsInstanced. Le curseur permet de sélectionner le nombre d&rsquo;instances à créer. Le bouton permet de basculer entre la vue des cubes pleins et en fil de fer. Les FPS et le nombre d&rsquo;instances sont indiqués dans le titre de la fenêtre. Je peux obtenir plus de 10 000 instances en même temps à 30 FPS (soit plus de 120 000 triangles) sur mon portable équipé d&rsquo;une 8600M GT.</p>
<p>Pour ceux qui testeraient avec du matériel plus puissant, il est possible d&rsquo;augmenter le nombre d&rsquo;instance maximal en modifiant le facteur multiplicateur à la ligne 127 du fichier glwidget.cpp ou la valeur maximale du QSlider à la ligne 22 du fichier mainwindow.cpp. J&rsquo;ai pu ainsi créer plus de 400 000 instances (4,8 millions de triangles) avant d&rsquo;arriver à 30 FPS sur une tour équipée d&rsquo;une GTX 460.</p>
<p><img src="http://gbelz.developpez.com/blog/instanciation.png" alt="Exemple d'affichage des cubes pleins (en haut) et en fil de fer (en bas)" title="Exemple d'affichage des cubes pleins (en haut) et en fil de fer (en bas)" /></p>
<p><a href="http://gbelz.developpez.com/blog/instanciation.zip">Télécharger le projet d&rsquo;exemple</a></p>
<p><em><strong>Au suivre&#8230;</strong></em><br />
* <a href="http://http.developer.nvidia.com/GPUGems/gpugems_ch07.html">gpu gems chap 7</a><br />
* <a href="http://sol.gfxile.net/instancing.html">http://sol.gfxile.net/instancing.html</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les queries objects</title>
		<link>https://blog.developpez.com/gpu/?p=5</link>
		<comments>https://blog.developpez.com/gpu/?p=5#comments</comments>
		<pubDate>Mon, 02 Apr 2012 11:10:51 +0000</pubDate>
		<dc:creator><![CDATA[gbdivers]]></dc:creator>
				<category><![CDATA[Facile]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Query object]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Les queries objects permettent d&#8217;interroger OpenGL pour obtenir des informations à propos des traitements effectués. Par exemple, les queries objects permetttent de récupérer les nombres d&#8217;instances/primitives restant après un occlusion culling dans un geometry shader. On utilise également des tableaux &#8230; <a href="https://blog.developpez.com/gpu/?p=5">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Les queries objects permettent d&rsquo;interroger OpenGL pour obtenir des informations à propos des traitements effectués. Par exemple, les queries objects permetttent de récupérer les nombres d&rsquo;instances/primitives restant après un occlusion culling dans un geometry shader. On utilise également des tableaux de queries objects pour tester chaque rendu et la technique de conditional rendering pour faire les tests de culling directement sur le GPU.<br />
<span id="more-5"></span></p>
<div class="codecolorer-container cpp blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #666666;">// Pour créer des queries objects </span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">void</span> glGenQueries<span style="color: #008000;">&#40;</span>GLsizei n, GLuint <span style="color: #000040;">*</span>ids<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;GLuint query<span style="color: #008080;">;</span> <br />
&nbsp; &nbsp;GLuint queries_array<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">20</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp;glGenQueries<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, <span style="color: #000040;">&amp;</span>query<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp;glGenQueries<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">20</span>, query_array<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #666666;">// Détruire des queries objects </span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">void</span> glDeleteQueries<span style="color: #008000;">&#40;</span>GLsizei n, <span style="color: #0000ff;">const</span> GLuint <span style="color: #000040;">*</span>ids<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;glDeleteQueries<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>, <span style="color: #000040;">&amp;</span>query<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp;glDeleteQueries<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">20</span>, query_array<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #666666;">// Lancer la query </span><br />
&nbsp; &nbsp;glBeginQuery<span style="color: #008000;">&#40;</span>GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_SAMPLES_PASSED : nombre de pixels écris </span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_ANY_SAMPLES_PASSED : true si au moins 1 pixel écris (GL &gt;= 3.3) </span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_PRIMITIVES_GENERATED </span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN &nbsp;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_TIME_ELAPSED : temps d'exécution en nanosecondes </span><br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #666666;">// Arrêter la query </span><br />
&nbsp; &nbsp;glEndQuery<span style="color: #008000;">&#40;</span>GL_SAMPLES_PASSED<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #666666;">// Récupérer le résultat de la query </span><br />
&nbsp; &nbsp;glGetQueryObjectuiv<span style="color: #008000;">&#40;</span>query, GL_QUERY_RESULT_AVAILABLE, <span style="color: #000040;">&amp;</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp;glGetQueryObject<span style="color: #008000;">&#40;</span>query, GL_QUERY_RESULT, <span style="color: #000040;">&amp;</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #666666;">// Conditionnal rendering </span><br />
&nbsp; &nbsp;glBeginConditionalRender<span style="color: #008000;">&#40;</span>query, GL_QUERY_WAIT<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// GL_QUERY_WAIT, GL_QUERY_NO_WAIT, GL_QUERY_BY_REGION_WAIT </span><br />
&nbsp; &nbsp;glEndConditionalRender<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
