<?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; Samples</title>
	<atom:link href="http://rastergrid.com/blog/category/programming/samples/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>Tue, 07 Sep 2010 20:49:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Efficient Gaussian blur with linear sampling</title>
		<link>http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/</link>
		<comments>http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 20:48:16 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[bloom]]></category>
		<category><![CDATA[blur]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[depth-of-field]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[GLEW]]></category>
		<category><![CDATA[GLM]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[postprocessing]]></category>
		<category><![CDATA[SFML]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=299</guid>
		<description><![CDATA[

Gaussian blur is an image space effect that is used to create a softly blurred version of the original image. This image then can be used by more sophisticated algorithms to produce effects like bloom, depth-of-field, heat haze or fuzzy glass. In this article I will present how to take advantage of the various properties [...]]]></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%252Fefficient-gaussian-blur-with-linear-sampling%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FcLq0EW%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Efficient%20Gaussian%20blur%20with%20linear%20sampling%22%20%7D);"></div>
<div class="wp-caption alignleft" style="width: 160px"><br />
<img class=" " title="Gaussian blur" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_thumbnail.png" alt="Gaussian blur" width="150" height="150" /><p class="wp-caption-text">Gaussian blur</p></div>
<p>Gaussian blur is an image space effect that is used to create a softly blurred version of the original image. This image then can be used by more sophisticated algorithms to produce effects like bloom, depth-of-field, heat haze or fuzzy glass. In this article I will present how to take advantage of the various properties of the Gaussian filter to create an efficient implementation as well as a technique that can greatly improve the performance of a naive Gaussian blur filter implementation by taking advantage of bilinear texture filtering to reduce the number of necessary texture lookups. While the article focuses on the Gaussian blur filter, most of the principles presented are valid for most convolution filters used in real-time graphics.</p>
<p><span id="more-299"></span></p>
<p>Gaussian blur is a widely used technique in the domain of computer graphics and many rendering techniques rely on it in order to produce convincing photorealistic effects, no matter if we talk about an offline renderer or a game engine. Since the advent of configurable fragment processing through texture combiners and then using fragment shaders the use of Gaussian blur or some other blur filter is almost a must for every rendering engine. While the basic convolution filter algorithm is a rather expensive one, there are a lot of neat techniques that can drastically reduce the computational cost of it, making it available for real-time rendering even on pretty outdated hardware. This article will be most like a tutorial article that tries to present most of the available optimization techniques. Some of them may be familiar to all of you but maybe the linear sampling will bring you some surprise, but let&#8217;s not go that far but start with the basics.</p>
<h2>Terminology</h2>
<p>In order to precede any possibility of confusion, I&#8217;ll start the article with the introduction of some terms and concepts that I will use in the post.</p>
<p><strong>Convolution filter</strong> &#8211; An algorithm that combines the color value of a group of pixels.</p>
<p><strong>NxN-tap filter &#8211; </strong>A filter that uses a square shaped footprint of pixels with the square&#8217;s side length being N pixels.</p>
<p><strong>N-tap filter</strong> &#8211; A filter that uses an N-pixel footprint. Note that an N-tap filter does *not* necessarily mean that the filter has to sample N texels as we will see that an N-tap filter can be implemented using less than N texel fetches.</p>
<p><strong>Filter kernel</strong> &#8211; A collection of relative coordinates and weights that are used to combine the pixel footprint of the filter.</p>
<p><strong>Discrete sampling</strong> &#8211; Texture sampling method when we fetch the data of exactly one texel (aka GL_NEAREST filtering).</p>
<p><strong>Linear sampling</strong> &#8211; Texture sampling method when we fetch a footprint of 2&#215;2 texels and we apply a bilinear filter to aquire the final color information (aka GL_LINEAR filtering).</p>
<h2>Gaussian filter</h2>
<p>The image space Gaussian filter is an NxN-tap convolution filter that weights the pixels inside of its footprint based on the Gaussian function:</p>
<p style="text-align: center;"><img class=" aligncenter" title="Gaussian function 2D" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_function_2D.png" alt="Gaussian function 2D" width="190" height="41" /></p>
<p>The pixels of the filter footprint are weighted using the values got from the Gaussian function thus providing a blur effect. The spacial representation of the Gaussian filter, sometimes referred to as the &#8220;bell surface&#8221;, demonstrates how much the individual pixels of the footprint contribute to the final pixel color.</p>
<div class="wp-caption aligncenter" style="width: 444px"><img title="Gaussian function graphical representation" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_graph.png" alt="Gaussian function graphical representation" width="434" height="351" /><p class="wp-caption-text">The graphical representation of the 2-dimensional Gaussian function</p></div>
<p>Based on this some of you may already say &#8220;aha, so we simply need to do NxN texture fetches and weight them together and voilà&#8221;. While this is true, it is not that efficient as it looks like. In case of a 1024&#215;1024 image, using a fragment shader that implements a 33&#215;33-tap Gaussian filter based on this approach would need an enormous number of 1024*1024*33*33 ≈ 1.14 billion texture fetches in order to apply the blur filter for the whole image.</p>
<p>In order to get to a more efficient algorithm we have to analyze a bit some of the nice properties of the Gaussian function:</p>
<ul>
<li>The 2-dimensional Gaussian function can be calculated by multiplying two 1-dimensional Gaussian function:</li>
</ul>
<p style="text-align: center;"><img class="aligncenter" title="Gaussian function 1D" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_function_1D.png" alt="Gaussian function 1D" width="190" height="41" /></p>
<ul>
<li>A Gaussian function with a distribution of 2σ is equivalent with the product of two Gaussian functions with a distribution of σ.</li>
</ul>
<p>Both of these properties of the Gaussian function give us room for heavy optimization.</p>
<p>Based on the first property, we can separate our 2-dimensional Gaussian function into two 1-dimensional one. In case of the fragment shader implementation this means that we can separate our Gaussian filter into a horizontal blur filter and the vertical blur filter, still getting the accurate results after the rendering. This results in two N-tap filters and an additional rendering pass needed for the second filter. Getting back to our example, applying the two filters to a 1024&#215;1024 image using two 33-tap Gaussian filters will get us to 1024*1024*33*2 ≈ 69 million texture fetches. That is already more than an order of magnitude less than the original approach made possible.</p>
<p>Using the second property of the Gaussian function, we can separate our 33&#215;33-tap filter into three 9&#215;9-tap filter (9+8=17, 17+16=33). Back to our example, for the 1024&#215;1024 sized image this results in 1024*1024*9*9*3 ≈ 255 million texture fetches. As we can see, we also spared a large amount of the necessary texture fetches using this approach as well.</p>
<p>Of course, the combination of the two techniques is also possible. That means we both separate our filter to a vertical and horizontal filter as well as decompose our 33-tap filter into three 9-tap filter. This will get us to the almost optimal number of 1024*1024*9*3*2 ≈ 56 million texture fetches.</p>
<h2>Gaussian kernel weights</h2>
<p>We&#8217;ve seen how to implement an efficient Gaussian blur filter for our application, at least in theory, but we haven&#8217;t talked about how we should calculate the weights for each pixel we combine using the filter in order to get the proper results. The most straightforward way to determine the kernel weights is by simply calculating the value of the Gaussian function for various distribution and coordinate values. While this is the most generic solution, there is a simpler way to get some weights by using the binomial coefficients. Why we can do that? Because the Gaussian function is actually the distribution function of the normal distribution and the normal distribution&#8217;s discrete equivalent is the binomial distribution which uses the binomial coefficients for weighting its samples.</p>
<div class="wp-caption aligncenter" style="width: 610px"><img class=" " title="Binomial coefficients" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/binomial_coeff.png" alt="Binomial coefficients" width="600" height="250" /><p class="wp-caption-text">The Pascal triangle showcasing the binomial coefficients that can be used to calculate the kernel weights (each element in the succeeding rows is the sum of its &quot;parents&quot;).</p></div>
<p>For implementing our 9-tap horizontal and vertical Gaussian filter we will use the last row of the Pascal triangle illustrated above in order to calculate our weights. One may ask why we don&#8217;t use the row with index 8 as it has 9 coefficients. This is a justifiable question, but it is rather easy to answer it. This is because with a typical 32 bit color buffer the outermost coefficients don&#8217;t have any effect on the final image while the second outermost ones have little to no effect. We would like to minimize the number of texture fetches but provide the highest quality blur as possible with our 9-tap filter. Obviously, in case very high precision results are a must and a higher precision color buffer is available, preferably a floating point one, using the row with index 8 is better. But let&#8217;s stick to our original idea and use the last row&#8230;</p>
<p>By having the necessary coefficients, it is very easy to calculate the weights that will be used to linearly interpolate our pixels. We just have to divide the coefficient by the sum of the coefficients that is 1024 in this case. Of course, for correcting the elimination of the four outermost coefficients, we can reduce the sum to 1002, however this does not have any visible effect either as our color buffer has a limited precision.</p>
<p>Now, as we have our weights it is very straightforward to implement our fragment shaders. Let&#8217;s see how the vertical file shader will look like in GLSL:</p>
<pre class="brush:cpp">uniform sampler2D image;

