<?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>Parse Error &#187; OpenGL</title>
	<atom:link href="https://vertostudio.com/gamedev/?cat=12&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://vertostudio.com/gamedev</link>
	<description>Michael L. Farrell&#039;s Game Dev Blog</description>
	<lastBuildDate>Tue, 08 Dec 2020 18:13:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Porting to mobile &#8211; A few weeks of work boiled down to one post.</title>
		<link>https://vertostudio.com/gamedev/?p=411</link>
		<comments>https://vertostudio.com/gamedev/?p=411#comments</comments>
		<pubDate>Thu, 07 May 2015 01:05:27 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=411</guid>
		<description><![CDATA[DG on Mobile After putting roughly 6 months into this project, it seemed stupid not to go the extra mile and release this game for iOS if it was possible to be ran on it.   So that&#8217;s what I spent the last few weeks doing, and I eventually reached success (I submitted it to [...]]]></description>
			<content:encoded><![CDATA[<h1><a href="http://vertostudio.com/gamedev/wp-content/uploads/2015/05/image.jpg"><img class="aligncenter size-full wp-image-412" title="image" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/05/image.jpg" alt="" width="348" height="310" /></a></h1>
<h1>DG on Mobile</h1>
<p>After putting roughly 6 months into this project, it seemed stupid not to go the extra mile and release this game for iOS if it was possible to be ran on it.   So that&#8217;s what I spent the last few weeks doing, and I eventually reached success (I submitted it to the store for review this weekend).   Disclaimer, much of this post was written using voice dictation so it might not flow as well as a typed document</p>
<h1>What it took</h1>
<p>Now even though mobile was in the back of my mind, this game was never really designed to run on mobile. The final desktop game took up roughly 1 GB of disk space and 1 gigabyte of RAM running which would slowly rise to 4 GB over time which I suspected and later confirmed to be caused by memory leaks.</p>
<p>To get the game to run on my iPhone 5s, The first thing I did was make some minor modifications to the graphics engine code base to support running OpenGL 3.2 code on an iOS device.  The easiest way to do this, was to simply target the OpenGL ES 3.0 API. The differences between OpenGL 3, and GLES 3.0  are so minor, that this was the best bet that I had for an effortless port of the game.   This sure beat the hell out of the alternative which was to laboriously rewrite my dozens of now-forked shaders in GLSL for OpenGL ES 2.0.   The downside to this however, was that I basically was cutting off any iOS device that could not run OpenGL ES 3.0 (pre-iPhone 5s, pre iPad air).  I still decided to go for it despite all this.</p>
<p>OpenGL ES 3.0 supported so many things that I needed for my game (such as multiple render targets, shadow maps, occlusion queries, etc) that the whole process worked out really well.   Things that used to be near impossible to do on mobile OpenGL were now surprisingly easy to accomplish.</p>
<p>Still, there were some serious challenges that I had to overcome</p>
<h1>What sucked and needed fixing</h1>
<p>Off the bat, the most serious and challenging problem presented itself almost immediately after running a few levels of the game on my iPhone:  RAM consumption.   Almost immediately, loading the first level resulted in memory warnings and the eventual memory crash caused by allocating too much RAM on the device (this equates to roughly 512 MB on an iPhone 5s).   This almost made me cancel the idea immediately thinking that there&#8217;s no way the game could fit as designed on a mobile device.   When I ran the instruments tool, A utility that comes with Xcode to help you trace allocations and such,  I discovered that my sound effects alone were taking up well over 100 megs of RAM.   I also discovered that the heap was growing at an alarming rate between level reloads resulting in the eventual memory crash.   Other assets such as textures and animation data were taking up another hundred megabytes or more (GPU memory is not easily trackable on an iOS device so I could only speculate how much the standard high-resolution desktop textures were taking up).</p>
<p>I used the invaluable &#8220;generations&#8221; tool of the instruments utility to track down an eliminate my biggest causes of memory leaks.  The funniest one I can remember is the silent failure of the OpenAL alDeleteBuffers call resulting in the leak of ALL sound effects used in the game, including the very large &#8220;radio music&#8221; buffer which held roughly 1+ minutes of music audio.  Leaking this was wasteful on desktop, but downright devastating on mobile.   Discovering that I had to dequeue the auduo buffer first, solved that issue.  Other stupidities such as bad pointer casting and issues related to C++ 11 smart pointer retain cycles I counted for the other memory leaks.</p>
<p>Apart from the memory leaks, there was a very serious issue that almost crippled the release of the entire game on mobile. This one was not my fault, and it&#8217;s related to a arcane bug in the iOS OpenGL 3.0 driver  and how it handles OpenGL occlusion queries.   Leave it to me to always find GL driver bugs in just about every platform I target for my games.   This particular bug caused repeated usage of occlusion queries to eventually crash the whole app inside the driver code. I frustratingly posted this on the Apple developer forums, and got one of the engineers (one of the awesome engineers) to track down the issue and provide a workaround for me which fix the issue.  For those that are curious, the workaround was to run the occlusion queries without an active color buffer attached to the default frame buffer object, bypassing the issue that leads to the crash.</p>
<p>Fixing all these issues however, still would not of been enough to get the game to run on iOS</p>
<h1>Optimizations for mobile</h1>
<p>To get the game to work &#8220;fit&#8221; on my iPhone 5s and iOS in general, I had to make the following optimizations</p>
<ul>
<li>UX/controls &#8211; The game needed to support a touchscreen interface.  I  accomplished this by adding various touch regions for things like the aiming (touchpad on the left side of the screen), shooting (lower right hand corner of the screen), and vehicle acceleration/deceleration (tilting the device).</li>
<li>Compressed reduced-resolution textures &#8211; this was probably the biggest deal.   I took advantage of the OpenGL ES 3.0 standard ETC2 compression to pre-compress all textures to this special format.   This allowed me to drastically reduce both the ram and disk space consumption of the texturea for the game.  It also drastically decreased the amount of time it took for the scenes to load, offsetting the load delays caused by the slower CPU on my iPhone.</li>
<li>Shortened sound effects &#8211; I truncated very long sound effects such as the radio music which were loaded as OGG files.  I reduced these from over one minute to roughly 30 second loops at the longest, drastically reducing the amount of memory taken up by the audio in RAM.  The reason why the sound effects have to exist as full audio buffers has to do with the real-time effects that I apply to them using Open AL in the game.</li>
<li>Gzipped scene metadata &#8211;  despite already using a binary XML format to store the actual scene data, I found that the disk space usage of all of my scenes was still very high and I could not expect users to download a 1 GB app on iOS.  I fix this by gzipping the project files and live-decompressing them on load (using C++ gzipped file streams).   Despite this adding a very slight CPU performance hit on load, it was worth it for the reduced app size &#8211;  which I ultimately got down to roughly 500 MB.</li>
<li>Shader optimization &#8211;  because many of the game&#8217;s shaders were written for a far more powerful desktop GPU,  I had to make optimizations such as reducing precision in some areas and disabling more expensive effects in the game to account for the slower GPUs on mobile.   I also added an option to the game&#8217;s main menu to disable the retina display on certain devices and even made this the default on devices such as the iPad Air first-generation.</li>
</ul>
<p>I also added support for MFI game controllers, a supported API by iOS 7 and above to allow players with physical game pads to get the best gaming experience possible. This was not a big stretch considering the original game was designed for physical buttons in the first place.</p>
<p>After doing all of this crazy stuff, I finally got the game to run reliably without crashing on my iPhone 5s and iPad air.</p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2015/05/image1.jpg"><img class="aligncenter size-large wp-image-413" title="image" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/05/image1-1024x768.jpg" alt="" width="625" height="468" /></a></p>
<p>Victory.</p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=411</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Push through to the end</title>
		<link>https://vertostudio.com/gamedev/?p=378</link>
		<comments>https://vertostudio.com/gamedev/?p=378#comments</comments>
		<pubDate>Mon, 09 Mar 2015 23:13:11 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=378</guid>
		<description><![CDATA[After a long vacation abroad during the past month or so, it is a must that this game will meet it&#8217;s goal of completion in march.  I&#8217;ve pushed through to level 19 today with great progress.  The new newspaper-esque art style looks really good and at this point, it&#8217;s just a race to the finish [...]]]></description>
			<content:encoded><![CDATA[<p>After a long vacation abroad during the past month or so, it is a must that this game will meet it&#8217;s goal of completion in march.  I&#8217;ve pushed through to level 19 today with great progress.  The new newspaper-esque art style looks really good and at this point, it&#8217;s just a race to the finish line.  The coolest thing about experimentation sometimes is how you stumble on to a specific kind of rendering style by accident.  I&#8217;ve found that by using the same SSAO technique that I have previously implemented while removing the depth-checking produces a dark outline halo around most models in the scene.  While for generalized SSAO this would be undesirable, I love the way it looks and have decided to make it part of the art style for the dark/noire second-half section of the game.  Combining that effect with a lack of the blur post-processing effect on the noisy SSAO results in the very newspaper/comicbook style that I was already <span style="line-height: 1.714285714; font-size: 1rem;">going for.  </span></p>
<p>Needless to say, things are going well now that I&#8217;m back at it.</p>

<a href='https://vertostudio.com/gamedev/?attachment_id=379' title='art style'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/03/art-style-150x150.jpg" class="attachment-thumbnail" alt="art style" title="art style" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=380' title='art style 2'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/03/art-style-2-150x150.jpg" class="attachment-thumbnail" alt="art style 2" title="art style 2" /></a>

]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=378</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ambient Occlusion</title>
		<link>https://vertostudio.com/gamedev/?p=362</link>
		<comments>https://vertostudio.com/gamedev/?p=362#comments</comments>
		<pubDate>Fri, 30 Jan 2015 21:51:55 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=362</guid>
		<description><![CDATA[So I got the ambient occlusion effect implemented in the actual game shader code.  I followed the technique outlined in this article.  I must say, it&#8217;s very subtle, but it looks nice.  The real benefit here is that when I turn off the &#8220;check depth range&#8221; mechanism, I get a very awesome surreal dark outline [...]]]></description>
			<content:encoded><![CDATA[<p><span style="line-height: 1.714285714; font-size: 1rem;">So I got the ambient occlusion effect implemented in the actual game shader code.  I followed the technique outlined in <a title="this article" href="http://t.co/xleU0YlQbY">this article</a>.  I must say, it&#8217;s very subtle, but it looks nice.  The real benefit here is that when I turn off the &#8220;check depth range&#8221; mechanism, I get a very awesome surreal dark outline around all of the models in the scene.  This will be an excellent effect to use when I work on the second half of the game (which will use an artistic black and white noire post processing style signifying the protagonists slowly weakening grip on reality).</span></p>
<p>I didn&#8217;t understand how ambient occlusion worked at all before implementing the effect, but now I must say, I have a pretty reasonable grasp on it.  Basically in one brief description, it takes random samples at every point on the surface to determine how much ambient light from the rest of the scene can reach that point.  In other words, how much of the ambient light is occluded by other nearby surfaces.  This is done by randomly sampling points within a small hemisphere emanating from the surface.  What makes SSAO so nice, is that this technique is approximated entirely in screen space, making it reasonable for real-time rendering in a game.  The downside is it seems to be a little noisy and I see artifacts from time to time on the screen, but hopefully I&#8217;ll be able to clean some of that up in time.</p>
<p>Below are some more progress shots showing the kinds of subtle shadowing I can achieve using SSAO in the VGLPP/DrivebyGangster engine.</p>

<a href='https://vertostudio.com/gamedev/?attachment_id=363' title='Screen Shot 2015-01-28 at 2.22.25 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/01/Screen-Shot-2015-01-28-at-2.22.25-PM-150x150.png" class="attachment-thumbnail" alt="Screen Shot 2015-01-28 at 2.22.25 PM" title="Screen Shot 2015-01-28 at 2.22.25 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=364' title='ssao_comparison'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/01/ssao_comparison-150x150.png" class="attachment-thumbnail" alt="ssao_comparison" title="ssao_comparison" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=365' title='ssaoshot'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/01/ssaoshot-150x150.png" class="attachment-thumbnail" alt="ssaoshot" title="ssaoshot" /></a>

]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=362</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ambient Occlusion!</title>
		<link>https://vertostudio.com/gamedev/?p=357</link>
		<comments>https://vertostudio.com/gamedev/?p=357#comments</comments>
		<pubDate>Tue, 27 Jan 2015 02:49:00 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=357</guid>
		<description><![CDATA[Today was huge!  I am exhausted.  I busted my ass today to get an affect known as screen-space ambient occlusion (SSAO) working in a prototype scene in verto studio.  Right when I was about to give up, I got it working!  I&#8217;m too groggy to explain anything about it, so I&#8217;ll just post pictures! This [...]]]></description>
			<content:encoded><![CDATA[<p>Today was huge!  I am exhausted.  I busted my ass today to get an affect known as screen-space ambient occlusion (SSAO) working in a prototype scene in verto studio.  Right when I was about to give up, I got it working!  I&#8217;m too groggy to explain anything about it, so I&#8217;ll just post pictures!</p>
<p>This is going to add a huge boost to the visual look-and-feel of the game without a severe performance penalty.  Needless to say, I&#8217;m pretty stoked!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>

<a href='https://vertostudio.com/gamedev/?attachment_id=359' title='Screen Shot 2015-01-26 at 6.24.37 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/01/Screen-Shot-2015-01-26-at-6.24.37-PM-150x150.png" class="attachment-thumbnail" alt="Screen Shot 2015-01-26 at 6.24.37 PM" title="Screen Shot 2015-01-26 at 6.24.37 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=360' title='Screen Shot 2015-01-26 at 6.44.02 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2015/01/Screen-Shot-2015-01-26-at-6.44.02-PM-150x150.png" class="attachment-thumbnail" alt="Screen Shot 2015-01-26 at 6.44.02 PM" title="Screen Shot 2015-01-26 at 6.44.02 PM" /></a>

]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=357</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL point light shadows &amp; Atomspheric FX hacks</title>
		<link>https://vertostudio.com/gamedev/?p=319</link>
		<comments>https://vertostudio.com/gamedev/?p=319#comments</comments>
		<pubDate>Sat, 27 Dec 2014 08:44:56 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=319</guid>
		<description><![CDATA[So asset creation in the form of modeling the final environment that&#8217;ll be used in the game took the past few days.  It&#8217;s amazed how much faster it went this time compared the first scene (the city street).  I chalk this up to experience that I&#8217;ve picked up now that I&#8217;ve been doing this awhile, [...]]]></description>
			<content:encoded><![CDATA[<p>So asset creation in the form of modeling the final environment that&#8217;ll be used in the game took the past few days.  It&#8217;s amazed how much faster it went this time compared the first scene (the city street).  I chalk this up to experience that I&#8217;ve picked up now that I&#8217;ve been doing this awhile, and my understanding of things that are very time consuming to model vs things I can quickly grab, import, texture, and place from turbosquid.  The perfect balance of both techniques has led to me being done with the dark night alley street scene after just a few days.</p>
<p>Where I spent the most time this time was in the shaders.  I really wanted to have quality rendering and go out with a bang since this&#8217;ll likely be the last environment that I do for the game.  I want the dark alleyway to appear foggy and dark, like its just about to rain.  That includes moist shiny cobblestone rocks, and a damp fog effect that feels very palpable to the player.</p>
<p>This idea of mine posed two major problems that I haven&#8217;t had to tackle until now.</p>
<h2>Point Light Shadows</h2>
<p>The first major problem, is that I could no longer &#8220;cheat&#8221; using a single directional light source representing the &#8220;sun&#8221; in the scene.  Instead, I had to place a street lamp every building or so and have these be the only sources of light in the scene.  This means, in order to keep my shadows working, I now had to implement shadows from a point light source.  In some ways this was easier than point lighting (no longer necessary to compute an optimal shadow bounding box to be used for the light&#8217;s ortho matrix projection).  However, now I needed render to and utilize cube maps to store the shadow depth information.  Surprisingly, there was very little comprehensive information on the web about how to properly do PCF shadows using cubemaps.</p>
<p>What I found that works is the following.</p>
<ul>
<li>Create a cubemap renderer that is positioned at the exact same position as one of the point lights - <span style="line-height: 1.714285714; font-size: 1rem;">this special vgl engine object renders the scene into 6 faces of a cubemap with 90-degree fov angles to properly capture the entire scene from &#8220;all angles&#8221;.</span></li>
<li><span style="line-height: 1.714285714; font-size: 1rem;">Format the cubemap shader to have each face hold floating point depth-component values and keep the size small (256&#215;256) since there will be alot of these.</span></li>
<li><span style="line-height: 1.714285714; font-size: 1rem;">Define an &#8220;override&#8221; shader to be used by the above cubemap renderer to ensure a simple specialized &#8220;light render&#8221; shader was used when rendering the scene into the cubemap faces.  </span></li>
<li>Set the cubemap compare mode (<span style="line-height: 1.714285714; font-size: 1rem;"><em>GL_TEXTURE_COMPARE_MODE</em>) </span>for the rendered cubemap texture to <span style="line-height: 1.714285714; font-size: 1rem;"><em>GL_COMPARE_REF_TO_TEXTURE</em> which helps with percentage-closest-filtering (PCF) mode to allow smoother linear-interpolated shadow edges.  </span></li>
<li><span style="line-height: 1.714285714; font-size: 1rem;">Lastly, pass a rendered shadow cubemap for each light to the scene shaders in the form of <em>samplerCubeShadow</em></span></li>
</ul>
<p>The &#8220;light render&#8221; shader mentioned above which is used when rendering the depth information to the cubemaps looks like so:</p><pre class="crayon-plain-tag">precision mediump float;
in mediump vec4 w_pos;
out vec4 fragColor;

struct Light
{
  vec4 worldPosition;
};
uniform Light lights[8];

#define LIGHT      0
uniform vec2 nearFarPlane;

void main()
{
  // distance to light
  float distanceToLight = distance(lights[LIGHT].worldPosition.xyz, w_pos.xyz);

  float resultingColor = (distanceToLight - nearFarPlane.x) /
           (nearFarPlane.y - nearFarPlane.x);

  gl_FragDepth = resultingColor;
  fragColor = vec4(1.0);
}</pre><p>Basically this encodes the distance from the surface point to the light in the form normalized depth information.  This is done by manually overriding the depth value stored in <em>gl_FragDepth</em>.  Each light has its own cubemap renderer with a custom-tailored shader like this (using the correct light index to compute distance from).</p>
<p>The per-fragment lighting shader code that utilizes the cube shadow maps looks like:</p><pre class="crayon-plain-tag">/*....*/

#define LIGHT 0
#define ATTENUATION

uniform samplerCubeShadow shadowMap;

/*.......*/

void pointLight0(in mediump vec3 normal, in mediump vec3 eye, in mediump vec3 ecPosition3)
{
  mediump float nDotVP;       // normal . light direction
  mediump float nDotHV;       // normal . light half vector
  //mediump float pf = 0.0;           // power factor
  mediump float attenuation = 1.0;  // computed attenuation factor
  mediump float d;            // distance from surface to light source
  mediump vec3  VP;           // direction from surface to light position
  mediump vec3  halfVector;   // direction of maximum highlights

  // Compute vector from surface to light position
  VP = vec3(lights[LIGHT].position) - ecPosition3;

#ifdef ATTENUATION
  // Compute distance between surface and light position
  d = length(VP);
#endif

  // Normalize the vector from surface to light position
  VP = normalize(VP);

  // Compute attenuation
#ifdef ATTENUATION
  {
    attenuation = 1.0 / (lights[LIGHT].constantAttenuation +
                         lights[LIGHT].linearAttenuation * d +
                         lights[LIGHT].quadraticAttenuation * d * d);
  }
#endif

  nDotVP = dot(normal, VP);
  mediump vec2 frontAndBack = vec2(nDotVP, -nDotVP);
  frontAndBack = max(vec2(0.0), frontAndBack);

  float visibility = 1.0;

  // difference between position of the light source and position of the fragment
  vec3 fromLightToFragment = lights[LIGHT].worldPosition.xyz - va_position.xyz;

  // normalized distance to the point light source
  float distanceToLight = length(fromLightToFragment);
  float currentDistanceToLight = (distanceToLight - nearFarPlane.x) / (nearFarPlane.y - nearFarPlane.x);

  // normalized direction from light source for sampling
  fromLightToFragment = normalize(fromLightToFragment);      
  visibility *= max(texture(shadowMap, vec4(-fromLightToFragment, currentDistanceToLight-shadowBias), 0.0), 0.0);

  //  if(nDotVP &gt; 0.0)
  {
    diffuse  += visibility*material.diffuse*lights[LIGHT].diffuse * frontAndBack.x * attenuation;
    diffuseBack += visibility*material.diffuse*lights[LIGHT].diffuse * frontAndBack.y * attenuation;
  }

  //if(lights[LIGHT].doSpec)
  {
    mediump vec2 cutOff = step(frontAndBack, vec2(0.0));

    halfVector = normalize(VP + eye);
    nDotHV = dot(normal, halfVector);
    frontAndBack = vec2(nDotHV, -nDotHV);
    frontAndBack = max(vec2(0.0), frontAndBack);

    lowp vec2 pf = pow(frontAndBack, vec2(material.shininess, material.shininess));
    specular += visibility*material.specular*lights[LIGHT].specular * pf.x * attenuation * cutOff.y;
    specularBack += lights[LIGHT].specular * pf.y * attenuation * cutOff.x;
  }

  ambient += lights[LIGHT].ambient * attenuation;
}</pre><p>Essentially the highlighted code above compares the distance between the surface point to the light to the stored depth value in the cube texture using the fragment-light vector as a lookup value into the cubemap.  Because we&#8217;re sampling using a special &#8220;shadow&#8221; version of the cubemap sampler, the result will be properly interpolated between shadow texels to avoid ugly edges between shadowed and non-shadowed areas.</p>
<p>Luckily, I was able to build this into the Verto Studio editor and associated graphics system and test this out with relatively little trouble.  Even though I have 4 or 5 statically rendered cubemap shadow textures in the entire scene.  I was able to keep performance high by building versions of the shaders for each side of the street so that each individual shader only has to shade with at most 3 lights at a time.  This worked out better than I had expected.</p>
<h2>Light-Fog Interaction (Volume FX)</h2>
<p>This part was tricky..  I had an idea in my head of how I wanted this to look.  So I did something that usually leads to trouble;  I tried to come up with a volume rendering technique on my own from scratch and implement it and just kinda see how it goes.</p>
<p>The basic idea stems from what I&#8217;ve observed in real life from foggy, dark, damp nights and lighting.  Essentially, fog at night is black&#8230; IF there is no light around to interact with the fog.  Naturally, if the water droplets don&#8217;t have any light to interact with them, you won&#8217;t see them and the fog will appear black.  However, if any light interacts with the water vapor in the air, it&#8217;ll create the illusion of a whiter colored and denser fog.  So this is what I set out to emulate with my shader.</p>
<p>Now atmospheric shader effects can often lead to the necessity of raymarching and heavy iteration in the fragment shader to simulate the accumulation of light-atomosphere interaction.  To this I said &#8220;hell no&#8221; since ray marching of any kind in a shader terribly robs performance.  I quickly realized that I could avoid raymarching entirely if I used a simple model to represent the light-fog interaction that I was going for.</p>
<p>In my case, it turned out I could do the whole effect using something as simple as a sphere intersection test.  Basically, when I&#8217;m shading a pixel (a point on the surface), I&#8217;m interested in what happens to the light on its way back from the surface to the viewer, the surface-to-viewer vector.  If the atmosphere affects the light at any point along this vector, I&#8217;ll need to compute that.  In other words, if the ray from the surface to the viewer intersects a sphere centered at the light, then the fog affects the light on the way back to the viewer.  How much?  Well if I calculate the length of the segment between the entry and exit points of the ray intersection (how much of the sphere the ray pierces), I find that length is proportional to both the perceived increase in density of the fog and the brightening of the fog color.</p>
<p>This algorithm is given below in fragment shader code:</p><pre class="crayon-plain-tag">/*.....*/

uniform float fogDensity;
uniform vec3 fogColor;

//sphere intersection
bool intersect(vec3 raydir, vec3 rayorig, vec3 pos, float radiusSquared, 
               out float innerSegmentLength)
{
   float t0, t1; // solutions for t if the ray intersects

   // geometric solution
   vec3 L = pos - rayorig;
   float tca = dot(L, raydir);

   //seems to be true if ray o is inside the sphere
   //we want this to be a positive..
   //if(tca &lt; 0) 
   //  return false;

   float d2 = dot(L, L) - tca * tca;
   if(d2 &gt; radiusSquared)
     return false;
   float thc = sqrt(radiusSquared - d2);
   t0 = tca - thc;
   t1 = tca + thc;

   innerSegmentLength = abs(t0-t1);

   return true;
}

vec4 computeFog(vec4 color)
{
  vec3 viewDirection = normalize(cameraPosition - vec3(va_position));

  vec3 surfacePos = ec_pos.xyz/va_position.w;
  const float LOG2 = 1.442695;
  float fogFactor = exp2(-fogDensity * length(surfacePos) * LOG2);  

  vec3 fogCol = fogColor;
  vec3 rayO = vec3(va_position);
  vec3 rayD = viewDirection;
  float len = 0.0;
  const float r = 80.0;

  //for each light we interact with...
  if(intersect(rayD, rayO, lights[LIGHT].worldPosition.xyz, r*r, len))
  {
    float d = len/r;
    float p = clamp(log(d)*d, 0.0, 1.0);
    fogCol = mix(fogColor, vec3(0.4), p);

    len = 0.0;
    const float innerR = 25.0f;
    if(intersect(rayD, rayO, lights[LIGHT].worldPosition.xyz, innerR*innerR, len))
    {
      float len10 = len/innerR;
      float nd = min(len10*0.25, 1.0);
      fogFactor *= mix(1.0, 0.0, nd);

      fogCol += mix(vec3(0.0), vec3(0.2), len10);
    }
  }

  if(intersect(rayD, rayO, lights[LIGHT1].worldPosition.xyz, r*r, len))
  {
    float d = len/r;
    float p = clamp(log(d)*d, 0.0, 1.0);
    fogCol = mix(fogColor, vec3(0.4), p);

    len = 0.0;
    const float innerR = 25.0f;
    if(intersect(rayD, rayO, lights[LIGHT1].worldPosition.xyz, innerR*innerR, len))
    {
      float len10 = len/innerR;
      float nd = min(len10*0.25, 1.0);
      fogFactor *= mix(1.0, 0.0, nd);

      fogCol += mix(vec3(0.0), vec3(0.2), len10);
    }
  }

  return mix(vec4(fogCol, 1.0), color, fogFactor);
}</pre><p>&nbsp;</p>
<p>I&#8217;m sure I&#8217;m not the first one to come up with this idea before, but it still did feel pretty cool to reason my way through a shading problem like this.  The visual result looks amazing.</p>
<p><span style="line-height: 1.714285714; font-size: 1rem;">The progress of this all is below in a gallery.  </span></p>

<a href='https://vertostudio.com/gamedev/?attachment_id=322' title='Screen Shot 2014-12-22 at 12.36.54 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-22-at-12.36.54-PM-150x150.png" class="attachment-thumbnail" alt="Screen Shot 2014-12-22 at 12.36.54 PM" title="Screen Shot 2014-12-22 at 12.36.54 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=323' title='Screen Shot 2014-12-22 at 2.21.58 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-22-at-2.21.58-PM-150x150.jpg" class="attachment-thumbnail" alt="Screen Shot 2014-12-22 at 2.21.58 PM" title="Screen Shot 2014-12-22 at 2.21.58 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=324' title='Screen Shot 2014-12-22 at 7.33.04 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-22-at-7.33.04-PM-150x150.jpg" class="attachment-thumbnail" alt="Screen Shot 2014-12-22 at 7.33.04 PM" title="Screen Shot 2014-12-22 at 7.33.04 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=325' title='Screen Shot 2014-12-24 at 11.33.34 AM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-24-at-11.33.34-AM-150x150.jpg" class="attachment-thumbnail" alt="Screen Shot 2014-12-24 at 11.33.34 AM" title="Screen Shot 2014-12-24 at 11.33.34 AM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=326' title='Screen Shot 2014-12-24 at 3.12.39 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-24-at-3.12.39-PM-150x150.jpg" class="attachment-thumbnail" alt="Screen Shot 2014-12-24 at 3.12.39 PM" title="Screen Shot 2014-12-24 at 3.12.39 PM" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=327' title='rendering'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/rendering-150x150.png" class="attachment-thumbnail" alt="rendering" title="rendering" /></a>

]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=319</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallax Occlusion Mapping &#8211; Advances in shader land</title>
		<link>https://vertostudio.com/gamedev/?p=290</link>
		<comments>https://vertostudio.com/gamedev/?p=290#comments</comments>
		<pubDate>Thu, 04 Dec 2014 05:16:02 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=290</guid>
		<description><![CDATA[Today was cool&#8230; at least the first part of it was, before I spend 5 hours tracking down a bug in some of the game code. I stumbled onto a pretty cool little article geared towards a very awesome technique called &#8220;parallax occlusion mapping&#8221;. This is essentially bump mapping with some extra samples taken at [...]]]></description>
			<content:encoded><![CDATA[<p>Today was cool&#8230; at least the first part of it was, before I spend 5 hours tracking down a bug in some of the game code.</p>
<p>I stumbled onto a pretty cool little article geared towards a very awesome technique called &#8220;parallax occlusion mapping&#8221;. This is essentially bump mapping with some extra samples taken at each pixel to provide a realistic depth (or parallax) effect to the surface. This provides the illusion of realistic surface detail all while shading a single polygon. The article was somewhat dated and targeted for Direct3D instead of OpenGL, but I was able to port it over to GLSL 150 for OpenGL 3.2.</p>
<p>Here&#8217;s the original article:<br />
<a title="Article" href="http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262" target="_blank"><span style="line-height: 1.714285714; font-size: 1rem;">http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262</span></a></p>
<div></div>
<p><span style="line-height: 1.714285714; font-size: 1rem;">And here&#8217;s my port of the shader code for anyone who is interested.</span></p><pre class="crayon-plain-tag">in highp vec4 position;
in mediump vec3 normal;
in mediump vec2 texcoord0;
in mediump vec3 tangent;

out mediump vec2 va_texcoord;

out mediump vec3 va_eye;
out mediump vec3 va_normal2;
out mediump vec3 va_light;

uniform mat4 modelViewProjectionMatrix;
uniform mediump mat4 modelViewMatrix;
uniform mat4 modelMatrix;
uniform mat4 modelMatrixInverse;
uniform mediump vec2 textureScale;
uniform mediump vec2 bumpScale;
uniform mediump mat3 normalMatrix;
uniform float shadowBiasFactor;
uniform vec3 cameraPosition;

uniform bool doNormalize;

#define LIGHT    4

struct Light
{
  mediump vec4 worldPosition;
};

#ifdef GL_ES
highp mat3 transpose(in highp mat3 inMatrix) 
{
  highp vec3 i0 = inMatrix[0];
  highp vec3 i1 = inMatrix[1];
  highp vec3 i2 = inMatrix[2];
  //highp vec4 i3 = inMatrix[3];

  highp mat3 outMatrix = mat3(
                 vec3(i0.x, i1.x, i2.x),
                 vec3(i0.y, i1.y, i2.y),
                 vec3(i0.z, i1.z, i2.z)
                 );
  return outMatrix;
}
#endif

uniform Light lights[8];

void main()
{
  vec3 P = (modelMatrix * position).xyz;
  vec3 N = normal;
  vec3 E = P - cameraPosition;
  vec3 L = -lights[LIGHT].worldPosition.xyz - P;

  //Compute transformed normal
  vec3 eyeNormal = normalize(normalMatrix * normal);

  //Pass transformed texcoord.
  va_texcoord = texcoord0*textureScale;

  vec4 nNormal = vec4(normalize(normal), 0.0);
  vec4 nTangent = vec4(normalize(tangent), 0.0);
  vec4 nBinormal = vec4(cross(nNormal.xyz, nTangent.xyz), 0.0);
  mat3 tangentToWorldSpace;
  tangentToWorldSpace[0] = (modelMatrix * nTangent).xyz;
  tangentToWorldSpace[1] = (modelMatrix * nBinormal).xyz;
  tangentToWorldSpace[2] = (modelMatrix * nNormal).xyz;

  mat3 worldToTangentSpace = transpose(tangentToWorldSpace);

  va_eye = E * worldToTangentSpace;
  va_normal2 = N * worldToTangentSpace;
  va_light = L * worldToTangentSpace;

  //Pass GL-transformed to vertex down pipeline
  gl_Position = modelViewProjectionMatrix * position;
}</pre><p>&nbsp;</p><pre class="crayon-plain-tag">#ifdef GL_ES
#extension GL_OES_standard_derivatives : require
#extension GL_EXT_shader_texture_lod : require
#endif

precision mediump float; 

in mediump vec2 va_texcoord;
in mediump vec4 ec_pos;

in mediump vec3 va_eye;
in mediump vec3 va_normal2;
in mediump vec3 va_light;

out vec4 fragColor;

#define LIGHT    4

//Prototypes
vec4 computeLight(in mediump vec3 normal, in mediump vec4 ecPosition, in lowp float alphaFade, out lowp vec4 otherSideColor, out lowp vec4 secondaryHighlight);

//Lights
struct Light
{
  mediump vec4 worldPosition;
};

uniform vec3 cameraPosition;
uniform Light lights[8];
uniform vec4 lightModelProductSceneColor;
uniform lowp sampler2D texture0;
uniform sampler2D bumpTexture;
uniform sampler2D heightTexture;

//uniform bool lightingEnabled;

const float fHeightMapScale = 0.02;
const int nMaxSamples = 32;
const int nMinSamples = 8;

void main()
{
  // Calculate the geometric surface normal vector, the vector from
  // the viewer to the fragment, and the vector from the fragment
  // to the light.
  vec3 N = normalize(va_normal2);
  vec3 E = normalize(va_eye);
  vec3 L = normalize(va_light);

  float fParallaxLimit = -length( va_eye.xy ) / va_eye.z;
  fParallaxLimit *= -fHeightMapScale;

  vec2 vOffsetDir = normalize(va_eye.xy);
  vec2 vMaxOffset = vOffsetDir * fParallaxLimit;

  int nNumSamples = int(mix(float(nMaxSamples), float(nMinSamples), dot(E, N)));
  float fStepSize = 1.0 / float(nNumSamples);

  vec2 dx = dFdx(va_texcoord);
  vec2 dy = dFdy(va_texcoord);

  float fCurrRayHeight = 1.0;
  vec2 vCurrOffset = vec2(0.0);
  vec2 vLastOffset = vec2(0.0);

  float fLastSampledHeight = 1.0;
  float fCurrSampledHeight = 1.0;

  int nCurrSample = 0;

  while(nCurrSample &lt; nNumSamples)
  {
    fCurrSampledHeight = textureGrad(heightTexture, va_texcoord+vCurrOffset, dx, dy).r;
    if(fCurrSampledHeight &gt; fCurrRayHeight)
    {
      float delta1 = fCurrSampledHeight - fCurrRayHeight;
      float delta2 = ( fCurrRayHeight + fStepSize ) - fLastSampledHeight;

      float ratio = delta1/(delta1+delta2);

      vCurrOffset = (ratio) * vLastOffset + (1.0-ratio) * vCurrOffset;

      nCurrSample = nNumSamples + 1;
    }
    else
    {
      nCurrSample++;

      fCurrRayHeight -= fStepSize;

      vLastOffset = vCurrOffset;
      vCurrOffset += fStepSize * vMaxOffset;

      fLastSampledHeight = fCurrSampledHeight;
    }
  }

  vec2 vFinalCoords = va_texcoord + vCurrOffset;
  vec4 vFinalNormal = texture(bumpTexture, va_texcoord + vCurrOffset);
  lowp vec4 vFinalColor = texture(texture0, vFinalCoords); //vec4(1.0);

  vFinalNormal = vFinalNormal * 2.0 - 1.0;

  vec3 vAmbient = vFinalColor.rgb * 0.1;
  vec3 vDiffuse = vFinalColor.rgb * max( 0.0, dot( L, vFinalNormal.xyz ) ) * 0.5;

  vFinalColor.rgb = vAmbient + vDiffuse;

  fragColor = vFinalColor;
}</pre><p>Some of this code is &#8220;massaged&#8221; by Verto Studio&#8217;s code converter when ran on mobile.  It&#8217;s definitely a pretty cool effect!  It requires 3 texture maps to work currently, a standard diffuse (color texture) map, a normal map, and a displacement or height map.  Lucky for me, there&#8217;s a sick little program called &#8220;crazy bump&#8221; for mac that can generate both normal maps and displacement maps from any standard diffuse texture map!</p>

<a href='https://vertostudio.com/gamedev/?attachment_id=291' title='crazy bump in action'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-03-at-9.12.16-PM-150x150.png" class="attachment-thumbnail" alt="crazy bump in action" title="crazy bump in action" /></a>
<a href='https://vertostudio.com/gamedev/?attachment_id=292' title='Screen Shot 2014-12-03 at 9.05.20 PM'><img width="150" height="150" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/12/Screen-Shot-2014-12-03-at-9.05.20-PM-150x150.jpg" class="attachment-thumbnail" alt="Screen Shot 2014-12-03 at 9.05.20 PM" title="Screen Shot 2014-12-03 at 9.05.20 PM" /></a>

<h2> WebGL demo</h2>
<p>For those who want to see the shader effect in action, I got a <a title="WebGL demo" href="http://vertostudio.com/pub/webgl/parallax/" target="_blank">WebGL demo</a> which runs on chrome and safari (firefox and IE don&#8217;t work).</p>
<p>It&#8217;s an expensive effect however, so I&#8217;m not sure yet if I can work it in for Driveby Gangster.  Either way, it&#8217;ll definitely be a nice little addition to the shader arsenal.  If I do actually put it into use, I hope to eventually add self-shadowing effects as well.</p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=290</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Things&#8230;</title>
		<link>https://vertostudio.com/gamedev/?p=208</link>
		<comments>https://vertostudio.com/gamedev/?p=208#comments</comments>
		<pubDate>Fri, 10 Oct 2014 22:40:17 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=208</guid>
		<description><![CDATA[Despite the activity on this blog, I&#8217;ve actually been quite hard at work on this game.  The last few days have been filled with quite a bit of shadow mapping optimization which has proven to be much more complicated than I originally thought.  Shadows are probably a good chunk of the reason why most people [...]]]></description>
			<content:encoded><![CDATA[<p>Despite the activity on this blog, I&#8217;ve actually been quite hard at work on this game.  The last few days have been filled with quite a bit of shadow mapping optimization which has proven to be much more complicated than I originally thought.  Shadows are probably a good chunk of the reason why most people go with pre-built game engines instead of developing their own, but I finally got shadows working reasonably well!</p>
<p><span style="font-size: 1rem; line-height: 1.714285714;">I&#8217;ve also spent quite a few days trying to get the frame rate up for the actual game by optimizing the rendering engine.  I&#8217;ve made some small strides here but honestly the main cost in terms of performance seems to be the grand total accumulation of just &#8220;alot of OpenGL api usage&#8221; to draw roughly 250 separate objects in the scene.  When I turn off the root call (entity render) for the entire scene, the framerate goes sky-high, but when I comment out smaller parts or optimize entire sections of code such as my prepare to draw methods (setting up uniform state), I get very small gains.  This leads me to throw up my hands and say &#8220;screw it&#8221; at least for awhile.  I get roughly 60 fps when close to buildings (thanks to occlusion queries) and about 30 when viewing the whole street on my Geforce 650 m card.  That&#8217;s going to have to be good enough for what should remain a small game project.  I really don&#8217;t want to get sucked into too much more low-level OpenGL </span>optimization<span style="font-size: 1rem; line-height: 1.714285714;"> for this project.  Surprisingly, my older laptop from 2009 gets 20 fps (still pretty decent) and the iPad Air gets a very decent rendering performance too.  Perplexing&#8230; but I&#8217;m all-around  pleased so I&#8217;m moving on from performance optimization for now&#8230;</span></p>
<p>After all this craziness, my next step is to finally start texturing the character model and making sure he still animates properly when textured.  My character artist wasn&#8217;t able to texture the model so now this falls onto me.  This hopefully shouldn&#8217;t be too bad.  I&#8217;m planning on doing the UV texturing within verto to avoid more problems with 3D file format conversion.  It should work out fine, as long as I make sure I absolutely do not modify the vertices of the model when I do the texturing, as this will break the references inside of the animation skeleton structures.  Fun stuff.  More to come soon&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=208</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The ways of shadows</title>
		<link>https://vertostudio.com/gamedev/?p=198</link>
		<comments>https://vertostudio.com/gamedev/?p=198#comments</comments>
		<pubDate>Mon, 06 Oct 2014 20:59:29 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=198</guid>
		<description><![CDATA[Ahh shadows.  I&#8217;ve been putting this off because lets face it, 3D shadow mapping is not frickin easy.  There are countless advanced algorithms for 3D shadow mapping to make shadows look as pretty as possible on our discrete-centric graphics hardware.  Some of them are crazy complicated and quite difficult to implement.  I&#8217;ve been messing around [...]]]></description>
			<content:encoded><![CDATA[<p>Ahh shadows.  I&#8217;ve been putting this off because lets face it, 3D shadow mapping is not frickin easy.  There are countless advanced algorithms for 3D shadow mapping to make shadows look as pretty as possible on our discrete-centric graphics hardware.  Some of them are crazy complicated and quite difficult to implement.  I&#8217;ve been messing around with 3D graphics programming for over 10 years now and let me say that shadows have always been just out of reach for me.  This week, I decided to put an end to that.</p>
<p>As a plan, I&#8217;ve decided to keep things as simple as possible.  I&#8217;m making a game here, not a game engine, so I wanted to get shadows working reasonably well, and get back to the game programming aspect of this project.</p>
<p>The basic outline of the simplest shadow mapping technique:</p>
<ul>
<li>Render the scene from the perspective of the infinitely far direction light (shadow pass) into a shadow-depth texture.</li>
<li>Render the scene normally using the depth-information from the shadow-depth texture to determine whether or not a particular pixel is visible to the light or not (in shadow or not).</li>
</ul>
<h2>The Shadow Pass</h2>
<p>Above, it sounds simple.  In practice, there are many caveats.  For starters, its absolutely critical to get the most of out of the &#8220;shadow-depth&#8221; texture in terms of resolution as possible.  Thus, when rendering the shadow pass, we want to contain the entire scene into the light&#8217;s view with the constraint that we show as much (are as zoomed in) as possible.  If we zoom in too little, we hurt the resolution of the shadow map.  If we zoom too much, we risk clipping the scene resulting in some shadows being lost.  Furthermore, we want to render this step with as simple of a shader as possible, to avoid unnecessary wasted computation on the GPU.</p>
<p>Going back to the optimal viewport containment (zooming) issue, this boils down to computing the optimal Ortho-box that the scene will be contained in.  We&#8217;ll use this box as the parameters to the ortho projection matrix given during the light/shadow rendering pass.  Optimally bounding the scene with this box <span style="line-height: 1.714285714; font-size: 1rem;">presents a problem due to the fact that the box is in light-view-space coordinates, and all of our scene bounding boxes are in world-space.  Trying to work through this last night, I resorted to pencil and paper.</span></p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/IMG_2294.jpg"><img class="size-large wp-image-199 alignnone" title="IMG_2294" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/IMG_2294-768x1024.jpg" alt="" width="625" height="833" /></a></p>
<p>The algorithm essentially involves grabbing the light&#8217;s &#8220;viewing&#8221; transformation which consists of a simple lookAt transform and applying it to the 8 corner vertices of the world-space bounding box of the entire scene.  Once I have these coordinates in light-view-space, hopefully a computation of a new axis-aligned bounding box of these 8 points will be the ortho-box I&#8217;m looking for.  It turns out, that this worked quite well.</p>
<p>The actual code of this algorithm ended up looking more like this..</p><pre class="crayon-plain-tag">if(lightPos.w == 0.0f)
  {
    float3 lightInvV = make_float3(lightPos.x, lightPos.y, lightPos.z);
    lightInvV = float3Normalize(lightInvV);

    mat4 depthViewMatrix = mat4MakeLookAt(boxPos.x+lightInvV.x, boxPos.y+lightInvV.y, boxPos.z+lightInvV.z, boxPos.x, boxPos.y, boxPos.z, 0, 1, 0);

    //transform the bounding region into light-space
    GrowableArray *boundingRegionVerts = [box generateVertices];
    [self applyTransform:depthViewMatrix toVerts:boundingRegionVerts];

    //calculate light-space extremma to properly bound the region in light-space
    //(axis-align the new region to light-space)
    Box3D *lightSpaceBox = [self calcLightSpaceBoundingRegionWithVerts:boundingRegionVerts];
    boxPos = lightSpaceBox.pos;
    boxSz = lightSpaceBox.dims;

    mat4 depthProjectionMatrix = mat4MakeOrtho(boxPos.x-boxSz.x/2, boxPos.x+boxSz.x/2,
                                               boxPos.y-boxSz.y/2, boxPos.y+boxSz.y/2,
                                               boxPos.z-boxSz.z/2, boxPos.z+boxSz.z/2);
    mat4 depthMVP = mat4Multiply(depthProjectionMatrix, mat4Multiply(depthViewMatrix, depthModelMatrix));    
    shadowMatrix = depthMVP;

    return depthMVP;
  }</pre><p>&nbsp;</p>
<p>Below is a sample result of a shadow pass done using my cheap and simple bounding algorithm ran on our street scene (vantage of the light).  Note that this is stored into a depth-component texture attached to the depth-attachment of an offscreen FBO.</p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/Screen-Shot-2014-10-06-at-10.21.29-AM.png"><img class="aligncenter size-large wp-image-200" title="Screen Shot 2014-10-06 at 10.21.29 AM" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/Screen-Shot-2014-10-06-at-10.21.29-AM-1024x887.png" alt="" width="625" height="541" /></a></p>
<p><span style="font-size: 1rem; line-height: 1.714285714;">Goooood.</span></p>
<h2>The Shadow-Application (main) Pass</h2>
<p>During the main rendering pass, I needed to modify my shaders to include the application of the shadows from the light-map.  Alongside the light-map texture, I needed the a variant of the same &#8220;MVP&#8221; model-view-projection used to transform a world-space position into projected light-view-space coordinates.  This matrix is commonly referred to as a &#8220;bias shadow matrix&#8221; because its optimized to express the result in a normalized texture-coordinate form that GLSL texture routines are expecting.  In short, it simply applies the lighting-transform, divides the coordinates by 2 and then shifts them by 0.5.</p><pre class="crayon-plain-tag">mat4 biasMatrix = make_mat4(
                                      0.5, 0.0, 0.0, 0.0,
                                      0.0, 0.5, 0.0, 0.0,
                                      0.0, 0.0, 0.5, 0.0,
                                      0.5, 0.5, 0.5, 1.0
                                      );          
          biasMatrix = mat4Multiply(biasMatrix, lightMatrix);</pre><p>Armed with the shadow matrix and the shadow map texture, I generate the needed shadow coordinate information in vertex shader.  I also compute a shadow bias to combat a well-known phenomenon known as &#8220;shadow acne&#8221; essentially caused by z-fighting from the shadowmap texture.  <span style="line-height: 1.714285714; font-size: 1rem;"> </span></p><pre class="crayon-plain-tag">struct Light
{
  /*....*/  
  mat4 biasShadowMatrix;
};

uniform Light lights[1];

in highp vec4 position;
in mediump vec3 normal;

out float shadowBias;
out vec4 shadowCoord;

void main()
{
  //Compute transformed normal
  vec3 eyeNormal = normalize(normalMatrix * normal);

  float cosTheta = dot(eyeNormal, normalize(lights[0].position.xyz));
  float bias = 0.005*tan(acos(cosTheta));
  shadowBias = clamp(bias, 0.0, 0.01);  
  shadowCoord = lights[0].biasShadowMatrix * position;

  //......
}</pre><p>Lastly, in the fragment shader, I sample the shadow texture to determine whether or not the shadow coordinate of the given fragment is visible or not to the light.  I can vary the visibility factor to be as dark or light as I want to achieve the desired effect.  Note that I&#8217;m using a shadow sampler here.  This special hardware sampler takes multiple samples of the shadow map for me and interpolates the results automatically to produce a smoother shadow edge.</p><pre class="crayon-plain-tag">uniform sampler2DShadow shadowMap;

in vec4 shadowCoord;
in float shadowBias;

void main()
{
  vec4 highlight = vec4(0.0);
  lowp vec4 color = vec4(1.0);

  float visibility = 1.0;

  //sample the shadow map to determine the shadow color (1.0 or 0.3, interpolated)
  vec3 coord = vec3(shadowCoord.xy, shadowCoord.z-shadowBias);
  visibility *= max(texture(shadowMap, coord), 0.3);

  vec4 lightColor = computeLight(normalize(va_normal), ec_pos, 1.0, lightColorOtherSide, highlight);
  color.a = material.alpha;

  color *= visibility;  
  fragColor = (gl_FrontFacing) ? color*lightColor : color*lightColorOtherSide;
}</pre><p>The results of all of this craziness is something quite nice.  Shadows casted in my scene that can lie across curved surfaces.  This was quite a bit of work but I think it&#8217;ll be quite worth it since now my graphics engine is shadow-capable.  Down the road I&#8217;d like to add point-light shadow capability via rendering into shadow cubemaps and general shadow capability for Verto Studio, but for now, directional light shadows satisfies the needs of my game project.</p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/Screen-Shot-2014-10-06-at-12.51.52-PM.jpg"><img class="aligncenter size-large wp-image-203" title="Screen Shot 2014-10-06 at 12.51.52 PM" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/10/Screen-Shot-2014-10-06-at-12.51.52-PM-1024x602.jpg" alt="" width="625" height="367" /></a></p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=198</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More of texturing day</title>
		<link>https://vertostudio.com/gamedev/?p=187</link>
		<comments>https://vertostudio.com/gamedev/?p=187#comments</comments>
		<pubDate>Tue, 23 Sep 2014 05:05:08 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[3D modeling]]></category>
		<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=187</guid>
		<description><![CDATA[Yesterday I worked quite a bit with my character animator Tyler Hurdle to get the animations properly exported from his modeling software into my graphics engine.  After much wrestling, I got the simple walk cycle loaded in and it looks awesome.   Things happened today.  Those things included me finishing up the texturing for the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I worked quite a bit with my character animator Tyler Hurdle to get the animations properly exported from his modeling software into my graphics engine.  After much wrestling, I got the simple walk cycle loaded in and it looks awesome.  <a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/walking.gif"><img class="aligncenter size-full wp-image-188" title="walking" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/walking.gif" alt="" width="320" height="366" /></a></p>
<p>Things happened today.  Those things included me finishing up the texturing for the Hotel.  I must say, it&#8217;s really starting to look good. I can&#8217;t imagine how it&#8217;s going to look once I add in the final shadowing and post-processing effects.  I didn&#8217;t take as many intermediate screenshots as I should have this time. So I only really have the final results of where I am at the end of today.  Nothing too-far out of the ordinary happened during the last steps of the texturing of the hotel besides me modifying the basic window shader effects to include partial transparency. I did this so that I could &#8220;cheat&#8221; with the interior shops of the hotel, modeling the interior as a simple gaussian-blurred backdrop which is partially of obscured by the semitransparent window.</p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/store-front1.jpg"><img class="size-large wp-image-189 aligncenter" title="store front" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/store-front1-1024x606.jpg" alt="" width="625" height="369" /></a></p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/hotel-roof-and-sign.jpg"><img class="aligncenter size-large wp-image-190" title="hotel roof and sign" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/hotel-roof-and-sign-1024x606.jpg" alt="" width="625" height="369" /></a></p>
<p>I also decided to get rid of the ugly default &#8220;sand&#8221; texture that I&#8217;ve been using for my background terrain.  I spiffied this up a bit with multitexturing effects using a detail texture which came out pretty awesome.</p>
<p><a href="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/desert-texture.png"><img class="aligncenter size-large wp-image-191" title="desert texture" src="http://vertostudio.com/gamedev/wp-content/uploads/2014/09/desert-texture-1024x604.png" alt="" width="625" height="368" /></a></p>
<p>After all this, the frame rate performance within the editor and the game started to both get really bad.  So I had to stop modeling and dive into some optimization once again.  Using instruments within xcode, I uncovered some horrors related to the terrible performance of objective-c&#8217;s NSString methods (namely stringWithFormat) which forced me to eliminate their usage and some of the more critical sections of the rendering engine&#8217;s code.  That alone, gained me another ten frames per second back and started getting me to question the viability of Objective-C for hardcore game engine development.  I sure hope Swift&#8217;s string methods are faster than Objective-C&#8217;s.</p>
<p>Continuing with optimization, I put off the long-needed step of sorting scene entities first by transparency, and then by material.  This helped me avoid unnecessary state changes which propagate to the shader and harm performance.  I also hard-coded a backface culling test which showed that I really need a per-model &#8220;cull backfaces&#8221; option within the editor.  All of this optimization added up quite a bit to bring my performance back up to a reasonable level.</p>
<p>All of this work today uncovered quite a few new bugs in the editor itself, so tomorrow will likely be spent fixing those&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=187</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The insanity that is OpenGL Occlusion Queries</title>
		<link>https://vertostudio.com/gamedev/?p=177</link>
		<comments>https://vertostudio.com/gamedev/?p=177#comments</comments>
		<pubDate>Wed, 17 Sep 2014 20:37:35 +0000</pubDate>
		<dc:creator>Michael Farrell</dc:creator>
				<category><![CDATA[Dev logs]]></category>
		<category><![CDATA[Driveby Gangster]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vertostudio.com/gamedev/?p=177</guid>
		<description><![CDATA[Intro So this morning is the first morning that I am working without a day job.  I must say its liberating&#8230;. but enough about that crap!  It&#8217;s time to get to work! This morning was a programming morning.  The considerable performance drop of my scene during my modeling efforts led me to investigate methods for [...]]]></description>
			<content:encoded><![CDATA[<h2>Intro</h2>
<p>So this morning is the first morning that I am working without a day job.  I must say its liberating&#8230;. but enough about that crap!  It&#8217;s time to get to work!</p>
<p>This morning was a programming morning.  The considerable performance drop of my scene during my modeling efforts led me to investigate methods for improving my scene&#8217;s rendering performance, both in the editor and in the game itself (since they both use the exact same rendering engine).  Back in the day, I used to laboriously accomplish this using frustum culling.  Frustum culling is a technique that uses a spatial data structure, an octree, to categorize the mesh objects in a scene into cubic regions, and then mathematically detect whether or not those regions are in the viewing volume (frustum) currently visible in the scene.  This technique works okay, but it&#8217;s a pain in the ass to implement and I&#8217;d rather not if I don&#8217;t absolutely need to.  Furthermore, it doesn&#8217;t handle the situation of occlusion, when a very large 3D object is in front of a smaller one, eclipsing it, making it entirely invisible and useless to render since it&#8217;ll fail the z-buffer test.</p>
<p>Thus, enters &#8220;occlusion queries&#8221;.  A very cool OpenGL technique which allows you query exactly how much of a 3D object was truly rendered, and decide whether or not to keep rendering it in the future.  This is exactly what I needed.  It all sounds great in theory, now let me tell you about some of the issues I had implementing it.  I&#8217;ll try to avoid some of the ugly Objective-C syntax that surrounds this code in my actual system in my snippets.</p>
<h2>Technique Overview</h2>
<p>So in practice, occlusion culling is quite simple.  There are basically 3 steps.</p>
<p>First, you must render the scene using very simple solid bounding-box geometry.  ie, for each discrete mesh object within your scene, you render a giant solid box that entirely bounds that object. You only render this box with a very simple flat-color shader which will keep your query render very fast.  You don&#8217;t actually want these boxes to appear in your scene, so you do this step with color buffer writes and depth buffer writes turned off (masks set to FALSE).</p>
<p>Next, you query the results of the above for each box rendered and determine which models were visible (not occluded).  You make a note of the ones that were.</p>
<p>Finally, you render the scene normally, with the extra check to ensure that you don&#8217;t render the model objects that were not visible.</p>
<h2>Setup</h2>
<p>So the first thing I needed was a single occlusion query per mesh object in my scene.  In OpenGL, these (like many things in GL) are GLuint ids.  I dropped these into my entity mesh class</p><pre class="crayon-plain-tag">//Per each model
  GLuint occlusionQuery;
  BOOL occluded;
  EntityMeshOcclusionState occlusionState; //hidden, visible, waiting</pre><p>Then, in the model init and dealloc code, I generate the query objects as needed.</p><pre class="crayon-plain-tag">//Init
glGenQueries(1, &amp;occlusionQuery);

//dealloc
if(occlusionQuery)
{
  glDeleteQueries(1, &amp;occlusionQuery);
}</pre><p><span style="line-height: 1.714285714; font-size: 1rem;">I then set up a special method that renders the solid bounding box geometry used during the occlusion query.  Now here&#8217;s where things get tricky.  There&#8217;s a way to do occlusion queries wrong (which I found out the hard way).  So much so that the performance benefit that they offer is entirely negated by the pipeline stalling that you can inadvertently cause.  Note the check against the </span><span style="line-height: 1.714285714; font-size: 1rem;">EntityMeshOcclusionWaiting state.  This will be explained in the next section.</span></p>
<p>&nbsp;</p><pre class="crayon-plain-tag">-(void) renderOcclusionQuery
{
  if(occlusionState != EntityMeshOcclusionWaiting)
  {
    occlusionState = EntityMeshOcclusionWaiting;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, occlusionQuery);
    [self renderSolidCubeBBox];
    glEndQuery(GL_ANY_SAMPLES_PASSED);
  }
}</pre><p></p>
<h2>Scene Rendering</h2>
<p>To kick this off, I added a new special method to my Scene class called <span style="line-height: 1.714285714; font-size: 1rem;">renderOcclusionQueries.  I then inserted a call to this method in my scene&#8217;s main render method like so.  Note the usage of glColorMask and glDepthMask to ensure the query bounding boxes don&#8217;t actually render to the screen.</span></p><pre class="crayon-plain-tag">-(void) render
{
  if(occlusionCulling)
  {
    [self renderOcclusionQueries];
  }

  //don't waste time if we don't need to
  if(![renderPassManager numberOfPasses])
  {
    [self renderSinglePass];
  }
  else
  {
    [renderPassManager renderAll:self];
  }
}

-(void) renderOcclusionQueries
{
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glDepthMask(GL_FALSE);

  [VGL modelViewLoadIdentity];

  //camera (viewing) transform
  [activeCamera apply];

  [VGL enableFlatSolidColorRendering:YES];
  [VGL setPrimaryColor:make_float4(1, 1, 1, 1)];

  for(Entity *entity in entities)
  {
    if(![self isMeshEntity:entity])
      continue;

    if(!entity.hidden &amp;&amp; ![entity.passRendererExclusions containsObject:[renderPassManager currentlyRenderingNode]])
    {
      [entity renderOcclusionQuery];
    }
  }

  [VGL enableFlatSolidColorRendering:NO];

  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glDepthMask(GL_TRUE);
}</pre><p>With the queries properly set up, I can now use them during my main rendering pass of all the entities to ensure I only draw whats necessary.  Again, this was tricky.  I had to absolutely make sure I never stall the pipeline.  No matter what.  This means I don&#8217;t retrieve a query result unless <span style="line-height: 1.714285714; font-size: 1rem;">GL_QUERY_RESULT_AVAILABLE is true.  If it isn&#8217;t, I leave the query in the &#8220;waiting&#8221; state.  I also don&#8217;t start a new query when it&#8217;s in the waiting state (note the check against this in the above entity </span><span style="font-size: 1rem; line-height: 1.714285714;">renderOcclusionQuery method).  This essentially means that the occlusion queries are entirely </span>asynchronous<span style="font-size: 1rem; line-height: 1.714285714;"> with respect to the main rendering.  </span></p><pre class="crayon-plain-tag">//main geoemetry rendering
  for(Entity *entity in entities)
  {
        if(occlusionCulling)
        {
          GLuint passed = INT_MAX;
          GLuint available = 0;

          glGetQueryObjectuiv(entity.occlusionQuery, GL_QUERY_RESULT_AVAILABLE, &amp;available);

          if(available)
          {
            passed = 0;
            glGetQueryObjectuiv(entity.occlusionQuery, GL_QUERY_RESULT, &amp;passed);
            entity.occlusionState = (passed) ? EntityMeshOcclusionVisible : EntityMeshOcclusionHidden;
            entity.occluded = (passed) ? NO : YES;
          }
        }
        else
        {
          entity.occlusionState = EntityMeshOcclusionVisible;
          entity.occluded = NO;
        }

        if(!entity.occluded)
        {
          [entity render];
        }
  }</pre><p>That&#8217;s pretty much all there is to it.</p>
<h2>Considerations</h2>
<p>Now aint nothin in this world fo free.  So there&#8217;s some things I should mention.  First, if I wasn&#8217;t also targeting iOS mobile, I would have probably used the OpenGL conditional rendering method which essentially does alot of the above checking for me automatically.  I noodled around with this and couldn&#8217;t get equivalently good performance so I just moved onto the manual way.  I also don&#8217;t like how I still have to submit all the expensive drawing &#8220;and non&#8221; drawing calls with conditional rendering and essentially trust the driver to do whats best.  My method ensures NOTHING is ran if the object isn&#8217;t visible.  With the downside being initiating readbacks from the OpenGL device back to the CPU.  However, I&#8217;m getting very decent performance with this so I&#8217;m happy.</p>
<p>Also, because the queries are truly async, I can get myself into trouble when running this code on very slow or buggy graphics cards (ahem.. intel..ahem).  The problem being, if the query takes too long, you may look at a space where an object should be, and not see it for a few frames while waiting for the query to catch up.  This finally explains to me why when playing some games on my wii u (such as call of duty), I sometimes turn real fast, and see an object suddenly appear a few frames late.</p>
]]></content:encoded>
			<wfw:commentRss>https://vertostudio.com/gamedev/?feed=rss2&#038;p=177</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
