<?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>RasterGrid Blog &#187; tessellation</title>
	<atom:link href="http://rastergrid.com/blog/tag/tessellation/feed/" rel="self" type="application/rss+xml" />
	<link>http://rastergrid.com/blog</link>
	<description>A technical blog from Daniel Rákos (aka aqnuep)</description>
	<lastBuildDate>Fri, 24 Feb 2012 03:23:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>GPU based dynamic geometry LOD</title>
		<link>http://rastergrid.com/blog/2010/10/gpu-based-dynamic-geometry-lod/</link>
		<comments>http://rastergrid.com/blog/2010/10/gpu-based-dynamic-geometry-lod/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 19:35:13 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[culling]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[LOD]]></category>
		<category><![CDATA[occlusion culling]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[tessellation]]></category>
		<category><![CDATA[vertex buffer]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=428</guid>
		<description><![CDATA[Dynamic geometry level-of-detail (LOD) algorithms are very popular and powerful algorithms that provide a great level of rendering performance optimization while preserving detail by using less detailed geometry for objects that are far away, too small or otherwise less significant in the quality of the final rendering. Many of these are used since the very]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F10%252Fgpu-based-dynamic-geometry-lod%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9M4KeD%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22GPU%20based%20dynamic%20geometry%20LOD%22%20%7D);"></div>
<div class="wp-caption alignleft" style="width: 210px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/10/mountains.png"><img class="  " title="Click to enlarge" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/mountains-thumb.png" alt="OpenGL 4.0 - Mountains demo" width="200" height="150" /></a><p class="wp-caption-text">OpenGL 4.0 - Mountains demo</p></div>
<p>Dynamic geometry level-of-detail (LOD) algorithms are very popular and powerful algorithms that provide a great level of rendering performance optimization while preserving detail by using less detailed geometry for objects that are far away, too small or otherwise less significant in the quality of the final rendering. Many of these are used since the very beginning of computer graphics technologies and are present in some form in current CAD softwares, video games and other graphics applications. While determining the appropriate geometry LOD was previously the task of the CPU, with todays hardware it is possible to also offload this to the GPU which excels at handling large amount of objects in parallel.<br />
<span id="more-428"></span></p>
<h2>Introduction</h2>
<p>With the advent of Shader Model 5.0 GPUs and the appearance of programmable tessellation hardware it may seem like the geometry LOD problem is solved once and for all. However, in many cases it is simply not enough as for far away objects even a patch pass-through tessellation shader already produces too much geometry than the added detail worths. As a result, classic geometry LOD algorithms are still a good-to-have feature in the tool-box of the developer. Not to mention that all vendors recommend disabling tessellation shaders at all if we don&#8217;t need any geometry amplification as even a pass-through tessellation shader does have its payload.</p>
<p>This means that there has to be still a conventional rendering path for geometries that should not be tessellated. Then why not to try offloading the geometry LOD determination to the GPU if possible?</p>
<p>This article presents a technique that was already presented by AMD&#8217;s <a title="March of the Froblins" href="http://developer.amd.com/samples/demos/pages/froblins.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/samples/demos/pages/froblins.aspx?referer=');">March of the Froblins</a> demo and by NVIDIA&#8217;s <a title="NVIDIA DX10 Samples" href="http://developer.download.nvidia.com/SDK/10/direct3d/samples.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/SDK/10/direct3d/samples.html?referer=');">Skinned Instancing</a> demo and allows GPU based dynamic geometry LOD determination using a geometry shader that selects the most appropriate LOD from a group of geometry LODs based on the object&#8217;s distance from camera. While this article and the reference implementation (<a title="OpenGL 4.0 - Mountains demo released" href="http://rastergrid.com/blog/2010/10/opengl-4-0-mountains-demo-released/">OpenGL 4.0 &#8211; Mountains demo</a>) presents the application of the technique only for instanced geometry, the same method can be easily extended to support heterogeneous objects by taking advantage of the latest functionalities introduced in OpenGL 4.</p>
<h2>The algorithm</h2>
<p>The technique is based on the geometry shader&#8217;s ability to emit or deny the emission of primitives into a transform feedback buffer as done in the mentioned DX based implementations. One major improvement compared to earlier approaches is that the LOD determination is done in a single pass rather than requiring a separate pass for each geometry LOD. Additionally, this LOD determination pass can be also merged together with other visibility determination passes like <a title="Instance culling using geometry shaders" href="http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/">Instance Cloud Reduction</a> or <a title="Hierarchical-Z map based occlusion culling" href="http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/">Hierarchical-Z map based occlusion culling</a> as it is done in the reference implementation. This was made possible thanks to the latest transform feedback capabilities introduced in OpenGL 4.0 (see the extension <a title="GL_ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">ARB_transform_feedback3</a>) that enables the geometry shader to output data to separate primitive streams.</p>
<div class="wp-caption aligncenter" style="width: 660px"><img class="    " title="Culling and dynamic LOD in the March of the Froblins demo" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/froblin-lod.png" alt="Culling and dynamic LOD in the March of the Froblins demo" width="650" height="340" /><p class="wp-caption-text">Flow-chart presenting the culling and dynamic LOD algorithms used in AMD&#39;s March of the Froblins demo. The implementation needs five passes for culling and separating three detail levels and performs two asynchronous queries meanwhile. Requires OpenGL 3 compliant hardware.</p></div>
<div class="wp-caption aligncenter" style="width: 660px"><img title="Culling and dynamic LOD in the Mountains demo" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/mountains-lod.png" alt="Culling and dynamic LOD in the Mountains demo" width="650" height="281" /><p class="wp-caption-text">Flow-chart presenting the culling and dynamic LOD algorithm used in our Mountains demo. The implementation requires only one pass for culling and separating three detail levels without the need to use asynchronous queries. Requires OpenGL 4 compliant hardware.</p></div>
<p>The algorithm itself is very simple and straightforward. For each object instance determine the appropriate geometry LOD based on it&#8217;s distance from the camera and the LOD distances passed as uniform to the shader. After this, output the instance&#8217;s data to the output stream ID that corresponds to the determined LOD&#8217;s index. Here you can see a GLSL implementation of the algorithm:</p>
<pre class="brush:c">#version 400 core

uniform mat4 ModelViewMatrix;
uniform vec2 LodDistance;

layout(points) in;
layout(points, max_vertices = 1) out;

in vec3 InstancePosition[1];

layout(stream=0) out vec3 InstPosLOD0;
layout(stream=1) out vec3 InstPosLOD1;
layout(stream=2) out vec3 InstPosLOD2;

void main() {
  float distance = length(ModelViewMatrix * vec4(InstancePosition[0], 1.0));
  if ( distance &lt; LodDistance.x ) {
    InstPosLOD0 = InstancePosition[0];
    EmitStreamVertex(0);
  } else
  if ( distance &lt; LodDistance.y ) {
    InstPosLOD1 = InstancePosition[0];
    EmitStreamVertex(1);
  } else {
    InstPosLOD2 = InstancePosition[0];
    EmitStreamVertex(2);
  }
}</pre>
<p>Additionally, the geometry LOD determination pass has to be executed with primitive queries enabled for all the relevant output streams to acquire the number of instances for each geometry LOD index:</p>
<pre class="brush:cpp">for (int i=0; i&lt;NUM_LOD; i++)
  glBeginQueryIndexed(GL_PRIMITIVES_GENERATED, i, lodQuery[i]);

glBeginTransformFeedback(GL_POINTS);
  glDrawArrays(GL_POINTS, 0, instanceCount);
glEndTransformFeedback();

for (int i=0; i&lt;NUM_LOD; i++)
  glEndQueryIndexed(GL_PRIMITIVES_GENERATED, i);</pre>
<p>Finally, the only thing what is left is to issue an instanced draw call for each geometry LOD index to draw all the instances:</p>
<pre class="brush:cpp">for (int i=0; i&lt;NUM_LOD; i++) {
  glGetQueryObjectiv(lodQuery[i], GL_QUERY_RESULT, instanceCountLOD[i]);
  if ( instanceCountLOD[i] &gt; 0 )
    glDrawElementsInstanced(..., instanceCountLOD[i]);
}</pre>
<p>That&#8217;s all, and what you get as a result is a fully GPU based geometry LOD selection algorithm.</p>
<h2>The Mountains demo</h2>
<p>The reference implementation provided as part of the <a title="OpenGL 4.0 - Mountains demo" href="http://rastergrid.com/blog/2010/10/opengl-4-0-mountains-demo-released/">OpenGL 4.0 &#8211; Mountains demo</a> that is available with full source code and Windows executable in the <a title="Mountains Demo download" href="http://rastergrid.com/blog/downloads/mountains-demo/">downloads section</a>. The demo application implements the same visibility determination algorithms that were presented in the <a title="SIGGRAPH 2008 Course Notes about the March of the Froblins" href="http://developer.amd.com/documentation/presentations/legacy/Chapter03-SBOT-March_of_The_Froblins.pdf" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/documentation/presentations/legacy/Chapter03-SBOT-March_of_The_Froblins.pdf?referer=');">SIGGRAPH 2008 Course Notes</a> besides the dynamic geometry LOD algorithm presented here in a single pass.</p>
<p>Dynamic LOD can be enabled in the demo by using the F3 key. After enabled, the demo separates the various geometry detail levels according to the LOD distances configured. As it can be seen, there is almost no visible difference between the scene rendered with dynamic geometry LOD enabled and disabled. Also, by setting the LOD distances appropriately, the algorithm provides seamless transition between subsequent geometry detail levels as the camera is moved.</p>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="background-color: #ffffff;" align="center">
<div class="wp-caption alignnone" style="width: 338px"><a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/lod-comp.png" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/10/lod-comp.png?referer=');"><img title="Click to enlarge" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/lod-comp-thumb.png" alt="Close-up view to compare image quality without and with dynamic LOD" width="328" height="160" /></a><p class="wp-caption-text">Close-up view of distant objects to compare the image quality without (left) and with (right) dynamic LOD.</p></div></td>
<td style="background-color: #ffffff;" align="center">
<p><div class="wp-caption alignnone" style="width: 223px"><a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/visual-lod.png" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/10/visual-lod.png?referer=');"><img title="Click to enlarge" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/visual-lod-thumb.png" alt="LOD visualization" width="213" height="160" /></a><p class="wp-caption-text">Geometry LOD visualization: LOD 0 (red), LOD 1 (green), LOD 2 (blue).</p></div></td>
</tr>
</tbody>
</table>
<p>When dyamic LOD is enabled, the demo also makes it possible to visualize the various geometry detail levels by pressing the F4 key. The highest detail LOD is marked with red, mid-level with green and the lowest detail geometries are marked as blue. It can be seen that as the camera moves the renderer automatically adjusts the detail of each individual instance.</p>
<p>Besides maintaining a constant quality without the viewer to observe any transitions between the various detail levels, the algorithm provides a huge performance gain in case of complex geometries as it can be seen on the figure below:</p>
<p><div class="wp-caption aligncenter" style="width: 654px"><img class="   " src="http://www.rastergrid.com/blog/wp-content/uploads/2010/10/mountains-fps.png" alt="Performance comparison of various culling and LOD techniques in frames per second on a Radeon HD5770 (higher is better)" width="644" height="224" /><p class="wp-caption-text">Performance comparison of the demo in frames per second on a Radeon HD5770 (higher is better): no culling (bottom), instance cloud reduction (middle), ICR + Hi-Z map based occlusion culling (top), no geometry LOD (blue), dynamic geometry LOD (red).</p></div>
<h2>Conclusion</h2>
<p>We&#8217;ve seen how straightforward is to implement GPU based dynamic geometry LOD determination using geometry shaders on OpenGL 4.0 compliant hardware providing also a reference implementation that uses the algorithm to efficiently determine detail levels for large number of instanced geometry. We also briefly mentioned that the algorithm can be extended to handle arbitrary object sets. We discussed about a possible OpenGL 3 based implementation but we did not provide one as it requires several rendering passes to perform all the operations that can be implemented in a single pass on Shader Model 5.0 hardware.</p>
<p>Even though the algorithm is already extremely efficient, it still involves the use of asynchronous primitive queries that may induce some latency. Of course, this latency can be easily hidden by performing other operations on the CPU/GPU until the results are available.</p>
<p>Furthermore, taking full advantage of Shader Model 5.0 GPUs it would be possible to eliminate the need of asynchronous queries by using atomic counters and indirect rendering, however the core OpenGL specification does not expose yet such functionality so this improvement is left for a future release of the demo.</p>
<p>Classic dynamic geometry LOD algorithms are still first class citizens of every rendering system and even though the introduction of hardware tessellation somewhat subsumes the need for these classic techniques, practice shows that the best way to implement a full-fledged dynamic LOD system is by using geometry LOD selection and tessellation together rather that one instead of the other.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/10/gpu-based-dynamic-geometry-lod/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>History of hardware tessellation</title>
		<link>http://rastergrid.com/blog/2010/09/history-of-hardware-tessellation/</link>
		<comments>http://rastergrid.com/blog/2010/09/history-of-hardware-tessellation/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 21:14:33 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[tessellation]]></category>
		<category><![CDATA[tessellation control shader]]></category>
		<category><![CDATA[tessellation evaluation shader]]></category>
		<category><![CDATA[tessellator]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[TruForm]]></category>
		<category><![CDATA[vertex shader]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=324</guid>
		<description><![CDATA[With the introduction of Shader Model 5.0 hardware and the API support provided by OpenGL 4.0 made GPU based geometry tessellation a first class citizen in the latest graphics applications. While the official support from all the commodity graphics card vendors and the relevant APIs are quite recent news, little to no people know that]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F09%252Fhistory-of-hardware-tessellation%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9lvtay%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22History%20of%20hardware%20tessellation%22%20%7D);"></div>
<div class="wp-caption alignleft" style="width: 260px"><img title="Geometry Tessellation" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/tessellation.png" alt="Geometry Tessellation" width="250" height="124" /><p class="wp-caption-text">Geometry Tessellation</p></div>
<p>With the introduction of Shader Model 5.0 hardware and the API support provided by OpenGL 4.0 made GPU based geometry tessellation a first class citizen in the latest graphics applications. While the official support from all the commodity graphics card vendors and the relevant APIs are quite recent news, little to no people know that hardware tessellation has a long history in the world of consumer graphics cards. In this article I would like to present a brief introduction to tessellation and discuss about its evolution that resulted in what we can see in the latest technology demos and game titles.<br />
<span id="more-324"></span></p>
<h2>Introduction</h2>
<p>Geometry tessellation is a graphics technique used to amplify the geometric details of a particular mesh. This is done by subdividing the polygons of the mesh into smaller polygons and, if needed, alter the position of the generated vertices to better fit the theoretical shape of the object that is being modeled by the mesh.</p>
<p>Tessellation was a commonly used technique in offline rendering softwares to add a greater level of realism to computer modeled objects as well as it has been often used as a preprocessing technique for real-time graphics applications. However, due to the increased number of geometry data, the usage of tessellated geometry was very limited in the early eras of real-time computer graphics as it needed huge amount of disk/memory storage as well as much higher processing capabilities in order to achieve interactive frame rates.</p>
<p>The key problem of an offline tessellation preprocessing and using a detailed mesh in real-time graphics is that even the latest generation of GPUs lack of the needed memory size and bandwidth to make this a practical approach and we are not even talking about additional costs that are involved by having a much larger dataset that has to be run through possibly complex vertex processing steps like skeletal animation. Having the tessellation technology integrated into the GPU makes it possible to overcome most of these restrictions.</p>
<p>While hardware tessellation as a generic feature made its way to the relevant APIs only in the recent past, there were a few earlier efforts already made by various hardware generations in order to make this technology popular. In order to present the evolution of hardware tessellation I will go through the relevant technologies in a chronological order to better see the reasons why this great feature didn&#8217;t make its way to the core API specifications until now.</p>
<h2>TruForm</h2>
<p>The first consumer graphics card featuring hardware tessellation that made its way to the market was the ATI Radeon 8500 in 2001. The tessellation feature of the GPU got known as TruForm and soon became available in OpenGL via the extension <a title="GL_ATI_pn_triangles" href="http://www.opengl.org/registry/specs/ATI/pn_triangles.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ATI/pn_triangles.txt?referer=');">GL_ATI_pn_triangles</a> but the functionality never made its way into core due to the lack of any similar hardware support from other graphics card vendors.</p>
<p>The tessellation hardware present in the Radeon 8500 was a completely fixed function component that had predefined tessellation evaluation modes even though the GPU had already support for both programmable vertex and fragment processing. It is also interesting that the tessellator operated on vertices emitted by the vertex shader if one was present.</p>
<div class="wp-caption aligncenter" style="width: 548px"><img class="   " title="Simplified rendering pipeline of the ATI Radeon 8500" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/sm14_tess.png" alt="Simplified rendering pipeline of the ATI Radeon 8500" width="538" height="160" /><p class="wp-caption-text">Simplified rendering pipeline of the ATI Radeon 8500</p></div>
<p>The tessellator itself has one configurable parameter: the tessellation level. This controls the amount of cuts that are performed over each edge of the input primitive which in case of TruForm must be always a triangle (whether it comes from a list, strip of fan). As the support for the extension has been removed a few years ago, unfortunately I cannot tell the upper limit for the tessellation level supported by TruForm but I remember as it was about 15 or so (I hope somebody can confirm it or correct me).</p>
<p>Beside that, the tessellation evaluator has a few other configurable parameters that control the way how vertex positions and normals are evaluated after the geometry amplification. For normals there is a linear and a quadratic interpolation mode, for vertex positions linear and cubic interpolation is available. All the rest of the vertex attributes are linearly interpolated over the tessellated geometry.</p>
<p>The good thing in TruForm is that it can be very simply added to an existing rendering engine implementation just by adding a few API calls but taking into account that the functionality of the hardware component can be only managed using rendering state limits tessellation parameter control to a per object basis and also means that changing the tessellation configuration breaks batches as well.</p>
<p>Another advantage of TruForm is that it works on transformed vertices which means that we can safely use tessellation with complex vertex processing techniques like skeletal animation without worrying about huge transformation costs that in case of a post-tessellation vertex shader would be inherent.</p>
<p>Another issue that is a must to be mentioned when one talks about hardware tessellation is crack-free rendering. As usually tessellation works on individual primitives there is often no guarantee that no cracks will appear between adjacent polygons after tessellation is applied. In case of TruForm this is relevant only if cubic position interpolation is used as only that mode alters the vertex positions themselves. In case this vertex position evaluation mode is used the artists must ensure that vertices on common edges have the same normal. This is quite a limiting factor in certain situations but should not cause any problems in the most of the common use cases.</p>
<p>A huge deficit of the original N-Patch implementation of ATI is that the tessellation evaluation is not programmable and has little to no options to control how the resulting vertices will look like. This meant that novel graphics techniques like displacement mapping were not possible to be implemented with it. While this is a quite severe limiting factor, TruForm was still a great feature for increasing the detail of already existing and upcoming game titles.</p>
<p>Unfortunately TruForm wasn&#8217;t that welcome by the developer community due to the additional burden brought to artists and the lack of flexibility from programming side. Still, I think the most important factor was the lack of wide adoption of the feature from other relevant vendors.</p>
<h2>Beyond TruForm</h2>
<p>After the original appearance of hardware tessellation there were several further efforts to make geometry tessellation a popular feature in real-time graphics. Besides ATI, Matrox also released GPUs with N-Patch support and ATI has also improved his TruForm feature with the appearance of the Radeon 9700. These cards were able to do two very important things that the original TruForm was lacking.</p>
<p>First, they provided means to do the tessellation evaluation based on a texture which enabled the implementation of displacement mapping. Second, and in my opinion even more important, that they supported adaptive tessellation which means that the tessellation factor was calculated dynamically based on the distance from the camera. Finally, the new tessellation implementations allowed also continuous tessellation mode thus allowing seamless transition between various tessellation levels.</p>
<p>Unfortunately I don&#8217;t know any OpenGL extensions that exposed this functionality and that means also that I&#8217;ve never had a closer look at them so if you are interested in these technologies you&#8217;ll have to do a little bit of search around the internet.</p>
<h2>Geometry Shaders</h2>
<p>After the failure of the early attempts to introduce hardware tessellation to the general public, the appearance of Shader Model 4.0 capable graphics cards made many developers think that we&#8217;re gonna see hardware tessellation in the form of geometry shaders. While actually some cards really had a new generation of tessellation hardware on the market this time that had nothing to do with geometry shaders, but I will talk about it later&#8230;</p>
<p>Many developers have incorrectly seen a practical tessellator in the form of the geometry shader at its appearance. While it is true that a geometry shader can in fact be used to perform geometry amplification, several hardware limitations in fact make this approach rather inefficient in practice. Anyway, first I will talk about how geometry shaders can be used for tessellation and after that I will tell why not to do so.</p>
<p>The geometry shader is a new programmable stage introduced by Shader Model 4.0 that operates on whole primitives after vertex processing and before primitive assembly. They have a fixed input and output primitive type that doesn&#8217;t have to match. This means it is possible to emit triangles even though the input primitives were points.</p>
<p>The greatest feature of geometry shaders is that they can output a dynamically adjustable amount of geometric primitives based on the input primitive including even the possibility to discard the current primitive. The first allows us to do a certain amount of geometry amplification with them and evaluate the output primitives as we wish (of course, within the boundaries of the possibilities of a shader). The only limiting factor is the upper limit of the output buffer available on the target hardware. This, in fact is a rather limiting factor, especially in case of large number of vertex attributes.</p>
<div class="wp-caption aligncenter" style="width: 454px"><img title="Simplified rendering pipeline of Shader Model 4.0" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/sm40_tess.png" alt="Simplified rendering pipeline of Shader Model 4.0" width="444" height="160" /><p class="wp-caption-text">Simplified rendering pipeline of Shader Model 4.0</p></div>
<p>In this use case scenario, the geometry shader acts like both the tessellator and the evaluator as it is used for both the execution of the geometry amplification as well as the interpolation of the vertex attributes. This provides almost complete flexibility over how we would like to implement our tessellation algorithm. We can choose the tessellation factor as part of the programmable stage so adaptive tessellation is no problem. Also we can easily add displacement mapping or any other technique to control how our newly generated primitives will be positioned and oriented.</p>
<p>Now, as we have seen how easy and flexible is a geometry shader based tessellation implementation, let&#8217;s see the dark side of it&#8230;</p>
<p>First of all, as the geometry shader is a revolutionary feature compared to earlier programmable GPU capabilities it suffer from the fact that it doesn&#8217;t really fit into the existing architecture. Previously, every fixed-function and programmable hardware component on the GPU had a fixed amount of input and output data making it possible to create a kind of a synchronous pipeline architecture. This way it was rather easy for the execution dispatcher to share workload over the computing units and keep them all the time busy (at least most of the time).</p>
<p>The programmable amount of output data made possible by geometry shaders somewhat breaks this synchronous architecture. This means that a more dynamic dispatching mechanism is required to control the consumption of the data output by it. In order to achieve this there are two important issues:</p>
<p>First, there should be a temporary buffer that will hold the output as we cannot guarantee that the outputs can be immediately fed to the subsequent stages of the rendering pipeline. This has been implemented by memory buffers and/or caches by the various vendors.</p>
<p>Second, due to the geometry shader can be executed in parallel (at least in theory) and various instances of the geometry shader can output various amount of primitives, there can be problems with the synchronization of data emissions and the order in what output primitives will take place in the output buffer.</p>
<p>AMD solved these problems by introducing a new cache that is meant to handle the special nature of primitive emissions executed by the geometry shader. Unfortunately NVIDIA&#8217;s implementation is much more limited and, as far as I can tell, it may result in that geometry shader instances are executed only on one or just a few computing units which can severely degrade performance in case of tessellation. This is the reasoning behind why we have to specify in GLSL the maximum number of primitives that our geometry shader can output. This is used as an input for NVIDIA drivers to plan the necessary storage strategy for the geometry shader and in fact they have no any effect in case of AMD GPUs. So if you want your geometry shader to run faster on AMD GPUs, just set this maximum limit as high as possible <img src='http://rastergrid.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>There is another problem with a geometry shader based tessellator implementation: the geometry amplification is done iteratively within a single shader which is quite a waste in case of a highly parallelized processor architecture like that of the GPU. This results in a reasonable amount of delay.</p>
<p>Back to the topic that geometry shaders break the synchronous nature of GPUs, I would like to talk about how the number and type of emitted primitives affect the overall performance of the rendering pipeline (not even considering the aforementioned negative factors).</p>
<p>The best performance can be achieved in case both the input and output primitive type of the geometry shader is the same (e.g. triangle -&gt; triangle). Besides that, usually GPUs have an accelerated path for outputting four vertices for one vertex input (e.g. point -&gt; triangle strip) that is useful for rendering point sprites or billboards. All the other combinations should be avoided if possible.</p>
<p>I hope I was clear enough to convince all of you that geometry shaders are not meant for tessellation as I really gone mad when I&#8217;ve seen that everybody was just talking about this particular use case when in fact geometry shaders are much more useful in other situations.</p>
<h2>Tessellation on HD2000 series</h2>
<p>The true successor of the original hardware tessellation feature reappeared with the Xbox360&#8242;s GPU and then for PC with the introduction of the AMD Radeon HD2000 series. This hardware generation came equipped with a fixed function hardware tessellator similar of that of the Radeon 8500 but with added programming flexibility. The functionality is accessible in OpenGL through the extension <a title="GL_AMD_vertex_shader_tessellator" href="http://www.opengl.org/registry/specs/AMD/vertex_shader_tessellator.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/vertex_shader_tessellator.txt?referer=');">GL_AMD_vertex_shader_tessellator</a> but, again, it didn&#8217;t make it its way into core OpenGL, neither into DX10 due to the lack of support on NVIDIA GPUs. The extension in fact turns the traditional vertex shader into a tessellation evaluation shader (or a domain shader in DX terminology) and even though the extension does not explicitly names it as such I will sometimes refer it this way.</p>
<p>Still, one important restriction has to be mentioned regarding to the presented functionality, namely that this tessellation mechanism cannot be used together with geometry shaders due to hardware limitations. My guess is that most probably the tessellator output is emitted to the same cache that is used by geometry shaders (somebody from AMD can confirm this or correct me).</p>
<div class="wp-caption aligncenter" style="width: 454px"><img class=" " title="Simplified rendering pipeline of the AMD Radeon HD2900 with tessellation" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/hd2000_tess.png" alt="Simplified rendering pipeline of the AMD Radeon HD2900 with tessellation" width="444" height="160" /><p class="wp-caption-text">Simplified rendering pipeline of the AMD Radeon HD2900 with tessellation</p></div>
<p>The upgraded vertex shader introduced by the extension is provided with barycentric coordinates generated by the tessellator and with the control point indices (three indices in case of a triangle and four in case of a quad). The actual control point data is then fetched from within the vertex buffers used.</p>
<p>One important disadvantage of the tessellation architecture provided by the extension is that there is no programmable stage before the tessellator which does not allow us to do expensive per-vertex operations on the control cage (e.g. skeletal animation). Fortunately, it is very easy to overcome this limitation as on this hardware generation we already have transform feedback (stream out in DX terminology) and auto draw at our disposal. This way we can simply use an additional rendering step and an auxiliary buffer to make things working as expected.</p>
<div class="wp-caption aligncenter" style="width: 643px"><img title="Using transform feedback to add real vertex shaders to the rendering pipeline in case tessellation is used on AMD Radeon HD2900" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/hd2000_tess2.png" alt="Using transform feedback to add real vertex shaders to the rendering pipeline in case tessellation is used on AMD Radeon HD2900" width="633" height="160" /><p class="wp-caption-text">Using transform feedback to add real vertex shaders to the rendering pipeline in case tessellation is used on AMD Radeon HD2900</p></div>
<p>The maximum tessellation level is 15 and there is a discrete and a continuous tessellation mode that is configurable using API calls.</p>
<p>While this looks already almost like the tessellation mechanism introduced by DX11, the key disadvantage is the lack of adaptive tessellation, that is the possibility to algorithmically define the tessellation level on the GPU. This makes it rather impractical for dynamic LOD based tessellation level selection as the required API calls would be batch breakers.</p>
<p>Still, I think this feature should have caught the attention of developers but it seems that it remained only the tool of tech demos as developers have rather waited for the appearance of DX11 that forced NVIDIA to finally implement their own hardware tessellator.</p>
<h2>Tessellation shader</h2>
<p>Finally, with the advent of Shader Model 5.0 GPUs we have our &#8220;official&#8221; hardware tessellation. The functionality is exposed in OpenGL via the extension <a title="GL_ARB_tessellation_shader" href="http://www.opengl.org/registry/specs/ARB/tessellation_shader.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/tessellation_shader.txt?referer=');">GL_ARB_tessellation_shader</a> what was introduced as part of the fourth major revision of the specification. The extension introduces two new shader types: the tessellation control shader (referred to as hull shader in DX11) and the tessellation evaluation shader (domain shader in DX terminology).</p>
<p>The new feature enables programmable tessellation levels up to 64 via the newly introduced tessellation control shader that allows us to process our control points in parallel yet synchronized manner.</p>
<div class="wp-caption aligncenter" style="width: 663px"><img class=" " title="Simplified rendering pipeline of Shader Model 5.0 GPUs" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/sm50_tess.png" alt="Simplified rendering pipeline of Shader Model 5.0 GPUs" width="653" height="160" /><p class="wp-caption-text">Simplified rendering pipeline of Shader Model 5.0 GPUs</p></div>
<p>This final revision of the feature allows us to use all the advanced techniques needed for a novel tessellation based renderer like adaptive continuous tessellation and displacement mapping. Also the vertex shader is completely separate and even though many of the vertex shader tasks have to be moved to the tessellation evaluation shader, complex operations like skeletal animation can be simply kept in the vertex shader.</p>
<p>Another thing is that Shader Model 5.0 hardware relaxes the limitation about the concurrent usage of tessellation and geometry shaders so one can use both to implement their algorithms that rely on geometry shader usage freely.</p>
<p>Still, the implementation of a tessellation evaluator shader does not really differ from that used in case of Shader Model 4.0 tessellation as we use the barycentric coordinates generated by the tessellator in the same style, just we don&#8217;t need explicit vertex fetches but the primitive data is baked for us straight from the beginning.</p>
<p>Crack-free rendering is still an issue however, especially in case of the programmable evaluators available in the last two versions. OpenGL 4.0 addresses this issue by introducing a precise qualified that restricts the shader compiler to use any optimizations like operation reordering or fused multiply-add that may introduce floating point round errors thus at least guaranteeing that the same sequence of operations will result in the same number. Any further steps against cracks introduced by tessellation are the responsibility of the programmer.</p>
<h2>Conclusion</h2>
<p>We&#8217;ve seen how various GPU generations addressed the issue of hardware tessellation as well as in what form they are available in various OpenGL implementations. I&#8217;ve also tried to collect the most relevant advantages and disadvantages of the implementations in various hardware generations.</p>
<p>There was also a completely separate discussion about geometry shaders and their use for geometry amplification and I hope I managed to convince everybody that it is not the way to go.</p>
<p>We&#8217;ve also briefly mentioned some of the major issues that may arise concerns regarding to the use of tessellation, however the thorough examination of these issues needs a much longer discussion that is out of the scope of this article, still, an interesting topic for a future one.</p>
<p>Unfortunately, I didn&#8217;t prepare any sample application demonstrating the usage of the various tessellation implementations due to the lack of time so this has to be also postponed to a future article.</p>
<p>For further reading and especially for sample applications I recommend you to check out the following links:</p>
<p><a title="Hardware Tessellation on Radeon in OpenGL @ Geeks3D" href="http://www.geeks3d.com/20100209/test-hardware-tessellation-on-radeon-in-opengl-part-12/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.geeks3d.com/20100209/test-hardware-tessellation-on-radeon-in-opengl-part-12/?referer=');">Hardware Tessellation on Radeon in OpenGL @ Geeks3D</a><br />
<a title="First Contact with OpenGL 4.0 GPU Tessellation @ Geeks3D" href="http://www.geeks3d.com/20100730/test-first-contact-with-opengl-4-0-gpu-tessellation/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.geeks3d.com/20100730/test-first-contact-with-opengl-4-0-gpu-tessellation/?referer=');"> First Contact with OpenGL 4.0 GPU Tessellation @ Geeks3D</a></p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/09/history-of-hardware-tessellation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A brief preview of the new features introduced by OpenGL 3.3 and 4.0</title>
		<link>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/</link>
		<comments>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 16:23:17 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[tessellation]]></category>
		<category><![CDATA[tessellation control shader]]></category>
		<category><![CDATA[tessellation evaluation shader]]></category>
		<category><![CDATA[texture array]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex shader]]></category>
		<category><![CDATA[vertex stream]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=207</guid>
		<description><![CDATA[The Khronos Group continues the progress of streamlining the OpenGL API. One very important step in this battle has been made just a few days ago by releasing two concurrent core releases of the OpenGL specification, namely version 3.3 and 4.0. This is a major update of the standard containing many revolutionary additions to the]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F03%252Fa-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FceIGqq%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20brief%20preview%20of%20the%20new%20features%20introduced%20by%20OpenGL%203.3%20and%204.0%22%20%7D);"></div>
<p>The Khronos Group continues the progress of streamlining the OpenGL API. One very important step in this battle has been made just a few days ago by releasing two concurrent core releases of the OpenGL specification, namely version 3.3 and 4.0. This is a major update of the standard containing many revolutionary additions to the tool-set of OpenGL that need careful examination. In this article I would like to talk about these new features trying to point out their importance and touching also some practical use case scenarios.</p>
<p><span id="more-207"></span>This is the fourth revision of the OpenGL API standard in the last two years. This fast pace revolution started about one and half years ago with the release of the version 3.0 of the specification. At that time, a great feel of disappointment has overcame the developers due to the lack of the promised rewrite of the whole API. Others, who had to deal with legacy code were also disappointed but they felt so because the new revision of the API threatened them with removing old features. These two opposing forces have put the Khronos Group into a situation where there was very difficult to make a decision that would make everybody happy. After two releases, this issue has been mostly resolved with OpenGL 3.2 and also lots of missing features have been integrated into the core API meanwhile.</p>
<p>Even though great steps has been made in order to fulfill everybody&#8217;s needs, the gap between the core functionality of OpenGL and the DirectX API still increased, especially due to the introduction of Shader Model 5.0 hardware. OpenGL was in a position when it had to adopt the features of the new hardware generation and also try to make up leeway in case of Shader Model 4.0 hardware. My personal wish was that there should be two new versions of the API: one that complements the OpenGL 3.x API with the missing features and another that catches up to DirectX 11. Actually my wish became true as the first time in the history of OpenGL we got two new releases of the standard at once, and finally, we got an API that is a really competitive alternative for Microsoft&#8217;s DirectX API. I think I can say this in the name of every OpenGL developer: Thank you Khronos!</p>
<p>Okay, but that&#8217;s enough about history and acknowledgements. Lets see what&#8217;s under the hood of the new API revisions! When I read the good news at <a title="OpenGL.org" href="http://www.opengl.org/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/?referer=');">OpenGL.org</a> I felt myself like a child at Christmas just taking the first look at the presents under the tree: I was in great ecstasy and started to &#8220;open the presents&#8221; as fast as I could&#8230;</p>
<h2>New features of OpenGL 3.3</h2>
<p>Let&#8217;s start with the new version of the API targeting Shader Model 4.x hardware. It seems that the concentration on the major release 4.0 didn&#8217;t capture the attention of the ARB explicitly as we have many interesting features already in the first box&#8230;</p>
<h3><a title="ARB_blend_func_extended" href="http://www.opengl.org/registry/specs/ARB/blend_func_extended.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/blend_func_extended.txt?referer=');">ARB_blend_func_extended</a></h3>
<p>This is a feature for what I&#8217;ve seen many requests on the OpenGL discussion forums. It enables fragment shaders to output an additional color per render target that can be used as a blending factor for either source or destination colors providing an additional degree of freedom to affect the way how fragments are blended into the destination buffers. This is one functionality that is supported by the underlying hardware for a while but without API support it was impossible to take advantage of it. As it is very straightforward how this feature works I would not even talk about it too much. Just one additional comment: surprisingly <a title="ATI Catalyst 10.2: Better CrossFire and OpenGL Support" href="http://www.geeks3d.com/20100218/test-ati-catalyst-10-2-better-crossfire-and-opengl-support/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.geeks3d.com/20100218/test-ati-catalyst-10-2-better-crossfire-and-opengl-support/?referer=');">AMD already supports this extension</a> in its latest graphics drivers which is a remarkable thing taking in consideration that AMD drivers were always a step behind the NVIDIA ones in the race of adopting latest OpenGL features. It seems that now AMD takes seriously the OpenGL support and this is good news for all the developers out there, especially for me, being an ATI fan.</p>
<h3><a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a></h3>
<p>Most probably not just for me, the way how the binding of vertex attributes to shader attributes and the binding of shader outputs to render targets happened earlier caused a big headache from both the point of view of modular software design and efficiency. Previously, the application developer had little to no control over how to automatically connect these elements together in a shader independent way. This tight coupling between the host application code and the shaders just make the work of the developers cumbersome. This feature leverages the way how this binding process is done by allowing to globally assign a particular semantic meaning to an attribute location without knowing how that attribute will be named in any particular shader, decoupling the host application from the shaders. This extension is a typical example how design abstractions can ease the life of the developer without any dependency on hardware support.</p>
<h3><a title="ARB_occlusion_query2" href="http://www.opengl.org/registry/specs/ARB/occlusion_query2.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/occlusion_query2.txt?referer=');">ARB_occlusion_query2</a></h3>
<p>Well, there isn&#8217;t too much to say about this extension as it just adds a new occlusion query type that reports just a boolean value about the visibility of the object rather than the actual samples. It is somewhat equivalent to the occlusion query extensions prior to <a title="ARB_occlusion_query" href="http://www.opengl.org/registry/specs/ARB/occlusion_query.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/occlusion_query.txt?referer=');">ARB_occlusion_query</a>. Don&#8217;t ask me why this feature is important but they felt that it might be useful. One thing I can think about that with such a query we might get our results about the occlusion query of the proxy object sooner as we have to wait only till the first passed sample but I&#8217;m not confident whether such thing is supported by either the hardware or the drivers.</p>
<h3><a title="ARB_sampler_objects" href="http://www.opengl.org/registry/specs/ARB/sampler_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/sampler_objects.txt?referer=');">ARB_sampler_objects</a></h3>
<p>This is one another feature that people have been waiting for years. This extension decouples texture image data from sampler state. Previously, if a texture image had to be used with different sampler modes, no matter if we talk about various filtering modes or texture coordinate wrapping, one had to do expensive state changes to modify the sampler state of the texture object, accomplish the needed filtering or wrapping from within shaders or, in worst case, duplicating texture image data in order to have access to the same texture with different sampler parameters. The primary intend of this feature is to solve these problems.</p>
<p>One thing to remark regarding to this extension is that even though it is a long waited addition to the API, several people already expressed their discontent regarding to the fact that the texture unit semantics have been kept. Nevertheless, I also expected that the introduction of this feature should be the point when the texture unit semantics has to go but after seeing the example of <a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a> as a way to decouple the shader code from the host application code I tend to agree with Khronos in this decision as we can think about the texture units from now as an adapter layer between GPU and CPU code and as such the decision seems reasonable.</p>
<h3><a title="ARB_shader_bit_encoding" href="http://www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt?referer=');">ARB_shader_bit_encoding</a></h3>
<p>This extension adds built-in functions for getting and setting the bit encoding for floating-point values in the OpenGL Shading Language. As it is more like an indicator extension regarding to added functionality in the Shading Language I would rather not go into details as I will talk about the new Shading Language later.</p>
<h3><a title="ARB_texture_rgb10_a2ui" href="http://www.opengl.org/registry/specs/ARB/texture_rgb10_a2ui.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_rgb10_a2ui.txt?referer=');">ARB_texture_rgb10_a2ui</a></h3>
<p>Again, an extension that is quite self-explanatory: new texture image format called RGB10_A2 with non-normalized unsigned integers in them. This is nothing more than another hole filled in the gap between hardware and API support.</p>
<h3><a title="ARB_texture_swizzle" href="http://www.opengl.org/registry/specs/ARB/texture_swizzle.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_swizzle.txt?referer=');">ARB_texture_swizzle</a></h3>
<p>Especially when using one or two component texture formats, like in the case of shadow maps, the specification was somewhat unclear how these components are finally mapped to RGBA quadruples and provided little to no facilities to control this process. If the developers weren&#8217;t already fed up with this, the possibility of a problem increased even further because often the driver implementations behaved differently as well. This issue has been finally clarified with this extension by providing an explicit tool for the application developer to control the swizzling of the components that is done implicitly afterwards in case of every single texture fetch. The new state is introduced as part of texture object state that provides fine grained control over when and how to use the swizzling. According to the extension specification, this feature has a notable role in helping porting issues of legacy OpenGL applications as well as those of the games written for PlayStation 3 as the console provides such functionality already.</p>
<h3><a title="ARB_timer_query" href="http://www.opengl.org/registry/specs/ARB/timer_query.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/timer_query.txt?referer=');">ARB_timer_query</a></h3>
<p>Prior to this extension, runtime performance measurements were limited to the use of client side timing information or relying on the use of offline profiling mechanisms like that of AMD&#8217;s <a title="GPU PerfStudio" href="http://developer.amd.com/gpu/perfstudio/Pages/default.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.amd.com/gpu/perfstudio/Pages/default.aspx?referer=');">GPUPerfStudio</a>. During development, this timing information can help identify application, driver or GPU bottlenecks. At runtime, this data can be used to dynamically optimize the scene to achieve reasonable frame rates. While today&#8217;s hardware provides a great repertoire of performance measurement metrics there was no API support to access these previously. This feature provides an additional asynchronous query type that enables application developers to measure the driver and GPU time that is required to complete a set of rendering commands, thus providing additional flexibility for both offline and runtime optimizations. While this extension does not guarantee 100% consistency and repeatability, the information gathered with timer queries will definitely make it possible to identify server side bottlenecks and the reasons behind them.</p>
<h3><a title="ARB_instanced_arrays" href="http://www.opengl.org/registry/specs/ARB/instanced_arrays.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/instanced_arrays.txt?referer=');">ARB_instanced_arrays</a></h3>
<p>Many people argued with me at the OpenGL discussion forums when I stated that instanced arrays should be included in core OpenGL. Their reasoning was built on the fact that we already have the <a title="ARB_draw_instanced" href="http://www.opengl.org/registry/specs/ARB/draw_instanced.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_instanced.txt?referer=');">ARB_draw_instanced</a> extension that provides a shader based thus much more flexible way to handle instanced geometry. While from this point of view I tend to agree with them, there are many non-trivial use cases which prove that my reasoning is not pointless. It seems that Khronos agrees with me regarding to this topic.</p>
<p>In a nutshell, the instanced arrays feature enables the use of vertex attributes as a source of instance data. This is done by introducing a so called &#8220;array divisor&#8221; that specifies how the corresponding vertex attributes are mapped to instances. Usually a vertex attribute advances on a per-vertex basis. In case of instanced arrays this advance happens only after ever<span style="font-size: small;">y Nth conceptual draw calls that is equivalent to  a traditional draw command, excluding instanced draw commands.</span></p>
<p>One use case can be when one deals with huge number of instances where the per-instance data simply not fits into uniform buffers. While in such cases one can use a texture buffer instead to source the instance data like it was mentioned in my article <a title="Uniform Buffers VS Texture Buffers - RasterGrid Blog" href="http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/">Uniform Buffers VS Texture Buffers</a>, accepting the additional overhead of using texture fetches may prove to be a not-so-performance-wise decision. Beside standard instancing use cases, there are plenty of nasty tricks that can be efficiently achieved using this feature but that goes far beyond the scope of this article and requires a separate discussion on what I will most probably recap in the near future.</p>
<h3><a title="ARB_vertex_type_2_10_10_10_rev" href="http://www.opengl.org/registry/specs/ARB/vertex_type_2_10_10_10_rev.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/vertex_type_2_10_10_10_rev.txt?referer=');">ARB_vertex_type_2_10_10_10_rev</a></h3>
<p>We&#8217;ve arrived to the final new extension included in core OpenGL 3.3. This is another gap filling extension to provide two new vertex attribute data formats: a signed and an unsigned format with 10 bits for each significant coordinate. The most typical use of this format is to store vertex normals in the signed-normalized version of the format in order to have a compact (4 bytes per normal) yet high precision (due to 10 bits per component) format that can reduce memory needs and bandwidth requirements while retaining sufficient precision. Previously, there was no way to have such high precision for the vertex attributes in case of a 4-byte footprint.</p>
<h3>The OpenGL Shading Language 3.30</h3>
<p>The first remarkable thing is the shift in the versioning of the Shading Language. It seems that from now it will be in align with the core specification version. This decision was most probably made because of the introduction of two release branches of the standard specification in order to avoid confusion regarding to the correspondence between API and Shading Language versioning.</p>
<p>As in case of talking about the OpenGL Shading Language it is much more difficult to easily summarize the new features with corresponding use cases I will simply limit my comments to an excerpt from its specification regarding to the features added in this new version:</p>
<ul>
<li>Layout qualifiers can be used to declare the location of vertex shader inputs and fragment shader outputs in align with the API functionality provided by <a title="ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">ARB_explicit_attrib_location</a> as mentioned before.</li>
<li>Built-in functions provided to converting floating-point values to integer ones representing their encoding.</li>
<li>Some clarification of already existing facilities of the language.</li>
</ul>
<h2>New features of OpenGL 4.0</h2>
<p>It is very obvious that the major version number change indicates that this revision of the specification is targeting Shader Model 5.0 hardware. To be honest, as I was never really interested in DirectX, I barely know all the features introduced by DX11 but seems that there are some great facilities in OpenGL 4.0 that I&#8217;ve never heard that hardware supports it. This can be due to DX11 does not even support such functionalities but it is maybe because I don&#8217;t know enough details about DX11. Anyway, let&#8217;s see the revolutionary things that we face we checking out the latest version of the OpenGL specification&#8230;</p>
<h3><a title="ARB_draw_buffers_blend" href="http://www.opengl.org/registry/specs/ARB/draw_buffers_blend.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_buffers_blend.txt?referer=');">ARB_draw_buffers_blend</a></h3>
<p>Using this feature one is able to select individual blend equations and blend functions for each render target. This extension was already exposed for a few months now so most probably everybody heard about it or even if not the functionality is very straightforward. It simply removes some of the restrictions when dealing with multiple render targets (MRT). One interesting thing is still that the Khronos Group decided to include this extension in the 4.0 version of the API but not in 3.3. This is odd as Shader Model 4.0 capable hardware already supports this feature or at least I have the extension on my Radeon HD2600 which raises the question: why only in 4.0? Unfortunately, I don&#8217;t know the answer but I hope the ARB has a good reason behind this, as we will see later, there are other features that for some reason were only exposed in the latest version of the API but not in core for Shader Model 4.0 hardware.</p>
<h3><a title="ARB_sample_shading" href="http://www.opengl.org/registry/specs/ARB/sample_shading.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/sample_shading.txt?referer=');">ARB_sample_shading</a></h3>
<p>In case of traditional multisample rendering the hardware optimizes the multisampling in a way that the fragment shader is executed only once for each fragment. This can be done as the standard specification relaxes the way how the implementation behaves regarding to feeding color and texture coordinate values for each sample. While this optimization usually does not provide any rendering artifacts and it heavily reduces the amount of pressure on the GPU, there are some situations when this optimization results in aliasing artifacts. One sample use case is when alpha-tested primitives are rendered.</p>
<p>This extension provides a global state for enabling and disabling sample shading and a way to control how fine-grained per-sample shading should be by supplying a minimum number of samples that need to be shaded. Beside this, it also introduces the required language elements to the OpenGL Shading Language to support sample shading.</p>
<h3><a title="ARB_shader_subroutine" href="http://www.opengl.org/registry/specs/ARB/shader_subroutine.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_subroutine.txt?referer=');">ARB_shader_subroutine</a></h3>
<p>In my humble opinion, this is one of the most important features introduced in this new version of the API specification. So far, many engine and shader developers faced the problems that where inherently there in the Shading Language that heavily reduced the ability to create a modular shader design in order to separate the independent tasks done in shaders nowadays. One initiative was the idea behind the <a title="EXT_separate_shaders" href="http://www.opengl.org/registry/specs/EXT/separate_shader_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/separate_shader_objects.txt?referer=');">EXT_separate_shader_objects</a> extension. While that extension removed the dependency between shader stages, it does not address the problem with tight coupling inside one shader stage, also the aforementioned extension defeats some of the design goals of the Shading Language introducing complicated language semantics in order to solve the problem of inter-stage dependency.</p>
<p>Just to emphasize the importance of this new functionality with a very basic example, let&#8217;s take a simple rendering engine that supports skeletal animated geometry, materials and lights. In such a use case both the vertex and fragment shaders have multiple roles: the vertex shader has to perform the skeletal animation (property of the geometry) and the view transformation (property of the camera or of the light in case of shadow map rendering), and the fragment shader has to calculate the incident light to the surface point (property of the light) and then calculate the illuminance factor (property of the material). With the traditional tool-set these components of the shaders were tightly coupled and in order to support the combination of any geometry type (animated or not, skeletal or morph animation, etc.), any light type (directional, point, etc.) and material type (diffuse, phong, environment mapped, etc.), one had to compile all possible combinations of the shaders or create uber-shaders that do run-time decisions in order to solve the problem of heterogeneous inputs. Both of these solutions provide additional hardware resource usage and possible runtime overhead.</p>
<p>This extension adds some kind of polymorphism support to shaders. This way a single shader can include many alternative subroutines for a particular task and dynamically select through the API which subroutine is called from each call site. This opens the doors for modular shader designs while retaining most of the performance of specialized shaders.</p>
<h3><a title="ARB_tessellation_shader" href="http://www.opengl.org/registry/specs/ARB/tessellation_shader.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/tessellation_shader.txt?referer=');">ARB_tessellation_shader</a></h3>
<p>Yes, this is about the new geometry tessellation mechanism introduced by Shader Model 5.0 hardware. The extension itself introduces three new stages that are roughly situated between the vertex shader and the geometry shader:</p>
<ul>
<li><strong>Tessellation Control Shader</strong> &#8211; This new shader type operates on a patch that is actually nothing more than a fixed-size collection of vertices, each with per-vertex attributes and a number of associated per-patch attributes. Also note that while it operates on a patch, it is invoked on a per-vertex basis. The most important rule of this shader is to perturb the tessellation level for the patch that controls how finely the patch will be tesselated. Usually think about a patch as a triangle or quad. This shader is equivalent to DX11&#8242;s hull shader.</li>
<li><strong>Fixed-function tessellation primitive generator</strong> &#8211; The role of this new stage is to subdivide the incoming patch based on the tessellation level and related configuration that the unit gets as input.</li>
<li><strong>Tessellation Evaluation Shader</strong> &#8211; This new shader type is responsible of calculating the position and other attributes of the vertices produced by the tesselator. This shader is equivalent to DX11&#8242;s domain shader.</li>
</ul>
<p>One important thing to notice is that a new primitive type is introduced, namely a patch. A patch on its own it is not directly or indirectly related to any traditional OpenGL primitive as it cannot be directly rendered. It is used only as the input type for the tesselator, however, a patch supplies the control grid of the geometry to be generated via tessellation so in practice it is most likely to be equivalent with triangles or quads but it is important to remark the difference.</p>
<p>As this is maybe the most well known feature of Shader Model 5.0 hardware I wouldn&#8217;t like to talk about it more as everybody knows what is it for and it would be rather long to explain how to use it. Also, it is not the intension of this article to fully cover the usage of all the new features, it is just a quick summarization of the new possibilities.</p>
<h3><a title="ARB_texture_buffer_object_rgb32" href="http://www.opengl.org/registry/specs/ARB/texture_buffer_object_rgb32.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_buffer_object_rgb32.txt?referer=');">ARB_texture_buffer_object_rgb32</a></h3>
<p>Yet another extension that introduces an additional format, now for texture buffers. Previously, texture buffers supported only four-component formats, this is extended with three-component formats. As currently there is no any practical use case in my mind when this can be useful, I would rather not come up with one. However, my opinion is that these formats most probably work with reduced performance compared to the four-component ones even though the memory footprint and bandwidth usage is maybe somewhat lower, I have concerns regarding to alignment related performance issues.</p>
<h3><a title="ARB_texture_cube_map_array" href="http://www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt?referer=');">ARB_texture_cube_map_array</a></h3>
<p>Those who already use texture arrays to help batching issues and remove unnecessary state changes most probably adore this extension as it enables texture array capabilities also for cube map textures. This comes handy especially in case when many materials use environment cube maps or when shadow cube maps are used for point lights. To come up with even a more concrete example, you can render the shadow cube maps for many hundreds of point lights with a single draw call by taking advantage of the layered rendering capability of geometry shaders and the possibility to bind texture arrays as render targets.</p>
<p>One more thing to notice here is that cube map arrays are already supported by Shader Model 4.1 hardware so the question to the ARB is again there, however, as OpenGL 3.3 still targets Shader Model 4.0 hardware maybe we will see a 3.x version of the specification that will also include this extension. The judgement is up to you whether you agree with me or not.</p>
<h3><a title="ARB_texture_gather" href="http://www.opengl.org/registry/specs/ARB/texture_gather.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_gather.txt?referer=');">ARB_texture_gather</a></h3>
<p>Another feature from the repertoire of Shader Model 4.1. This extension introduces new texture fetching functions to the Shading Language that determine a 2&#215;2 footprint of the texture that would be used for linear filtering in a texture lookup and returns a vector consisting of the first component from each of the four texels in the footprint. This is the so called Gather4 texture fetching mode and can be useful to accelerate percentage closer filtering of shadow maps as it can fetch four samples at once. Still, there are some limitations on the use of this fetching mode, one important thing is that a shader cannot use normal and gather fetches on the same sampler. This makes me think about whether this feature is not part of the sampler object state instead of being a Shading Language construct. Anyway, as in typical use cases these limitations does not defeat the goal of the feature, I would not consider this problem a design issue.</p>
<h3><a title="ARB_transform_feedback2" href="http://www.opengl.org/registry/specs/ARB/transform_feedback2.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback2.txt?referer=');">ARB_transform_feedback2</a></h3>
<p>The transform feedback mechanism already proved to me that is a great addition to the tool-set of graphics application developers. This feature extends transform feedback with an object type that encapsulates transform feedback related state to enable configuration reuse. Also it provides a way to pause and resume transform feedback mode if, for some reason, some rendering commands should be excluded from the feedback process.</p>
<p>The last and maybe most important benefit of this extension is the ability to draw primitives captured in transform feedback mode without querying the captured primitive count. It is roughly equivalent to DX10&#8242;s AutoDraw feature and the purpose of it is to eliminate the need to query the number of previously generated primitives in order to supply it to an OpenGL draw command. This solves the synchronization issues that previously happened between the CPU and the GPU.</p>
<p>One example is when a skeletal animated geometry has to be used in a multipass rendering technique. We can think about traditional forward rendering or when dealing with multiple shadow maps that have to be generated. Anyway, as the calculations needed to perform skeletal animation are rather expensive, it is wastage to perform these calculations in each pass.  A common way to solve this problem is to use transform feedback to capture the geometry emitted by a vertex shader that simply executes the skeletal animation on the input geometry. In subsequent rendering passes this feedback buffer can be used to source the geometry data to eliminate the need to recompute the animation. Without this extension, in such cases the application is most probably stalled until the feedback process ends as it needs to query the number of generated primitives. With this extension, this is solved as we don&#8217;t have to know the results of the previous transform feedback in order to issue a draw command that sources the data from the feedback buffer. By the way, this seems to be logical as the information is already on the GPU so why it should ping-pong between the CPU and the GPU?</p>
<p>As I mentioned before, the functionality provided by this extension is equivalent to DX10&#8242;s AutoDraw feature. This time my question is really serious: why this feature haven&#8217;t been included in OpenGL 3.3? It would provide a great benefit for those who use transform feedback and I don&#8217;t see any reason behind not supporting it because, as far as I can tell, it is supported on the corresponding hardware.</p>
<h3><a title="ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">ARB_transform_feedback3</a></h3>
<p>Surprisingly, OpenGL 4.0 comes with another transform feedback extension as well but this time a true Shader Model 5.0 feature. The new hardware generation has the ability to emit vertices from the geometry shader to multiple vertex streams. In order to provide clever API support, the ARB decided to relax the previous limitation of transform feedback mode that output can be in either interleaved format or to separate buffers. This new extension enables the use of both together also providing a way to group geometry shader outputs to groups in order to target the individual vertex streams.</p>
<p>The most important benefit of this feature is still that we have separate streams, each with its own primitive emission counter so the outputs should not necessarily have the same granularity. This provide room for very clever rendering techniques. As an example, remember NVIDIA&#8217;s <a title="NVIDIA Skinned Instancing demo" href="http://developer.download.nvidia.com/SDK/10/direct3d/samples.html" target="_blank" onclick="pageTracker._trackPageview('/outgoing/developer.download.nvidia.com/SDK/10/direct3d/samples.html?referer=');">Skinned Instancing</a> demo that used one draw call per geometry LOD to sort instance data on a per-LOD basis. Using this extension, this preprocessing step can be done with a single draw call, but the abilities of this feature goes far beyond such a simple use case, I will also talk a bit about another in the next section.</p>
<p>One of my less technical notes is that it seems that the Khronos Group members have good sense of humor. I realized this when I met the &#8220;manbearbig&#8221; when reading one of the examples in the extension specification.</p>
<h3><a title="ARB_draw_indirect" href="http://www.opengl.org/registry/specs/ARB/draw_indirect.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/draw_indirect.txt?referer=');">ARB_draw_indirect</a></h3>
<p>We&#8217;ve arrived to the most culminating point in the list of features introduced. It is hard to say such a thing, but in my humble opinion this extension can be the Holy Grail of next generation rendering engines. I will explain why I think so&#8230;</p>
<p>The extension provides a way to source the parameters of instanced draw commands from within buffer objects. One naive use case would be to put all the rendering command parameters to a buffer object using the host application and then draw everything with a single command. While this simple method already has its benefits, this feature provides much more flexibility than this. The most revolutionary is that, using this extension, one is able to generate instanced draw commands with the GPU on-the-fly. Together with <a title="ARB_transform_feedback3" href="http://www.opengl.org/registry/specs/ARB/transform_feedback3.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/transform_feedback3.txt?referer=');">ARB_transform_feedback3</a> it is possible to write a completely GPU based scene management system.</p>
<p>Those who remember my <em>Instance Cloud Reduction</em> (ICR) algorithm, presented in the article <a title="Instance culling using geometry shaders - RasterGrid Blog" href="http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/">Instance culling using geometry shaders</a>, know that the required synchronization points between the CPU and the GPU heavily limited the practical utility of the culling technique. By taking advantage of the aforementioned features in case of ICR does not just eliminate the synchronization issues that I&#8217;ve spoken of but makes the technique practical also in case of heavily heterogeneous scenes with virtually any number of geometries even if there are multiple number of LOD level for them, and this whole stuff can be done with even less number of draw calls than that of the demo that accompanied my article. As soon as we will see OpenGL 4.0 capable drivers I will write an article about this technique, supplying also a reference implementation.</p>
<h3><a title="ARB_texture_query_lod" href="http://www.opengl.org/registry/specs/ARB/texture_query_lod.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/texture_query_lod.txt?referer=');">ARB_texture_query_lod</a></h3>
<p>This extension provides new fragment shader texture functions, namely textureLOD*, that return the results of automatic LOD computations that would be performed if a texture lookup would be performed. These functions return a two-component vector. The X component of the result vector contains information about the mipmap level that would be used if a normal texture lookup would have been made with the same coordinates. This value can be a concrete mipmap level or a value between two levels if trilinear filtering is in use. The Y component of the result holds the computed LOD lambda-prime, see the OpenGL specification in order to check out where it is actually coming from and how it is calculated.</p>
<p>One interesting thing that this extension can be used for is when one implements some shader based filtering and addressing method for textures. As an example, lets take a mega-texture implemented that uses a 3D texture for storage, without actual mipmaps, and the addressing, filtering and mipmapping is done with shader code. As right now this is the only example that came into my mind and this is already awkward enough, I would rather leave the further discussion of the importance of this feature to more competent people.</p>
<h3><a title="ARB_gpu_shader5" href="http://www.opengl.org/registry/specs/ARB/gpu_shader5.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/gpu_shader5.txt?referer=');">ARB_gpu_shader5</a></h3>
<p>Basically, this extension is nothing more than a big umbrella feature under what all the additional general or minor API changes go. Just to sum up the miscellaneous features provided by this extension, here is an excerpt from the extension specification:</p>
<ul>
<li>Support for indexing into arrays of samplers using non-constant indices.</li>
<li>Support for indexing into an array of uniform blocks.</li>
<li>Extending Gather4 with the ability to select any single component of a multi-component texture, to perform per-sample depth comparison, and to specify arbitrary offsets computed at runtime when gathering the 2&#215;2 footprint.</li>
<li>Support for instanced geometry shaders, where a geometry shader may be run multiple times for each primitive.</li>
</ul>
<p>For a full list of new facilities introduced by the extension refer to the extension specification.</p>
<h3><a title="ARB_gpu_shader_fp64" href="http://www.opengl.org/registry/specs/ARB/gpu_shader_fp64.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/gpu_shader_fp64.txt?referer=');">ARB_gpu_shader_fp64</a></h3>
<p>This extension enables the use of double-precision floating-point data types and arithmetic from within shaders, also providing API entry points for double-precision data where it was missing. While one may think that the added precision is somewhat wastage in case of real-time graphics, it is important to note that GPUs are more and more often used for scientific calculations, not even necessarily in case of graphics related tasks. Taking in consideration this fact, the importance of double-precision floating-point support should not be underestimated. Beside that, maybe standard graphics application developers can also take advantage of the higher precision in some extreme use case scenarios.</p>
<h3>The OpenGL Shading Language 4.00</h3>
<p>Beside what I&#8217;ve already mentioned, there is no important thing to mention regarding to the Shading Language. There where many changes but most of them are simply provide Shading Language support to the API extensions. What I haven&#8217;t mentioned so far is the synchronization possibility for tessellation shaders, more implicit conversions, more integer functions, packing and unpacking facilities for floating-point formats and a new qualifier to force precision and disallow optimizations that re-order operations or treat different instances of the same operator with different precision.</p>
<h2>Conclusion</h2>
<p>I hope that some of you didn&#8217;t give up the reading so far. Sorry, but it seems that this article gone wild and still didn&#8217;t manage to cover all the topics I intended to talk about. But still, maybe I&#8217;ll recap on those subjects later.</p>
<blockquote><p>Where is direct state access?</p></blockquote>
<p>The original promise of eliminating the bind-to-modify semantics from the OpenGL API is still not done. The first reaction of many people is still to ask this question. While the bind-to-modify semantics is a rather annoying &#8220;feature&#8221; of OpenGL, I tend to state that if we are not talking about legacy OpenGL, the importance of direct state access is less and less relevant as we can already heavily reduce the number of state changes and API calls in our applications, thanks to the fast pace evolution of OpenGL. I sincerely think that with a modern rendering engine design built upon the idioms behind the new versions of the OpenGL API one should not face any significant scalability issues due to the outdated bind-to-modify semantics but maybe I&#8217;m wrong.</p>
<p>Personally, I have only one problem with the newly released specification versions that I&#8217;ve already tried to emphasize several times: the fact that so far many Shader Model 4.x features are missing from the 3.x line of the API specification. Hopefully that will be solved sooner or later, however addressing these issues should happen before the hardware to support will become outdated.</p>
<p>Anyway, we should not have any harsh complains as the Khronos Group did a great job again. They managed to keep again the half-year schedule and they even published two parallel releases at once! If someone still says that the DirectX API is superior compared to OpenGL should think it twice, as it seems that the tendency is that OpenGL just starts to evolve more and more fast. Beside that as now also AMD is being active in the OpenGL world, we can expect good support from both industry and developer community point of view.</p>
<p>My respect for the Khronos Group and thanks for reading the article!</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