out vec4 FragmentColor;

uniform float offset[5] = float[]( 0.0, 1.0, 2.0, 3.0, 4.0 );
uniform float weight[5] = float[]( 0.2255859375, 0.193359375, 0.120849609375,
                                   0.0537109375, 0.01611328125 );

void main(void)
{
    FragmentColor = texture2D( image, vec2(gl_FragCoord)/1024.0 ) * weight[0];
    for (int i=1; i&lt;5; i++) {
        FragmentColor +=
            texture2D( image, ( vec2(gl_FragCoord)+vec2(0.0, offset[i]) )/1024.0 )
                * weight[i];
        FragmentColor +=
            texture2D( image, ( vec2(gl_FragCoord)-vec2(0.0, offset[i]) )/1024.0 )
                * weight[i];
    }
}</pre>
<p>Obviously the horizontal filter is no different just the offset value is applied to the X component rather than to the Y component of the fragment coordinate. Note that we hardcoded here the size of the image as we divide the resulting window space coordinate by 1024. In a real life scenario one may replace that with a uniform or simply use texture rectangles that don&#8217;t use normalized texture coordinates.</p>
<p>If you have to apply the filter several times in order to get a more strong blur effect, the only thing you have to do is ping-pong between two framebuffers and apply the shaders to the result of the previous step.</p>
<div class="wp-caption aligncenter" style="width: 610px"><a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian1.png" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian1.png?referer=');"><img class=" " title="Gaussian blur effect" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian1_thumbnail.png" alt="Gaussian blur effect" width="600" height="200" /></a><p class="wp-caption-text">9-tap Gaussian blur filter applied to an image of size 1024x1024: no filter applied (left), applied once (middle), applied nine times (right). Click to view the full-sized image in order to better see the difference.</p></div>
<h2>Linear sampling</h2>
<p>So far, we were able to see how to implement a separable Gaussian filter using two rendering pass in order to get a 9-tap Gaussian blur. We&#8217;ve also seen that we can run this filter three times over a 1024&#215;1024 sized image in order to get a 33-tap Gaussian blur by using only 56 million texture fetches. While this is already quite efficient it does not really expose any possibilities of the GPUs as this form of the algorithm would work perfectly almost unmodified on a CPU as well.</p>
<p>Now, we will see that we can take advantage of the fixed function hardware available on the GPU that can even further reduce the number of required texture fetches. In order to get to this optimization let&#8217;s discuss one of the assumptions that we made from the beginning of the article:</p>
<p>So far, we assumed that in order to get information about a single pixel we have to make a texture fetch, that means for 9 pixels we need 9 texture fetches. While this is true in case of a CPU implementation, it is not necessarily true in case of a GPU implementation. This is because in the GPU case we have bilinear texture filtering at our disposal that comes with practically no cost. That means if we don&#8217;t fetch at texel center positions our texture then we can get information about multiple pixels. As we already use the separability property of the Gaussian function we actually working in 1D so for us bilinear filter will provide information about two pixels. The amount of how much each texel contribute to the final color value is based on the coordinate that we use.</p>
<p>By properly adjusting the texture coordinate offsets we can get the accurate information of two texels or pixels using a single texture fetch. That means for implementing a 9-tap horizontal/vertical Gaussian filter we need only 5 texture fetches. In general, for an N-tap filter we need [N/2] texture fetches.</p>
<p>What this will mean for our weight values previously used for the discrete sampled Gaussian filter? It means that each case we use a single texture fetch to get information about two texels we have to weight the color value retrieved by the sum of the weights corresponding to the two texels. Now that we know what are our weights, we just have to calculate the texture coordinate offsets properly.</p>
<p>For texture coordinates, we can simply use the middle coordinate between the two texel centers. While this is a good approximation, we won&#8217;t accept it as we can calculate much better coordinates that will result us exactly the same values as when we used discrete sampling.</p>
<p>In case of such a merge of two texels we have to adjust the coordinates that the distance of the determined coordinate from the texel #1 center should be equal to the weight of texel #2 divided by the sum of the two weights. In the same style, the distance of the determined coordinate from the texel #2 center should be equal to the weight of texel #1 divided by the sum of the two weights.</p>
<p>As a result, we get the following formulas to determine the weights and offsets for our linear sampled Gaussian blur filter:</p>
<p style="text-align: center;"><img class="aligncenter" title="Weight and offset calculation for linear sampling" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/equation.png" alt="Weight and offset calculation for linear sampling" width="597" height="116" /></p>
<p>By using this information we just have to replace our uniform constants and decrease the number of iterations in our vertical filter shader and we get the following:</p>
<pre class="brush:cpp">uniform sampler2D image;

out vec4 FragmentColor;

uniform float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );
uniform float weight[3] = float[]( 0.2255859375, 0.314208984375, 0.06982421875 );

void main(void)
{
    FragmentColor = texture2D( image, vec2(gl_FragCoord)/1024.0 ) * weight[0];
    for (int i=1; i&lt;3; i++) {
        FragmentColor +=
            texture2D( image, ( vec2(gl_FragCoord)+vec2(0.0, offset[i]) )/1024.0 )
                * weight[i];
        FragmentColor +=
            texture2D( image, ( vec2(gl_FragCoord)-vec2(0.0, offset[i]) )/1024.0 )
                * weight[i];
    }
}</pre>
<p>This simplification of the algorithm is mathematically correct and if we don&#8217;t consider possible rounding errors resulting from the hardware implementation of the bilinear filter we should get the exact same result with our linear sampling shader like in case of the discrete sampling one.</p>
<div class="wp-caption aligncenter" style="width: 523px"><a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/side2side.png" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/09/side2side.png?referer=');"><img class=" " title="Side-to-side comparison of Gaussian blur with discrete and linear sampling" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/side2side_thumbnail.png" alt="Side-to-side comparison of Gaussian blur with discrete and linear sampling" width="513" height="250" /></a><p class="wp-caption-text">9-tap Gaussian blur applied nine times with discrete sampling (left) and linear sampling (right). Click for the full resolution of the image. Note that there is no visible difference between the two techniques even after several passes.</p></div>
<p>While the implementation of the linear sampling is pretty straightforward, it has a quite visible effect on the performance of the Gaussian blur filter. Taking into consideration that we managed to implement a 9-tap filter using just five texture fetches instead of nine, back to our example, blurring a 1024&#215;1024 image with a 33-tap filter takes only 1024*1024*5*3*2 ≈ 31 million texture fetches instead of the 56 million required by discrete sampling. This is a quite reasonable difference and in order to better present how much that matters I&#8217;ve done some experiment to measure the difference between the two techniques. The result speaks for itself:</p>
<div class="wp-caption aligncenter" style="width: 532px"><img title="Performance comparison of discrete and linear sampling" src="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/comparison2.png" alt="Performance comparison of discrete and linear sampling" width="522" height="400" /><p class="wp-caption-text">Performance comparison of the 9-tap Gaussian blur filter with discrete and linear sampling on a Radeon HD5770. The vertical axis is the frames per second (higher is better) and the horizontal axis represents results with various number of blur steps (higher is blurrier).</p></div>
<p>As we can see, the performance of the Gaussian filter implemented with linear sampling is about 60% faster than the one implemented with discrete sampling indifferent from the number of blur steps applied to the image. This roughly proportional to the number of texture fetches spared by using linear filtering.</p>
<h2>Conclusion</h2>
<p>We&#8217;ve seen that implementing an efficient Gaussian blur filter is quite straightforward and the result is a very fast real-time algorithm, especially using the linear sampling, that can be used as the basis of more advanced rendering techniques.</p>
<p>Even though we concentrated on Gaussian blur in this article, many of the discussed principles apply to most convolution filter types. Also, most of the theory applies in case we need a blurred image of reduced size like it is usually needed by the bloom effect, even the linear sampling. The only thing that is really different in case of a reduced size blurred image is that our center pixel is also a &#8220;double-pixel&#8221;. This means that we have to use a row from our Pascal triangle that has even number of coefficients as we would like to linear sample the middle texels as well.</p>
<p>We&#8217;ve also had a brief insight into the computational complexity of the various techniques and how the filter can be efficiently implemented on the GPU.</p>
<p>The demo application used for the measurements performed to compare the discrete and linear sampling method can be downloaded here:</p>
<h3>Binary release</h3>
<p><strong>Platform:</strong> Windows<br />
<strong>Dependency:</strong> OpenGL 3.3 capable graphics driver<br />
<strong>Download link:<span style="font-weight: normal;"> </span><a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_win32.zip" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_win32.zip?referer=');"><span style="font-weight: normal;">gaussian_win32.zip (2.96MB)</span></a></strong></p>
<p><a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_win32.zip"></a><strong>Source code</strong></p>
<p><strong>Language:</strong> C++<br />
<strong>Platform:</strong> cross-platform<br />
<strong>Dependency:</strong> GLEW, SFML, GLM<br />
<strong>Download link:</strong> <a href="http://www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_src.zip" onclick="pageTracker._trackPageview('/outgoing/www.rastergrid.com/blog/wp-content/uploads/2010/09/gaussian_src.zip?referer=');">gaussian_src.zip (5.41KB)</a><br />
<strong> </strong></p>
<p>P.S.: Sorry for the high minimum requirements of the application just I would really like to stick to strict OpenGL 3+ demos.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Going mobile with OpenGL ES</title>
		<link>http://rastergrid.com/blog/2010/04/going-mobile-with-opengl-es/</link>
		<comments>http://rastergrid.com/blog/2010/04/going-mobile-with-opengl-es/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 16:34:53 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[Telecommunication]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[mobile technology]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[OpenAL]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[phone]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=230</guid>
		<description><![CDATA[

Many things have changed since the first time the public put their hands on the first mobile phone device as these days the end user rarely makes their choices when buying a mobile equipment based on their telephony capabilities. In fact, nowadays these devices are one of the most popular entertainment platforms out there. 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%252F04%252Fgoing-mobile-with-opengl-es%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fa5rKKQ%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Going%20mobile%20with%20OpenGL%20ES%22%20%7D);"></div>
<p>Many things have changed since the first time the public put their hands on the first mobile phone device as these days the end user rarely makes their choices when buying a mobile equipment based on their telephony capabilities. In fact, nowadays these devices are one of the most popular entertainment platforms out there. The main problem for application developers is that these platforms tended to be very heterogeneous from point of view of hardware architecture as well as that of API support. Meanwhile things have changed. While the underlying hardware still varies a lot from device to device the work of application developers has been eased by having cross platform mobile operating systems and open standards. In particular OpenGL ES that is an embedded version of the popular graphics API. In this article I would like to talk about some of the big players of the mobile OS industry and about using OpenGL ES for creating impressive mobile applications.</p>
<p><span id="more-230"></span>The first version of the OpenGL ES specification has been released in order to provide a lightweight API for embedded graphics using a well-defined subset of the functionalities provided by the desktop version of OpenGL. While the specification is already out quite for a while, the wide adoption in the industry and the interest of application developers for it became strong only in the recent past. Currently, we have several mobile platforms that are bundled with 3D accelerators and provide a set of features via OpenGL ES that makes developers capable of creating games that weren&#8217;t possible even on desktop platforms about ten years ago.</p>
<h3>Going 3D on mobiles</h3>
<p>Those who know me, know that well that I was always interested in graphics, especially when using it for entertainment purposes. In particular, I was about to develop video games since the first time I&#8217;ve put my hands on a computer. This is no different now as well as now I&#8217;m writing about OpenGL ES and mobile platforms because I got interested in creating games for mobile phones.</p>
<p>As I&#8217;ve already mentioned before, the problem with developing for mobile equipments is the variety of hardware and software platforms that they are built on. As being somebody who is already familiar with desktop OpenGL, having OpenGL ES in the tool-set already eliminates some of the burden that I must face with.</p>
<p>Also when talking about application platform things have also changed a lot. Nowadays, we have just a few big players in the mobile OS industry thus easing the work of the developers. More precisely, if an application developer plans to go mobile and would like to grab the biggest market audience, can limit their efforts on the following platforms:</p>
<ul>
<li><strong>iPhone OS</strong> &#8211; This is the one that drives Apple&#8217;s iPhone mobile devices as well as the iPod Touch. It provides an application platform similar to that Mac developers got used to. It can be said that this platform is the most popular in the industry, especially when dealing with gaming applications.</li>
<li><strong>Android</strong> &#8211; This is the newest player in the field, brought by Google. While it&#8217;s a newbie in the industry it already captured the attention of tons of developers. We can say that currently Android and iPhone are dictating the direction of mobile entertainment.</li>
<li><strong>Symbian OS</strong> &#8211; Symbian has the largest share in most markets worldwide, still not that popular in the mobile gaming industry. It is the operating system running most of today&#8217;s Nokia phones.</li>
<li><strong>Windows Mobile</strong> &#8211; Microsoft&#8217;s product built on Windows CE, the company&#8217;s embedded operating system.</li>
<li><strong>RIM Blackberry OS</strong> &#8211; Operating system primarily designed for the business industry.</li>
</ul>
<p>While most of these mobile operating systems are built on the same design conceptions it is very difficult for the developer to create cross-platform applications for all these platforms as they vary on the language and tool-set support that minimizes the possibilities for code reuse. Unfortunately this is against the one of the most important rule of mobile development as to maximize portability.</p>
<p>It is not 100% true that there is no way to provide optimum portability for all these platforms, but if we choose this direction we are limited to two possibilities: cross-platform Java applications and web-based applications. While these seem to be excellent alternatives to native programming of the platforms, they severely limit the developer in creating applications that fully take advantage of the underlying hardware. This is when OpenGL ES comes into picture as all these platforms have API support thus providing at least some form of code reuse possibility when dealing with entertainment applications.</p>
<p>Now, I would like to continue with talking about the two platforms that I&#8217;m most interested in.</p>
<h3>iPhone OS</h3>
<p>I started to get involved in iPhone game development because one of my friends pushed me to after seeing the great success of his brother-in-law, <a title="zhooley's iPhone applications" href="http://www.zhooley.hu/iphone/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.zhooley.hu/iphone/?referer=');">zhooley</a> who had some great titles. Currently I don&#8217;t have a Mac yet to develop on, but already read some stuff about iPhone development. This is where the following information come from.</p>
<p>iPhone is currently is the most important platform for mobile application developers. It became such an important factor in the industry thanks to Apple&#8217;s AppStore. Previously there was little to no way for the end users to extend their mobile software base so easily. While this is good for the end user, it is maybe even better for application developers as AppStore provides them quite a large market audience.</p>
<p>The secret why iPhone is an excellent gaming platform lies in the palette of features that the phone hardware and the software frameworks provide. Just to mention the most important ones:</p>
<ul>
<li>Touch screen control with support for multi-touch events capturing the movement of up to five fingers.</li>
<li>Three accelerometers for tracking the spacial movement and direction of the device in all axes.</li>
<li>MVC inspired GUI framework for enhanced productivity.</li>
<li>Support for several industry standard APIs like OpenGL ES, OpenAL and much more.</li>
</ul>
<p>But that&#8217;s enough from the general speaking, let&#8217;s see what&#8217;s about OpenGL ES support on the iPhones&#8230;</p>
<p>As far as I can tell, not being an iPhone owner, the graphics hardware bundled with the mobile comes in form of PowerVR accelerators: MBX and SGX.</p>
<p>The PowerVR MBX has OpenGL ES 1.1 support, that is roughly equivalent to OpenGL 1.5, running a tile-based deferred renderer that is suitable for most 3D applications. That means it has only fixed function capabilities, however that is usually enough for most mobile applications. Also note that it has very limited amount of texture memory of 24MB.</p>
<p>The PowerVR SGX is a more powerful processor that also supports OpenGL ES 2.0, roughly equivalent to OpenGL 2.0, but has optimized fixed function shaders that provide flawless backward compatibility for OpenGL ES 1.1 applications.</p>
<p>The most important thing is still that all iPhones are able to do floating point maths natively and efficiently that is an important factor when dealing with OpenGL applications as the usage of the fixed point types can be quite a burden for developers, especially for those migrating from desktop development.</p>
<p>Additionally, the OpenGL ES implementation on iPhone provides some nice extensions like <a title="GL_OES_framebuffer_object" href="http://www.khronos.org/registry/gles/extensions/OES/OES_framebuffer_object.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.khronos.org/registry/gles/extensions/OES/OES_framebuffer_object.txt?referer=');">GL_OES_framebuffer_object</a>, <a title="GL_OES_compressed_paletted_texture" href="http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_paletted_texture.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.khronos.org/registry/gles/extensions/OES/OES_compressed_paletted_texture.txt?referer=');">GL_OES_compressed_paletted_texture</a> and <a title="GL_OES_point_sprite" href="http://www.khronos.org/registry/gles/extensions/OES/OES_point_sprite.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.khronos.org/registry/gles/extensions/OES/OES_point_sprite.txt?referer=');">GL_OES_point_sprite</a>. Also, thanks to the iPhone simulator that comes with the SDK it is easy to test the application during development without an actual device. Still, one important hint to mention is that the iPhone simulator has different OpenGL ES capabilities than the actual hardwares and also the performance characteristics measured on the simulator should not be taken as valid measurements because the simulator does not really simulate the graphics hardware but only the software platform.</p>
<p>iPhone development is done using the Cocoa API and preferably Objective-C, however C, C++ and Objective-C++ can be also used for development. One just has to interface somehow the Cocoa API and the rest can be done almost in any native programming language. That is one of the key advantages of the iPhone platform that one can develop native applications and no need for Java or web-based solutions.</p>
<p>While iPhone may seem to be a perfect choice for mobile game platform, we should not forget about one big disadvantage of it, in particular that one cannot develop legal iPhone applications without owning a Mac.</p>
<h3>Android</h3>
<p>The Android platform was suggested by one of my workmates who just brought a Droid. That phone is actually a device capable to compete with the iPhone from both features and performance point of view.</p>
<p>Android is the big hit of the last year and my forecast is that it will be one of the most relevant platforms of the upcoming years. Google adopted the idea of Apple and they also created an open market for the softwares that the end user can easily download and install on their devices. This is the AndroidMarket that can easily become a powerful competitor of the AppStore.</p>
<p>While, as I said earlier, the Motorola Droid, as an example, does support about the same feature set that makes the iPhone an excellent gaming platform, this cannot be said about most of the phones running Android on them. This is maybe one of the biggest disadvantages of the Android platform. However, we can take this also as an advantage as it makes it possible for more phones to adopt this operating system.</p>
<p>As the Android operating system is running on various phones from different vendors with different hardware capabilities, there isn&#8217;t too much to talk about the graphics hardware capabilities except that some devices not just don&#8217;t have a graphics accelerator but they also lack of floating point support. This is another disadvantage as it forces developers to stick to fixed point math in their OpenGL ES applications to maximize portability or they have to maintain two different rendering paths.</p>
<p>Originally, Android supported only OpenGL ES 1.0 that is roughly equivalent to OpenGL 1.3. However, since NDK r3 there is also OpenGL ES 2.0 support for Android as well. The feature set here varies much more from both hardware point of view and extension support.</p>
<p>Development for Android is done in Java using a proprietary SDK for accessing the Android API. The SDK comes with a simulator that works fine, except the long initial boot time that I was really surprised about when first trying it out.</p>
<p>One advantage of the SDK that it can be used in virtually any operating system so application developers can work on either Windows, Linux, MacOSX or other platform. There is also a nice Eclipse plugin that makes application development for Android even easier. That&#8217;s why I started with this one.</p>
<p>Just to illustrate how easy to put together some working demo with a good SDK, I&#8217;ve created a simple box rotating app to demonstrate OpenGL ES usage on Android. From installation till having a working application it took no more than two hours. You can find the download links for both the source code and the binary release at the end of the article.</p>
<h3>Why mobile games?</h3>
<p>I am a person who was, is and will be interested in developing computer games. Previously, I was working with desktop platforms and at the time when I was 10 years old it was satisfactory to put together some simple 2D game but not now.</p>
<p>I had always planned to create a state-of-the-art game engine and use it for some game, like most people like me do, but the efforts of one is simply unsatisfactory to compete with the players in the industry out there. Even if I feel the capability to be able to write such an engine but it would take that much time that I simply don&#8217;t have since I am working. Even if I would manage to accomplish it in a year or two then the problem with content creation comes into picture. For an AAA PC game content creation takes several times more than the actual programming and here I even lack the knowledge to achieve it. On the other hand mobile game creation is a much shorter process when you can get to actual results in a matter of weeks that is far better compared to PC game creation.</p>
<p>Also, I would never use third party game engines, except some basic libraries like OpenGL, a physics library and things like that because otherwise I wouldn&#8217;t feel the results being my own creation.</p>
<p>Having game development as a hobby works well during high school and university but it gets quite difficult after you are out there in the world having a job and responsibilities. Maybe I should have been already taking my time before to develop something concrete for PC but, as most fellow hobbyist know, you usually end up having hundreds of unfinished projects.</p>
<p>While I would never forget about desktop platforms and I will actively keep myself up with the evolution of the industry, mobile application development opened another world for me where I can unfold myself.</p>
<h3>HelloAndroid Demo</h3>
<p>Source code: <a href="http://rastergrid.com/blog/wp-content/uploads/2010/04/files/helloandroid_src.zip">helloandroid_src.zip</a><br />
Binary release: <a href="http://rastergrid.com/blog/wp-content/uploads/2010/04/files/HelloAndroid.apk">HelloAndroid.apk</a></p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/04/going-mobile-with-opengl-es/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Instance culling using geometry shaders</title>
		<link>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/</link>
		<comments>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 22:58:53 +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[fragment shader]]></category>
		<category><![CDATA[geometry instancing]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLEW]]></category>
		<category><![CDATA[GLM]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[SFML]]></category>
		<category><![CDATA[texture buffer]]></category>
		<category><![CDATA[transform feedback]]></category>
		<category><![CDATA[uniform buffer]]></category>
		<category><![CDATA[vertex buffer]]></category>
		<category><![CDATA[vertex shader]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=135</guid>
		<description><![CDATA[

Since the appearance of Shader Model 4.0 people wonder how to take advantage of the newly introduced programmable pipeline stage. The most important feature enabled by geometry shaders is that one can change the amount of emitted primitives inside the pipeline. The first thing that a naive developer would try to do with it is [...]]]></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%252F02%252Finstance-culling-using-geometry-shaders%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FanKmpg%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Instance%20culling%20using%20geometry%20shaders%22%20%7D);"></div>
<div id="attachment_136" class="wp-caption alignleft" style="width: 160px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/Nature-2010-02-08-20-20-36-24.png"><img class="size-thumbnail wp-image-136  " title="Nature demo screenshot" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/Nature-2010-02-08-20-20-36-24-150x150.png" alt="Nature demo screenshot" width="150" height="150" /></a><p class="wp-caption-text">OpenGL 3.2 - Nature</p></div>
<p>Since the appearance of Shader Model 4.0 people wonder how to take advantage of the newly introduced programmable pipeline stage. The most important feature enabled by geometry shaders is that one can change the amount of emitted primitives inside the pipeline. The first thing that a naive developer would try to do with it is geometry tesselation. However, the new shader performs very bad when used for tesselation in a real life scenario even though there are demos show casting this possibility. If we take a closer look at the new feature we observe that the most revolutionary in it is not that it can raise the number of emitted primitives but that it can discard them. This article would like to present a rendering technique that takes advantage of this aspect of geometry shaders to enable the GPU accelerated culling of higher order primitives.</p>
<p><span id="more-135"></span>Geometry shaders can be used for many different advanced rendering techniques that were impossible before the introduction of this flexible programmable shader stage. In this article I would like to present one use case that for me seemed to be one of the most practical application of primitive manipulation possibilities introduced by geometry shaders. As I haven&#8217;t seen any whitepaper talking specifically about this particular technique, even if some of them inherently used it, I would dare name the technique myself as <strong>Instance Cloud Reduction</strong>. I will also present a demo program that shows how to take advantage of the technique in a heavy workload situation.</p>
<p>The idea itself was inspired by AMD&#8217;s  tech demo for the Radeon 4800 series cards called <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>. An almost identical technique presented in this article is used in the mentioned demo for the culling of large amount of animated creatures against the view frustum. Also a somewhat similar technique is used in NVIDIA&#8217;s <a title="Skinned Instancing" 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 for determining LOD instance sets. Unfortunately, both demos are for DirectX only and, as far as I can tell, there is no OpenGL demo showing any of the aforementioned rendering techniques.</p>
<h3>Motivation</h3>
<p>Nowadays, as the computational capabilities of GPUs is growing in a much faster pace than that of CPUs, graphics developers meet more and more optimization problems related to CPU bound applications. More and more focus is on minimizing the number of driver invocations, actually that&#8217;s what motivated the restructuring of the two most commonly used graphics APIs. As a result we have now DirectX 10+ and OpenGL 3+. However, even if the introduction of geometry instancing, texture arrays and local memory buffer storage for the most important inputs of the rendering, there is still need for wise decisions from graphics programmers to take full advantage of the horsepower coming with the latest GPUs.</p>
<p>Earlier graphics applications strongly relied on CPU based culling techniques, whether it be the usage of the quite outdated BSPs or the more generic and still heavily applied hierarchical culling techniques. We&#8217;ve already reached the point that sometimes even the most efficient CPU based culling techniques seem to be too expensive and usually introduce the small batch problem. Instanced rendering is not an exception.</p>
<p>The applicability of geometry instancing is strongly limited by several factors. One of the most important ones is the culling of instanced geometries. One may choose to cull these objects in the same fashion as others, using the CPU, but that usually breaks the batch and maybe we loose the benefits of geometry instancing. It is more and more imminent to have a GPU based alternative. Without CPU based culling, by sending the whole bunch of instances down the graphics pipeline may choke our vertex processor in case we have high poly geometries and quite large amount of instances of it.</p>
<p>The rendering technique presented in this article will try to achieve this goal. We will use a multi-pass technique that in the first pass culls the object instances against the view frustum using the GPU and in the second pass renders only those instances that are likely to be visible in the final scene. This way we can severely reduce the amount of vertex data sent through the graphics pipeline.</p>
<h3>Implementation</h3>
<p>For some people it might seem that the promise for such a technique is simply too naive and is most probably relying on very exotic OpenGL features, heavy misuse of some basic features or need of data conversions during the frame rendering. Wondrously, this is not the case as we have all we need in OpenGL 3.2 to implement the object culling method sketched above. All we need are the followings:</p>
<ul>
<li>instanced rendering (core since OpenGL 3.1)</li>
<li>geometry shaders (core since OpenGL 3.2)</li>
<li>transform feedback (core since OpenGL 3.0)</li>
<li>uniform or texture buffers (core since OpenGL 3.1)</li>
</ul>
<p>The method itself is a multi-pass rendering technique, however, unlike other multi-pass rendering techniques it does not produce any fragments in the first pass, instead the first pass does the view frustum culling and processes data entirely only inside buffer objects.</p>
<h3>Culling pass</h3>
<p>In the first pass we will feed the graphics pipeline with information about the instances that are needed to perform the view frustum culling. For this we need two inputs for the executed shaders in order to be able to perform the required calculations:</p>
<ol>
<li><strong>Instance transformation data</strong> (whether it be a simple transformation matrix or quaternions or whatever) -- This preferably comes from one or more buffer objects that are bound as vertex buffers to the context.</li>
<li><strong>Object extents information</strong> -- Beside the instance positions we have to know the extents of an instance in order to perform correct culling. This can be either a single float representing the object radius if we choose to use bounding spheres for the culling or a three-dimensional extent vector if we would like to use bounding boxes.</li>
</ol>
<p>Using these as input we can feed in the instance transformation data as attributes of point primitives to our culling shader. The culling shader is composed of a vertex and a geometry shader. In a typical setup the role of each is the following: the vertex shader determines whether the actual object instance&#8217;s bounding volume is inside the view frustum and sends a flag about the culling to the geometry shader, that will emit the instance data to the destination buffer if the flag says that the instance is likely to be visible or does not emit anything if it is determined that the object instance is out of view.</p>
<p>Next, transform feedback is used to capture the primitives emitted by the geometry shader into another buffer object that will be used in the actual rendering pass to source instance transformation data. Beside this, we also need to have an asynchronous query to determine the number of primitives generated to know how many instances of the object do we actually need to render. The following figure shows the workflow of the first pass:</p>
<div id="attachment_146" class="wp-caption aligncenter" style="width: 460px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_pass1.png"><img class="size-full wp-image-146" title="Culling pass" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_pass1.png" alt="Culling pass" width="450" height="200" /></a><p class="wp-caption-text">Instance Cloud Reduction - Pass 1: Culling</p></div>
<p>The actual geometry shader implementation needed to perform the actual culling based on the view frustum check performed by the vertex shader should look like the following chunk:</p>
<pre class="brush: c">#version 150 core

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

in vec4 OrigPosition[1];
flat in int objectVisible[1];

out vec4 CulledPosition;

void main() {

	/* only emit primitive if the object is visible */
	if ( objectVisible[0] == 1 )
	{
		CulledPosition = OrigPosition[0];
		EmitVertex();
		EndPrimitive();
	}
}</pre>
<p>In this example we used only simply a four-component position vector for the instance transformation data but the technique works well for transformation matrices and quaternions as well.</p>
<p>One more thing is that beside that we set up transform feedback in a way that we feed our buffer object dedicated for the culled instance data and we also started an asynchronous query to be able to determine the number of primitives written into the buffer object, it is also useful to turn of rasterization as we wouldn&#8217;t like to produce any fragments as a result of the first pass.</p>
<h3>Rendering pass</h3>
<p>In the second pass there is nothing special to do. Simply use whatever rendering setup you would like to use. The only things that need to be changed in this step compared to your already existing rendering path is that the instance data for the rendering must be sourced from the generated culled instance data buffer and, as a result, the number of instances passed for the instanced drawing functions shall be changed in order to render only the visible instances. This number can be read from the asynchronous query&#8217;s result that we started in the first pass.</p>
<p>The instance data in the rendering pass can be, of course, sourced from either a uniform or a texture buffer object. This depends on the actual use case and is more clearly explained in the article <a href="http://rastergrid.com/blog/2010/01/uniform-buffers-vs-texture-buffers/">Uniform Buffers VS Texture Buffers</a>.</p>
<p>Important note is that when one has to deal with several instanced geometries it is recommended to do the culling phase prior to rendering any instanced primitives because of the following reasons:</p>
<ul>
<li>The result of the first instance cloud&#8217;s culling is more likely to be finished on the GPU so no sync issues arise from reading the asynchronous query result to determine the number of visible instances.</li>
<li>Probably less state changes are needed as very different setup is required by the two passes.</li>
<li>Results in tidier renderer design as culling is clearly separated from actual rendering.</li>
</ul>
<p>Putting everything together, the application of the presented technique would result in the following workflow on the GPU:</p>
<div id="attachment_150" class="wp-caption aligncenter" style="width: 660px"><a href="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_combined.png"><img class="size-full wp-image-150" title="Instance Cloud Reduction" src="http://rastergrid.com/blog/wp-content/uploads/2010/02/icr_combined.png" alt="Instance Cloud Reduction" width="650" height="347" /></a><p class="wp-caption-text">Instance Cloud Reduction - Combined view of Pass 1 + Pass 2</p></div>
<h3>Conclusion</h3>
<p>We&#8217;ve seen that the presented advanced rendering technique is able to help in situations when we have to deal with large number of instanced geometries and how to take advantage of the latest features of graphics cards and OpenGL to perform view frustum culling calculations on the GPU. This prevents us from having to deal with complicated and expensive CPU based object culling methods that break the drawing batches, especially when dealing with dynamic objects. For ease the decision whether to incorporate this technique in your rendering engine I would like to present the advantages and disadvantages of it.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li>Heavily reduces the amount of processed data in a naive implementation.</li>
<li>No need for any space partitioning methods in the host application to handle the culling of dynamic objects.</li>
<li>Can handle huge amount of instanced objects due to the enormous horsepower of today&#8217;s GPUs.</li>
<li>Scales well with increased number of instances as the per-instance calculation is relatively low.</li>
<li>Relies strictly on OpenGL 3.2 core features.</li>
<li>No need for OpenCL capable hardware.</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li>Needs an extra rendering pass to perform the culling.</li>
<li>Requires the usage of asynchronous queries to determine the number of visible instances.</li>
</ul>
<p>I hope you agree with me and think about this technique as one more step towards fully GPU based scene management. If you have any remarks or improvement ideas regarding to the rendering technique itself feel free to tell me.</p>
<h3>The Demo</h3>
<p>As I promised, the technique presented above comes with a live demo that actually took most of my time dedicated to writing this blog in the last two weeks. The demo itself is more like a technical show cast rather than a presentation of a real-life use case scenario.</p>
<p>First of all, I used high polygon count models for the rendering to emphasize the amount of time the culling phase spares from the very valuable time of our GPU. In a real world application one would never do something like this. As a result, the demo is more like a benchmark than an interactive application. However, maybe on high-end graphics cards it can perform pretty well.</p>
<p>The demo scene consists of two object types: trees and grass blocks. The tree model is further divided into two parts as they need different textures: the tree trunk and the tree foliage. Obviously, this additional burden can be prevented by using texture arrays to avoid the need of separate draw calls to render the trunk and the foliage.</p>
<p>The tree trunk consists of 33138 triangles, the tree foliage has 16069 triangles and the faking-free grass block consists of 8961 triangles which I had to model myself as didn&#8217;t found any suitable model. Actually this modeling step consumed quite a reasonable amount of my time spent with the demo as I&#8217;m not an expert in this domain.As you can see, these models are not the ones that one might use in an interactive real-time application like games. However, they seemed to be very suitable for the purpose of the demonstration.</p>
<p>What really kicks off the boundaries of GPUs is that the demo renders 10,000 trees and 250,000 grass blocks using instancing. This ends up in more than <strong>2.7 billion triangles</strong> in the scene. This is far more that a GPU can handle without the aid of some scene management and culling. However, we will use no scene management at all and the only culling method that we will use is the one presented in this article.</p>
<p>The actual results are quite promising. The view frustum culling step usually spares more than <strong>99.9%</strong> of the GPU horsepower as the amount of actually rendered triangles after the culling step is far below 2 million triangles. This is still quite much but as we use high polygon count models and we don&#8217;t use any LOD techniques this seems reasonable.</p>
<p>Even if the demo scene statistics doesn&#8217;t seem like a typical use case scenario, the ease of the implementation and the compelling visual results made me pleased anyway:</p>
<p style="text-align: center;"><span class="youtube">
<object width="640" height="480">
<param name="movie" value="http://www.youtube.com/v/srbOFTLTe8k&amp;color1=3a3a3a&amp;color2=999999&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/srbOFTLTe8k&amp;color1=3a3a3a&amp;color2=999999&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="640" height="480"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=srbOFTLTe8k&fmt=18" onclick="pageTracker._trackPageview('/outgoing/www.youtube.com/watch?v=srbOFTLTe8k_fmt=18&amp;referer=');">www.youtube.com/watch?v=srbOFTLTe8k</a></p></p>
<p>On my Radeon HD2600XT I have achieved 6-7 frames per second which is acceptable taking in consideration the huge amount of geometry data still passed to the graphics card. On more recent cards I suppose it should run with good frame rates, however, due to the lack of hardware to test on, these are my only results. If anybody manages to take a better screen capture than mine above then please let me know.</p>
<h3>Implementation details</h3>
<p>Just to tell a few words about what techniques and tricks I&#8217;ve used during the creation of the demo here is a listing of the most important ones:</p>
<ul>
<li>Three models are used as mentioned previously with high instance counts with over 2.7 billion of total triangles in the scene as mentioned already.</li>
<li>Three 512x512 RGBA textures are used for the models that are partially handmade, and again, I&#8217;m not a texture artist so sorry if they don&#8217;t look flawless.</li>
<li>The wavefront model and TGA image loader that accompany the demo are very roughly implemented only for the demo so I would strongly encourage you not to use it to any purpose as it handles only a subset of the possibilities of the file formats.</li>
<li>The vertex data from the wavefront model files is transferred in a very naive way so vertex reuse isn&#8217;t taken into account.</li>
<li>The instance data consists of simple four-component vectors representing the world-space position of the instance. This seemed to be the most simple for the demonstration purposes.</li>
<li>In the second pass, the instance data is sourced from a texture buffer but not really because the visible instance count exceeded the amount that would fit in a uniform buffer. I used texture buffers because for this simple demonstration they seemed to be a little bit more easy to be integrated.</li>
<li>The morphing effect that simulated wind blow is done using hard-coded geometry deformation in the vertex shader. It is not physically correct but visually compelling.</li>
<li>The lighting is a simple directional light using Phong&#8217;s shading and reflection model.</li>
<li>Simple fog is simulated with some awkward formula that I&#8217;ve chosen after a few test runs.</li>
<li>Alpha testing is achieved by using the discard operation in the fragment shader.</li>
</ul>
<h3>Driver issues</h3>
<p>During the development of the demonstration program I&#8217;ve met several driver related problems as I&#8217;ve never used so heavily the latest OpenGL features previously. I&#8217;ve worked with Catalyst 9.12 and 10.1 but both seemed to lack of a proper GLSL compiler. Here are some of the issues I&#8217;ve met:</p>
<ul>
<li>When I&#8217;ve forgot to declare the varyings in the geometry shader as arrays like the standard requires then still the driver hasn&#8217;t complained about any syntax error but when tried to execute the code the program crashed.</li>
<li>Except the texture sampler uniform, all other uniforms failed to work when used in the fragment shader only so I&#8217;ve put them all in the vertex shader.</li>
<li>For loops seemed not to work when used inside the geometry shader, that&#8217;s why the culling itself is done in the vertex shader in the demo.</li>
</ul>
<p>All these problems resulted in nasty tricks to make things working and ended up in awful shader code. Sorry for that. At least now it works on my configuration but pretty unsure whether it will work on other graphics card and driver combos. Please report me any success or failure when trying out the demo. Anyway, be sure to have the latest graphics drivers installed as, at least in case of AMD, OpenGL 3.2 drivers came out only at the fall of 2009.</p>
<p><em><strong>Edit:</strong></em></p>
<p><em>Thanks to the information got from Pierre Boudier from AMD I&#8217;ve updated both the source and binary releases to support the latest drivers properly. The problem was that I didn&#8217;t use attribute location binding as specified in the standard.</em></p>
<p><em>Also have to mention that with my new Radeon HD5770 I managed to achieve over 90 frames per second that actually show that this technique can be in fact used for games and other interactive applications.</em></p>
<p><em>One more thing in the end. As you know this version of the Nature demo uses a texture buffer to source instance positions. I plan to create another version that will take advantage of the instanced arrays introduced in core with OpenGL 3.4. I expect quite a reasonable speedup as that would eliminate the need for texture fetches in the vertex array by rather dedicating a vertex fetcher for the purpose thus increasing the overall performance of the technique.</em></p>
<h3>Binary release</h3>
<p><strong>Platform:</strong> Windows<br />
<strong>Dependency:</strong> OpenGL 3.2 capable graphics driver<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_win32.zip" target="_blank">nature12_win32.zip (3.58MB)<br />
</a><strong>Comments:</strong> Includes the update that makes it work even with the latest drivers.</p>
<h3>Full source code</h3>
<p><strong>Language:</strong> C++<br />
<strong>Platform:</strong> cross-platform<br />
<strong>Dependency:</strong> GLEW, SFML, GLM<br />
<strong>Download link:</strong> <a href="http://rastergrid.com/blog/wp-content/uploads/2010/06/nature12_src.zip" target="_blank">nature12_src.zip (12.6KB)<br />
</a><strong>Comments:</strong> Sorry for the many dependencies, however, I would recommend the mentioned libraries for everybody who is doing OpenGL development.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Synchronizable objects for C++</title>
		<link>http://rastergrid.com/blog/2010/02/synchronizable-objects-for-c/</link>
		<comments>http://rastergrid.com/blog/2010/02/synchronizable-objects-for-c/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 19:01:56 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Multiprocessing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[macro]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[OpenMP]]></category>
		<category><![CDATA[synchronization]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=120</guid>
		<description><![CDATA[

Previously I talked about how one can easily take advantage of multiprocessing using OpenMP. Even if the C pragmas introduced by the parallel programming API standard is very straightforward for simple programs, it simply doesn&#8217;t fit nicely in a complex C++ application that is built from the ground with the OOP in mind. To smoothly [...]]]></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%252F02%252Fsynchronizable-objects-for-c%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FbbpIPT%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Synchronizable%20objects%20for%20C%2B%2B%22%20%7D);"></div>
<p>Previously I talked about how one can easily take advantage of multiprocessing using OpenMP. Even if the C pragmas introduced by the parallel programming API standard is very straightforward for simple programs, it simply doesn&#8217;t fit nicely in a complex C++ application that is built from the ground with the OOP in mind. To smoothly introduce OpenMP into such projects one need higher level constructs that hide the actual implementation details. This is the first article of a series that will try to provide reference implementations of such an abstraction. First, we will start with synchronizable primitives that try to reflect the functionality provided by the &#8220;synchronized&#8221; statement of Java.</p>
<p><span id="more-120"></span>This article is highly inspired by an article written by <a title="A &quot;synchronized&quot; statement for C++ like in Java" href="http://www.codeproject.com/KB/threads/cppsyncstm.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.codeproject.com/KB/threads/cppsyncstm.aspx?referer=');">Achilleas Margaritis</a><span style="line-height: normal; -webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px; font-size: small;"> and is mostly equivalent with his thoughts. My article tries to provide a portable reference implementation of a slightly modified version of the trick presented by Margaritis that uses OpenMP as the multiprocessing API back-end.</span></p>
<h2>Motivation</h2>
<p><span style="line-height: normal; -webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px; font-size: small;">According to the OO paradigm, classes and consequently objects provide an abstract interface to the underlying internal data or services of the modeled entity or entity class. When it comes to parallel programing we should provide facilities to enable concurrent access to shared resources that are in this case objects. Using plain OpenMP can be satisfactory, however when used extensively the OpenMP pragmas and API function calls introduced can greatly affect the readability and the maintainability of the code. Nevertheless, there can be platforms that use other APIs for handling race conditions. It is obvious that we need to encapsulate these facilities and provide an abstract tool-set instead.</span></p>
<h2>Implementation</h2>
<p><span style="line-height: normal; -webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px; font-size: small;">The very first building block of such a framework can be a mutex class that provides mutually exclusive access to certain resources. In the world of OpenMP this should look like something similar to the following:</span></p>
<pre class="brush: cpp">class Mutex {
public:
    Mutex() { omp_init_lock(&amp;_mutex); }
    ~Mutex() { omp_destroy_lock(&amp;_mutex); }
    void lock() { omp_set_lock(&amp;_mutex); }
    void unlock() { omp_unset_lock(&amp;_mutex); }
private:
    omp_lock_t _mutex;
};</pre>
<p>This seems already enough for us to make our Java-like &#8220;synchronized&#8221; statement, however we would like to create a framework that makes usage as easy and safe as possible. In order to get closer to this goal we apply the RAII (Resource Acquisition Is Initialization) design pattern to create our lock class:</p>
<pre class="brush: cpp">class Lock {
public:
    Lock(Mutex&amp; mutex) : _mutex(mutex), _release(false) { _mutex.lock(); }
    ~Lock() { _mutex.unlock(); }
    bool operator() const { return !_release; }
    void release() { _release = true; }
private:
    Mutex&amp; _mutex;
    bool _release;
};</pre>
<p>Our goal is to provide an inheritable interface for such objects that needs synchronization. However, this step has to involve severe considerations regarding to the provided interface as we explicitly need to conform to the following requirements:</p>
<ul>
<li>The interface shall not expose the interface of the underlying synchronization primitive, in our case the mutex class methods.</li>
<li>The interface shall be available only to the synchronizable objects but not for the external world as we would like to not just hide the implementation details of our abstract entity but also prevent the users to synchronize our objects as it should be the responsibility of the object itself.</li>
<li>The interface shall expose methods which are less prone to name collision, for convenience.</li>
</ul>
<p>If we take care of the presented conventions we end up with an interface similar to the following:</p>
<pre class="brush: cpp">class Synchronizable: protected Mutex {
protected:
	void enterSyncBlock() { this-&gt;lock(); }
	void exitSyncBlock() { this-&gt;unlock(); }
};</pre>
<p>Now we are almost at the finish line. We just need to inherit this class in order to have the needed facilities for an object that needs synchronization. However, using this interface directly is not the most comfortable and safe. If we would like to have a Java-like &#8220;synchronized&#8221; statement we have to call for additional help. Fortunately, we have our not so well respected C macro language coming to rescue us as we can use it to make some pseudo-language extensions. The simplest way to define our new statement is using the following line:</p>
<pre class="brush: cpp">#define synchronized(obj)  for(Lock obj##_lock = *obj; obj##_lock; obj##_lock.release())</pre>
<p>From now, we can really use object synchronization in C++ as easy as in Java, we just need the following syntax in the method of our shared objects:</p>
<pre class="brush: cpp">synchronized(this) {
    // some code that needs synchronization
}</pre>
<p>Now it is clearly visible how handy the RAII pattern became in our case. Beside that it is now very straightforward to use this statement it provides additional benefits:</p>
<ul>
<li>It makes the code more readable and as a result it is easier to maintain.</li>
<li>No need to call inconveniently named methods and use lock variables.</li>
<li>The synchronized code has it&#8217;s own scope inside the code.</li>
<li>It is exception-safe as the mutex is unlocked upon destruction.</li>
</ul>
<p>Additionally, we can also take advantage of the inherent problem in C++ regarding to multiple inheritance. If we inherit our object from other two synchronized objects then using a simple type casting we can explicitly specify which ancestor we would like to synchronize in a particular block. Also, to ease this we can define our synchronization statement instead of the Java-like one using the following line:</p>
<pre class="brush: cpp">#define synchronized(cls)  for(Lock obj##_lock = *static_cast&lt;cls*&gt;(this); obj##_lock; obj##_lock.release())</pre>
<p>In this case we pass the class name instead of the object pointer <em>this</em>. Using this later construct we can easily specify the correct ancestor that we would like to synchronize in case when we deal with multiple inheritance situations. Personally I prefer the later syntax as it is much more customized for C++ use cases.</p>
<p>As from now we don&#8217;t need a direct interface for entering and exiting our synchronization block we can simplify our synchronizable interface to the following chunk:</p>
<pre class="brush: cpp">class Synchronizable: protected Mutex {
};</pre>
<p>This is enough from now to provide the facilities needed for a synchronization block but still complies to the requirement that we would like to hide the synchronization primitive related details.</p>
<p>Beside this, Jörg came up with the idea today to replace the for loop in our macro with a single if statement. This seems reasonable as we don&#8217;t have to sacrifice any scoping and safety related benefits of our framework. This simplifies our lock class to the following:</p>
<pre class="brush: cpp">class Lock {
public:
    Lock(Mutex&amp; mutex) : _mutex(mutex) { _mutex.lock(); }
    ~Lock() { _mutex.unlock(); }
    bool operator() const { return true; }
private:
    Mutex&amp; _mutex;
};</pre>
<p>This definition of the lock class is satisfactory if we redefine our synchronized macro to use an if statement instead:</p>
<pre class="brush: cpp">/* Java-like synchronized statement */
#define synchronized(obj)  if (Lock obj##_lock = *obj)
/* alternative synchronized statement to support multiple inheritance */
#define synchronized(cls)  if (Lock obj##_lock = *static_cast&lt;cls*&gt;(this))</pre>
<p>Thanks to the useful comments we even managed to further optimize and minimize the support code needed for our new pseudo-language extension.</p>
<h2>Conclusion</h2>
<p>We have seen an example how one can implement an easy to use synchronizable interface for C++. Also, we&#8217;ve provided a concrete implementation that is based on OpenMP. This library is still far from an API that provides all the necessary constructs that one needs for using parallel programming in their C++ projects, however we made our first step and I will recap on the subject in subsequent articles to further extend this framework.</p>
<p>Credits go to Achilleas Margaritis whose article inspired me to write mine and to Jörg for the useful improvement ideas.</p>
<h3>Full source code</h3>
<p><strong>Language:</strong> C++<br />
<strong> Platform:</strong> cross-platform<br />
<strong> Dependency:</strong> OpenMP<br />
<strong> Download link:</strong> <a title="omp_sync.h" href="/blog/wp-content/uploads/2010/02/files/omp_sync.h" target="_blank">omp_sync.h</a><br />
<strong> Comments:</strong> In order to use it as it is, you will need a C++ compiler supporting OpenMP like GCC 4.2 or Visual C++ 2008.</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/02/synchronizable-objects-for-c/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
