<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8185650834667529493</id><updated>2012-01-25T22:32:43.641+01:00</updated><category term='techniques'/><category term='other'/><category term='Gamedev.pl'/><category term='debugging'/><category term='gameplay'/><category term='photography'/><category term='IGK'/><category term='games'/><category term='projects'/><category term='hdr'/><category term='algorithms'/><category term='common mistakes'/><category term='toolset'/><category term='photoshopping games'/><category term='site'/><category term='nGENE'/><category term='effects'/><category term='photomatix'/><category term='procedural'/><category term='diving'/><category term='agile'/><category term='tips'/><category term='video'/><category term='design'/><category term='macro'/><category term='work'/><category term='papers'/><category term='.NET'/><title type='text'>Wojciech Toman's devlog</title><subtitle type='html'>Blog about game and 3D engine programming, photography and diving</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default?start-index=101&amp;max-results=100'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>124</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8374203214144819791</id><published>2011-12-07T22:13:00.001+01:00</published><updated>2011-12-07T22:30:39.861+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>God rays - short video</title><content type='html'>In the last two posts I focused on the God rays effect (see &lt;a href="http://wtomandev.blogspot.com/2011/12/screen-space-god-rays.html"&gt;this&lt;/a&gt; and &lt;a href="http://wtomandev.blogspot.com/2011/12/god-rays-some-more-examples.html"&gt;this&lt;/a&gt;). This one will be the last related to this technique (currently I'm working on occlusion culling and vegetation so I will share my thoughts on these topics after finishing).&lt;br /&gt;In this short video you can see not only god rays but also improved clouds (again...) and some more serious movement of the water:&lt;br /&gt;&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="344" src="http://www.youtube.com/embed/NAXuxB-IVbc?fs=1" width="459"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8374203214144819791?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8374203214144819791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/12/god-rays-short-video.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8374203214144819791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8374203214144819791'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/12/god-rays-short-video.html' title='God rays - short video'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/NAXuxB-IVbc/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7048949583693732232</id><published>2011-12-03T15:44:00.001+01:00</published><updated>2011-12-03T15:51:01.186+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>God rays - some more examples</title><content type='html'>In the &lt;a href="http://wtomandev.blogspot.com/2011/12/screen-space-god-rays.html"&gt;previous post&lt;/a&gt; I described implementation of screen-space God rays. Here's the time to show some more screenshots:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-BHhbR3MYay0/Tto2cSTwf3I/AAAAAAAAFL0/GBRE8hwqfFc/s1600/WaterIGK+2011-12-02+00-29-48-43.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-BHhbR3MYay0/Tto2cSTwf3I/AAAAAAAAFL0/GBRE8hwqfFc/s320/WaterIGK+2011-12-02+00-29-48-43.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-G3pOJ9goS2E/Tto2j6m1AVI/AAAAAAAAFL8/VNtcC8hCm-M/s1600/WaterIGK+2011-12-02+00-43-07-20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-G3pOJ9goS2E/Tto2j6m1AVI/AAAAAAAAFL8/VNtcC8hCm-M/s320/WaterIGK+2011-12-02+00-43-07-20.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-bFs3__rLNCM/Tto2pc9RznI/AAAAAAAAFME/dnYS46GSZGs/s1600/WaterIGK+2011-12-02+00-44-41-39.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-bFs3__rLNCM/Tto2pc9RznI/AAAAAAAAFME/dnYS46GSZGs/s320/WaterIGK+2011-12-02+00-44-41-39.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-GKKn7A3SygE/Tto2yMayq0I/AAAAAAAAFMM/woyJfLPLCC0/s1600/WaterIGK+2011-12-02+00-53-09-66.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-GKKn7A3SygE/Tto2yMayq0I/AAAAAAAAFMM/woyJfLPLCC0/s320/WaterIGK+2011-12-02+00-53-09-66.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_6UG__kBNrs/Tto21pdYydI/AAAAAAAAFMU/HbhtdqlT_Mg/s1600/WaterIGK+2011-12-02+00-54-53-20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-_6UG__kBNrs/Tto21pdYydI/AAAAAAAAFMU/HbhtdqlT_Mg/s320/WaterIGK+2011-12-02+00-54-53-20.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-DREM9hpGg6M/Tto244vxv9I/AAAAAAAAFMc/vBui5_jPobE/s1600/WaterIGK+2011-12-02+00-56-15-54.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-DREM9hpGg6M/Tto244vxv9I/AAAAAAAAFMc/vBui5_jPobE/s320/WaterIGK+2011-12-02+00-56-15-54.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Ata3ySz_msM/Tto2-xz9hdI/AAAAAAAAFMk/phU1nIkBLic/s1600/WaterIGK+2011-12-02+00-58-37-82.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-Ata3ySz_msM/Tto2-xz9hdI/AAAAAAAAFMk/phU1nIkBLic/s320/WaterIGK+2011-12-02+00-58-37-82.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now I will work on dense vegetation creation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7048949583693732232?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7048949583693732232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/12/god-rays-some-more-examples.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7048949583693732232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7048949583693732232'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/12/god-rays-some-more-examples.html' title='God rays - some more examples'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-BHhbR3MYay0/Tto2cSTwf3I/AAAAAAAAFL0/GBRE8hwqfFc/s72-c/WaterIGK+2011-12-02+00-29-48-43.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-9098829906433828015</id><published>2011-12-02T01:01:00.001+01:00</published><updated>2011-12-02T08:43:17.261+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Screen-space God rays</title><content type='html'>&lt;em&gt;God rays &lt;/em&gt;(aka &lt;em&gt;light shafts&lt;/em&gt;, &lt;em&gt;light beams&lt;/em&gt;, &lt;em&gt;light rays&lt;/em&gt;)&amp;nbsp;are beautiful phenomenon caused by the light going through some medium denser than air&amp;nbsp;(like dust or smoke). Before going into details here's&amp;nbsp;my photo showing them in real life:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm6.staticflickr.com/5305/5775758518_cc0d85a7b5_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" mda="true" src="http://farm6.staticflickr.com/5305/5775758518_cc0d85a7b5_b.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are several approaches to render them. One of them, based on slicing volume with planes,&amp;nbsp;I described some time ago&amp;nbsp;&lt;a href="http://wtomandev.blogspot.com/2009/08/light-shafts.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This time inspired by my discussion with &lt;a href="http://blogvipa.blogspot.com/"&gt;Lukasz Zmijewski&lt;/a&gt;,&amp;nbsp;I decided to implement&amp;nbsp;God rays as a screen-space effect.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;First&amp;nbsp;of all,&amp;nbsp;it has to be mentioned that this effect is not a replacement for the other version. This one is more global and works best for sun rays outdoors. However, it is more difficult to use gobo (cookie) or animate it with noise. Also I don't think it would look good when used for indoor scenes.&lt;br /&gt;&lt;br /&gt;The idea behind this effect is straight-forward: take your scene and blur it using radial blur starting at screen-space sun position. Then blend the result additively with the scene.&lt;br /&gt;&lt;br /&gt;The only problem with such an implementation is that whole scene would be equally&amp;nbsp;blurred no matter the rays should be&amp;nbsp;visible at a given point&amp;nbsp;or not, ie. occlussion isn't taken into account.&amp;nbsp;However, this is very simple to fix and here are two possible solutions:&lt;br /&gt;&lt;br /&gt;1) render scene to the texture and output colour information only for objects which should be blurred (typically this would be the sky, sun and clouds) - output 0 (ie. black) for the rest of the scene (all occluders like terrain or trees),&lt;br /&gt;2) in case of deferred shading use G-Buffer contents. It can be material ID or some other characteristic&amp;nbsp;that says the object is&amp;nbsp;an occluder or not.&lt;br /&gt;&lt;br /&gt;I use second approach in my engine&amp;nbsp;and when blurring I check if the normal of the point is of zero length. I use&amp;nbsp;such normal vector&amp;nbsp;for objects not influenced by light (but which still needs to be rendered to the G-buffer) like the sky. If normal vector&amp;nbsp;length is larger than object is an occluder.&amp;nbsp;Not the best way I admit but works without problems.&lt;br /&gt;&lt;br /&gt;One more thing - in reality the rays are disappearing at some distance. This can be easily achieved by using linear or exponential decay factor.&lt;br /&gt;&lt;br /&gt;Here is the screenshot from nGENE showing this phenomenon in action:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://warsztat.gd/screens/8a46dcdb847364355c95639e3aa518bf.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" mda="true" src="http://warsztat.gd/screens/8a46dcdb847364355c95639e3aa518bf.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;It looks much better when moving (as the trees are waving slightly causing sun rays to move)&amp;nbsp;so I will try to upload short video soon (and maybe more screenshots as the rays look just incredible at sunset!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-9098829906433828015?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/9098829906433828015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/12/screen-space-god-rays.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9098829906433828015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9098829906433828015'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/12/screen-space-god-rays.html' title='Screen-space God rays'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5041852413634378045</id><published>2011-11-24T10:57:00.001+01:00</published><updated>2011-11-24T15:55:08.954+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Variance Shadow Mapping - theory and implementation</title><content type='html'>In &lt;a href="http://wtomandev.blogspot.com/2011/11/variance-shadow-mapping.html"&gt;my previous post&lt;/a&gt; I presented video from my implementation of VSM - &lt;i&gt;Variance Shadow Mapping&lt;/i&gt;. Today I will share theory and code behind it. You can find original paper and sources by Donnelly and Lauritzen &lt;a href="http://www.punkuser.net/vsm/"&gt;here&lt;/a&gt;.&lt;br /&gt;The technique is very simple yet it produces very nice and quite natural shadows. It can be considered a modification to standard shadow mapping.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;In shadow mapping it is normal to store depth value in a one channel floating-point texture like R32F. Then to produce soft shadows PCF (&lt;i&gt;Percentage Close Filtering&lt;/i&gt;) can be used on a full size shadow map to compute influence on the scene by sampling shadow map&amp;nbsp;around a given point n x n times (where n is a size of PCF kernel) and averaging the results. Although this technique has potential of producing very nice soft shadows it becomes very slow for larger n's.&lt;br /&gt;Variance shadow mapping in turn requires two channel texture (16- or 32-bit floating point). One of the channels stores depth value while the other stores depth squared. This allows to consider shadow map as not storing depth value but rather depth distribution.&lt;br /&gt;What we want is the average depth and average square depth. To obtain it we can blur the shadow map (using Gaussian blur or even simple box filter) or use filtering on it (eg. anisotropic). Having average values we can now &lt;a href="http://en.wikipedia.org/wiki/Variance"&gt;easily derive&lt;/a&gt; (E[X]) ^ 2 and E[X^2] from them. With both values calculated we can compute variances as:&lt;br /&gt;&lt;br /&gt;Var = E[X^2] - (E[X]) ^ 2.&lt;br /&gt;&lt;br /&gt;Then using Chebyshev's inequality we calculate p as:&lt;br /&gt;&lt;br /&gt;p = Var / (Var + (depth - E[x]) ^ 2)&lt;br /&gt;&lt;br /&gt;Then we use this value as shadowing factor, i.e. how much shadow is visible.&lt;br /&gt;&lt;br /&gt;Here's the code doing the last part:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float2 moments = tex2D(shadowMap, texCoord.xy).xy;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float mean = moments.x;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float meanSqr = moments.y;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float Ex_2 = mean * mean;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float E_x2 = meanSqr;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float variance = min(max(E_x2 - Ex_2, 0.0f) + shadowBias, 1.0f);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float m_d = (depth - mean);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float p = variance / (variance + m_d * m_d);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;return max(p, depth &amp;lt;= mean);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where depth is value we compare against value stored in the shadow map. In my case it is depth stored in the G-Buffer as I use deferred shading.&lt;br /&gt;&lt;br /&gt;So summing up there are just a few steps to be done to use Variance Shadow Mapping:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;div&gt;Calculate depth and depth * depth and store it in shadow map (2-channel 16- or 32-bit texture).&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Blur shadow map using a filter of your choice. It is also possible to down-sample shadow map prior to blurring.&lt;/li&gt;&lt;li&gt;Apply shadowing to the scene using snippet above.&lt;/li&gt;&lt;/ol&gt;And voila!&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5041852413634378045?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5041852413634378045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/11/variance-shadow-mapping-theory-and.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5041852413634378045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5041852413634378045'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/11/variance-shadow-mapping-theory-and.html' title='Variance Shadow Mapping - theory and implementation'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7152357083298569596</id><published>2011-11-23T17:39:00.001+01:00</published><updated>2011-11-24T10:57:17.316+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Variance Shadow Mapping</title><content type='html'>Variance Shadow Mapping (&lt;i&gt;VSM&lt;/i&gt; for short) is a very nice method of creating soft shadows. It's much faster than PCF as it use separable filter to achieve "blurring". Also it has potential of reducing artifacts. I will detail on this in the next post, today I would just like to share a short video showing my implementation:&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="344" src="http://www.youtube.com/embed/IapfTu5ceFU?fs=1" width="459"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7152357083298569596?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7152357083298569596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/11/variance-shadow-mapping.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7152357083298569596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7152357083298569596'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/11/variance-shadow-mapping.html' title='Variance Shadow Mapping'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/IapfTu5ceFU/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7883832238945889385</id><published>2011-11-18T16:23:00.001+01:00</published><updated>2011-11-19T22:09:57.024+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Vignetting</title><content type='html'>Vignetting is a pretty strange effect - it is about image being darker in the corners than it is in the middle. In photography it is considered undesirable feature of the lens (or simply defect ;) ) as it significantly reduces image quality. Cheaper lenses have higher vignetting, whilst more expensive ones have very limited one (or almost none). However, in the last few years black &amp;amp; white and vintage like post processing became very popular amongst photographers. As strong vignette is also considered vintage (because almost no of the current lenses have it at such extremes) it is present in many modern photos (quite a paradox, don't you think). So I decided to implement it for nGENE. Actually "implement" is a bit too big word here as it is done using following few lines of shader code:&lt;br /&gt;&lt;br /&gt;float vignetteStrength = 0.3f;&lt;br /&gt;float4 scene = tex2D(sceneTex, IN.texCoord);&lt;br /&gt; float4 colour = lerp(scene, vignetteColor, vignetteStrength * length(0.5f - IN.texCoord));&lt;br /&gt;&lt;br /&gt;It couldn't be simpler I guess :) Although it isn't perfect it works very nice and it works in the very same way I apply it to my photos.&lt;br /&gt;&lt;br /&gt;BTW I uploaded new screenshot from nGENE to Warsztat.gd:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://warsztat.gd/screens/f3579f6d3c127282178effc58bb56814.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://warsztat.gd/screens/f3579f6d3c127282178effc58bb56814.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7883832238945889385?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7883832238945889385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/11/vignetting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7883832238945889385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7883832238945889385'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/11/vignetting.html' title='Vignetting'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3399463298406433008</id><published>2011-11-13T15:54:00.001+01:00</published><updated>2011-11-15T22:38:32.047+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>I'm back - sort of</title><content type='html'>Long time no see. I haven't posted anything here for a few last months as I was very busy with a lot of stuff (work, moving to another flat and my thesis amongst other). However, for about a week now I'm developing nGENE again.Nothing really serious, some minor improvements, fixes of some graphical glitches and implementation of new tone mapping operators for the HDR pipeline. But after such a long break it's a real fun. I would love to finally play with DirectX 11 but I'm not sure if I will have time to implement new renderer from scratch.&lt;br /&gt;Moreover, I've recently came up with an idea for a simple game (at least in terms of graphics). I hope to start working on it very soon (actually it was what motivated me to introduce mentioned changes).&lt;br /&gt;Here is a short video showing some of the most recent graphical changes including:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;improved water (slightly more detailed),&lt;/div&gt;&lt;/li&gt;&lt;li&gt;improved clouds (they should appear at least a bit more natural),&lt;/li&gt;&lt;li&gt;improved HDR rendering (a few new tone mapping operators and addition of star effect),&lt;/li&gt;&lt;li&gt;addition of vintage like effects (I based them on photoshopping some of the photos).&lt;/li&gt;&lt;/ul&gt;I know the graphics are a bit out dated today but well... with such a long break it still isn't too bad I think (especially for the amateur ;) ).&lt;br /&gt;&lt;br /&gt;&lt;iframe allowfullscreen="1" frameborder="0" height="344" src="http://www.youtube.com/embed/jHGEufW-CLY?fs=1" width="459"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3399463298406433008?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3399463298406433008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/11/im-back-sort-of.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3399463298406433008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3399463298406433008'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/11/im-back-sort-of.html' title='I&apos;m back - sort of'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/jHGEufW-CLY/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7675471815481647246</id><published>2011-07-17T16:52:00.001+02:00</published><updated>2011-07-17T16:52:39.550+02:00</updated><title type='text'>Photomatix Pro 4.1 released!</title><content type='html'>Hi guys,&lt;br /&gt;&lt;br /&gt;as we officially released Photomatix Pro 4.1 yesterday (check it &lt;a href="http://www.hdrsoft.com/download/win.html"&gt;here&lt;/a&gt;) I should now finally have some time for working on my master thesis and nGENE. Hope to write something more soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7675471815481647246?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7675471815481647246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/07/photomatix-pro-41-released.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7675471815481647246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7675471815481647246'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/07/photomatix-pro-41-released.html' title='Photomatix Pro 4.1 released!'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-904431524348615765</id><published>2011-06-14T22:49:00.001+02:00</published><updated>2011-06-14T22:51:10.200+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><category scheme='http://www.blogger.com/atom/ns#' term='photomatix'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Photomatix Pro 4.1 Beta</title><content type='html'>Hi guys,&lt;br /&gt;&lt;br /&gt;I wasn't writing anything in the past few months as I was quite busy with both my work and studies (there is not much left with my studies luckily :) ) and didn't have time to work on nGENE at all. Sorry dudes.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Recently we released Photomatix Pro 4.1 beta at HDRsoft and you can download it &lt;a href="http://www.hdrsoft.com/download/beta/pmp41.html"&gt;here&lt;/a&gt;. There are numerous fixes and improvements in comparison to 4.0.x version and here are the most important ones (taken from HDRsoft site):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ability to select a region on the tonemapping/fusion preview and replace the region with a source photo - pretty cool feature, I've used it for this photo to remove artifacts in the sky:&amp;nbsp;&lt;a href="http://www.flickr.com/photos/wojtek_toman/5795994305/" title="Fields of Green by Wojtek Toman, on Flickr"&gt;&lt;img alt="Fields of Green" height="159" src="http://farm3.static.flickr.com/2523/5795994305_009f22ef57_m.jpg" width="240" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Improved automatic ghosting reduction: more ghosts removed and less artifacts&lt;/li&gt;&lt;li&gt;Addition of Sharpness setting to Fusion/Adjust method&lt;/li&gt;&lt;li&gt;Improvements to Fusion/Intensive method: several times faster and better result&lt;/li&gt;&lt;li&gt;Option to exclude perspective correction from alignment by matching features&lt;/li&gt;&lt;/ul&gt;Regarding the automatic ghosting reduction. It works so well in my opinion that I used it for most of my personal photos and most of the time at the moment and for most of them there were no problems (even though there was quite a lot of movement).&lt;br /&gt;&lt;br /&gt;As the summer is coming I hope to have more time and write some graphics related posts and work on nGENE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-904431524348615765?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/904431524348615765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/06/photomatix-pro-41-beta.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/904431524348615765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/904431524348615765'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/06/photomatix-pro-41-beta.html' title='Photomatix Pro 4.1 Beta'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2523/5795994305_009f22ef57_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-176572967324627917</id><published>2011-04-12T01:19:00.002+02:00</published><updated>2011-04-12T01:22:19.466+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'>How to avoid flickering in the Windows application?</title><content type='html'>If you have ever programmed a windows based application (level editor for instance) in .NET you probably encountered one serious problem - GUI flickering or some other artifacts with controls being not properly refreshed or painted when the form is being loaded. If not, probably your GUI was rather simple and you will come across it at some point :)&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;The common way of handling this is to enable double buffering of custom controls via following snippet:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this.SetStyle(ControlStyles.DoubleBuffer, true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this.SetStyle(ControlStyles.UserPaint, true);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is how you can enable automatic double buffering in your application.&lt;br /&gt;&lt;br /&gt;You can also try using:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;However, it still doesn't solve the issue in all cases. The biggest problems is with forms having many GUI elements (buttons, checkboxes etc.) and with level editor that is so easy to achieve.&lt;br /&gt;&lt;br /&gt;There is, however, a simple trick. Add following code to your form:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;protected override CreateParams CreateParams&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;get&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;CreateParams cp = base.CreateParams;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;return cp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What it does is something very simple - it enables double buffering at the level of a form (remember that previous snippet was about controls). Although it should be rather considered a trick as it only delays showing the form and doesn't speed up its rendering, it should be sufficient in most cases. Word of warning though - it might produce some drawing issues under Windows XP (eg. when minimizing a form) but how to get around this is described &lt;a href="http://angryhacker.com/blog/archive/2010/07/21/how-to-get-rid-of-flicker-on-windows-forms-applications.aspx"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-176572967324627917?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/176572967324627917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/04/how-to-avoid-flickering-in-forms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/176572967324627917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/176572967324627917'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/04/how-to-avoid-flickering-in-forms.html' title='How to avoid flickering in the Windows application?'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8012846258659545569</id><published>2011-04-08T12:09:00.000+02:00</published><updated>2011-04-08T12:09:25.676+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>A more interesting approach to black &amp; white</title><content type='html'>Just a few days ago I described the effect to achieve &lt;a href="http://wtomandev.blogspot.com/2011/04/vintage-look.html"&gt;a vintage look&lt;/a&gt; in the game. Today I will describe similar effect but it will join black &amp;amp; white and the vintage look techniques into one (a bit sepia like but as I don't like sepia very much I will describe something different). The problem with regular black &amp;amp; white is that it's rather cold in general. Cold images are not that pleasant for our eyes as warm images are. Vintage look effect can make the image warmer and make it more interesting and appealing. If you want to apply it be sure to take a look at the mentioned entry as this one will base on it.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Let's take a look at the base black &amp;amp; white image (with contrast already enhanced - I will write more on contrast enhancement and other filters like saturation or warmify in the consequent blog entries):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-aES5x619Yl8/TZ2XKbAVJfI/AAAAAAAAEwY/cIdqsTSKAqE/s1600/WaterIGK+2011-04-07+12-39-07-78.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-aES5x619Yl8/TZ2XKbAVJfI/AAAAAAAAEwY/cIdqsTSKAqE/s320/WaterIGK+2011-04-07+12-39-07-78.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;As you can see the image is rather dark and cold. Not really interesting to be honest. Boring and dull.&lt;br /&gt;&lt;br /&gt;And here is the same image with yellow and pink layers applied (using multiply and screen modes respectively):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-cEn2ICLT9VI/TZ2Xhkg6RRI/AAAAAAAAEwc/OJwlBM2gHXU/s1600/WaterIGK+2011-04-07+12-39-39-29.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-cEn2ICLT9VI/TZ2Xhkg6RRI/AAAAAAAAEwc/OJwlBM2gHXU/s320/WaterIGK+2011-04-07+12-39-39-29.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Much better but still not good enough but at least there is some atmosphere and feel now. The final step is to apply a warmify filter:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-v6w86tEwNhU/TZ2XsWH0YUI/AAAAAAAAEwg/lL90-nfjj14/s1600/WaterIGK+2011-04-07+12-39-47-31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-v6w86tEwNhU/TZ2XsWH0YUI/AAAAAAAAEwg/lL90-nfjj14/s320/WaterIGK+2011-04-07+12-39-47-31.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here is another example. Base high contrast black &amp;amp; white image (high contrast black and white images work best):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-7lxATFIvlEA/TZ2X3f51eDI/AAAAAAAAEwk/0iNGTst3MHY/s1600/WaterIGK+2011-04-07+12-41-39-91.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-7lxATFIvlEA/TZ2X3f51eDI/AAAAAAAAEwk/0iNGTst3MHY/s320/WaterIGK+2011-04-07+12-41-39-91.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And the one with the effect applied:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-BgBKrcIYD2o/TZ2X8p9TakI/AAAAAAAAEwo/bmpPECyPqrw/s1600/WaterIGK+2011-04-07+12-41-23-59.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-BgBKrcIYD2o/TZ2X8p9TakI/AAAAAAAAEwo/bmpPECyPqrw/s320/WaterIGK+2011-04-07+12-41-23-59.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I believe we are all used to regular black &amp;amp; whites and any other approach to it is more interesting. Besides we generally prefer warmer tones and hence the need to improve warmness of the b&amp;amp;w.&lt;br /&gt;&lt;br /&gt;How to warmify colours? Take a look at this &lt;a href="http://wtomandev.blogspot.com/2010/04/orange-teal-colour-grading.html"&gt;entry&lt;/a&gt;. The key is to apply curves adjustments. Actually applying a warmify filter stops the image to be in grayscale as you need to adjust especially red channel curve (by applying S-Curve or moving a midpoint). But the adjustments made are rather small and therefore the image is still close to being monochromatic.&lt;br /&gt;&lt;br /&gt;As you can hopefully remember from my entry on vintage look I applied there three layers: yellow, pink and blue. Although here I propose using yellow and pink layers only any combination of them might work depending on the desired effect and the input scene. In some of &lt;a href="http://wtomandev.blogspot.com/2011/04/slideshow-from-rome.html"&gt;my recent photos&lt;/a&gt; I used only yellow and there were some for which I used pink and blue or only blue. Just give a try all combinations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8012846258659545569?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8012846258659545569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/04/more-interesting-approach-to-black.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8012846258659545569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8012846258659545569'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/04/more-interesting-approach-to-black.html' title='A more interesting approach to black &amp; white'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-aES5x619Yl8/TZ2XKbAVJfI/AAAAAAAAEwY/cIdqsTSKAqE/s72-c/WaterIGK+2011-04-07+12-39-07-78.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1145727826821154575</id><published>2011-04-07T12:12:00.001+02:00</published><updated>2011-04-08T16:54:04.381+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Slideshow from Rome</title><content type='html'>Just a quick note on photography.&lt;br /&gt;&lt;br /&gt;This February I had a chance to visit Rome and spent there a few days (amazing city!). During this stay I took hundreds (thousands to be honest ;) ) of photos and here is the compilation of some of them I found the best. I would suggest watching it in HD as it reveals much more detail. There are a lot of different shot types: HDRs, architecture, panoramas, tilt-shifts, detail/texture and even a few nature shots. I hope you will like it!&lt;br /&gt;&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="344" src="http://www.youtube.com/embed/9od1VtLJNzM?fs=1" width="425"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1145727826821154575?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1145727826821154575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/04/slideshow-from-rome.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1145727826821154575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1145727826821154575'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/04/slideshow-from-rome.html' title='Slideshow from Rome'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/9od1VtLJNzM/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-169794927096157276</id><published>2011-04-05T15:04:00.006+02:00</published><updated>2011-04-07T10:51:18.131+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Vintage look</title><content type='html'>One of current trends in photography is trying to give a photo a vintage look. Not the black &amp;amp; white but rather pink &amp;amp; blue tone. With a photo editing suite it's just a matter of a few clicks. Recently I came up with an idea of porting this effect to HLSL as it is very interesting effect in my opinion (works very well not only to make image look older but also warmer).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Let's start with outlining the technique. In general we take a base photo and blend it with 3 layers in a following order:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Yellow (actually close to yellow one) one with multiply mode,&lt;/li&gt;&lt;li&gt;Pink one with screen mode,&lt;/li&gt;&lt;li&gt;Blue one with screen mode.&lt;/li&gt;&lt;/ol&gt;And here is a more detailed description:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Get the base photo.&lt;/li&gt;&lt;li&gt;Blend this photo with a color1 = {0.9843f, 0.9490f, 0.6392f} using multiply mode and using 0.59f factor.&lt;/li&gt;&lt;li&gt;Blend the result with a color2 = {0.9098f, 0.3960f, 0.7019f} using screen mode and using 0.205f factor.&lt;/li&gt;&lt;li&gt;Blend the result with a color3 = {0.0352f, 0.2862f, 0.9137f} using screen mode and using 0.17f factor.&lt;/li&gt;&lt;/ol&gt;Multiply blending mode should be obvious. It's implemented like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;result = lerp(source, source * dest, t);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Screen mode might be a bit less intuitive for those not familiar with Photo editing and here is the code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;result = lerp(source, (1.0 - ((1.0 - source) * (1.0 - dest))), t);&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And that's it. Almost :)&lt;br /&gt;&lt;br /&gt;Let's take a look at the example base image:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-3QcUQXo96sg/TZsRInee1sI/AAAAAAAAEvo/Ebp-KUTtpCs/s1600/WaterIGK+2011-04-05+14-34-53-76.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-3QcUQXo96sg/TZsRInee1sI/AAAAAAAAEvo/Ebp-KUTtpCs/s320/WaterIGK+2011-04-05+14-34-53-76.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In general applying described effect results in a low contrast image like the one below:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lSGD6_5C5gg/TZsRMDVoQBI/AAAAAAAAEvs/svnF_d3EMCI/s1600/WaterIGK+2011-04-05+14-34-56-00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-lSGD6_5C5gg/TZsRMDVoQBI/AAAAAAAAEvs/svnF_d3EMCI/s320/WaterIGK+2011-04-05+14-34-56-00.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So it is a good idea to apply a contrast enhancement filter and here is example result of applying it to the image above:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-d65BgY2Yvc4/TZsROubE14I/AAAAAAAAEvw/tPYsAgY0-PY/s1600/WaterIGK+2011-04-05+14-34-59-99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-d65BgY2Yvc4/TZsROubE14I/AAAAAAAAEvw/tPYsAgY0-PY/s320/WaterIGK+2011-04-05+14-34-59-99.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The photo definitely have a different look than the base one. You can note the pink and blue tones in the final image.&lt;br /&gt;&lt;br /&gt;It is also possible to use almost the same approach to have a warmer looking image. The only difference is to skip step no. 4 i.e. not applying blue layer. The results follow (contrast enhancement filter applied):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-iVDs59Auh5g/TZsUb9dAoqI/AAAAAAAAEwM/rr1T1TZBj-I/s1600/WaterIGK+2011-04-05+14-46-06-34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-iVDs59Auh5g/TZsUb9dAoqI/AAAAAAAAEwM/rr1T1TZBj-I/s320/WaterIGK+2011-04-05+14-46-06-34.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-uDJoQ8TDb9A/TZsUd_m_ynI/AAAAAAAAEwQ/ZZ7NdqKPzR8/s1600/WaterIGK+2011-04-05+14-46-56-22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-uDJoQ8TDb9A/TZsUd_m_ynI/AAAAAAAAEwQ/ZZ7NdqKPzR8/s320/WaterIGK+2011-04-05+14-46-56-22.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-vtqAHUCs924/TZsUm7HCU7I/AAAAAAAAEwU/3XlIhPdZpmM/s1600/WaterIGK+2011-04-05+14-42-57-57.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-vtqAHUCs924/TZsUm7HCU7I/AAAAAAAAEwU/3XlIhPdZpmM/s320/WaterIGK+2011-04-05+14-42-57-57.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Today I also committed a few fixes to the nGENE since I started writing my master thesis. More will come this week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-169794927096157276?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/169794927096157276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/04/vintage-look.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/169794927096157276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/169794927096157276'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/04/vintage-look.html' title='Vintage look'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-3QcUQXo96sg/TZsRInee1sI/AAAAAAAAEvo/Ebp-KUTtpCs/s72-c/WaterIGK+2011-04-05+14-34-53-76.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-614740210588386958</id><published>2011-03-24T11:40:00.000+01:00</published><updated>2011-03-24T11:40:20.733+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>My blog on photography</title><content type='html'>Hi again,&lt;br /&gt;&lt;br /&gt;I've just started my blog on photography. You can find it under&amp;nbsp;&lt;a href="http://www.hdrphotographer.blogspot.com/"&gt;http://www.hdrphotographer.blogspot.com&lt;/a&gt; (not much for now but expect some tutorials in the next few days). From now on I will upload photography related content only there (and on Flickr). This blog will turn into more technical one i.e. I want to restore its primary form. I hope it's a good decision :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-614740210588386958?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/614740210588386958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/03/my-blog-on-photography.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/614740210588386958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/614740210588386958'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/03/my-blog-on-photography.html' title='My blog on photography'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1936843525128940522</id><published>2011-03-23T11:15:00.001+01:00</published><updated>2011-03-23T11:17:06.873+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE as my master thesis</title><content type='html'>Hi all. I've been pretty busy in the last few months so there weren't many posts here (at HDRsoft we released &lt;a href="http://hdrsoft.com/download/pml_win.html"&gt;Photomatix Light 2.0&lt;/a&gt; during this period; it's a program for beginners in HDR photography).&lt;br /&gt;&lt;br /&gt;I also have some news regarding nGENE. I proposed a subject "&lt;i&gt;Design and implementation of 3D graphics engine for games and visualizations development&lt;/i&gt;" as my master thesis and it was accepted by my university. It means that I will finally have some time to work on nGENE. I will try to publish some technical entries about FX (I have a lot of ideas for new special effects with which I came while processing my photos), physics and architecture. I also hope to refactor large parts of it and implement some new features from scratch (I hope to finally play with DirectX 11). I also plan to release my master thesis once it is ready (although I will need to translate it to English).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1936843525128940522?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1936843525128940522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/03/ngene-as-my-master-thesis.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1936843525128940522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1936843525128940522'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/03/ngene-as-my-master-thesis.html' title='nGENE as my master thesis'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-748618096197947059</id><published>2011-01-03T13:05:00.000+01:00</published><updated>2011-01-03T13:05:26.995+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>New job and the end of adventure with GD?</title><content type='html'>I'm really happy to announce that for a few weeks now, I have a new job. I'm currently working as a Windows developer at the &lt;a href="http://hdrsoft.com/"&gt;HDRSoft&lt;/a&gt; company, authors of the Photomatix Pro I use personally for some time to do my HDR shots (all recently presented here are tonemapped using it) and which I mentioned in my posts and comments once or twice (and a few dozen times on Flickr), last time in my &lt;a href="http://wtomandev.blogspot.com/2010/10/hdr-photography-tutorial.html"&gt;tutorial&lt;/a&gt;. Actually I find it really satisfactory to work on a piece of software I use, I think that it's much more motivating and rewarding too than working on yet another web service you would never use for your personal work. At the same time I'm doing something really challenging this time as all image processing applications can be considered as such.&lt;br /&gt;&lt;br /&gt;I also gave a lot of thoughts to my potential future in the game development industry throughout last few months and I made my thoughts finally on that. Although I like games, I like playing them, making them is a real challenge and pleasure... but I don't want to do that for a living I think. The working conditions in the industry are rarely satisfactory (salary is one issue but long hours are much bigger for me). It doesn't mean that I won't write anything about graphics here anymore - no, in my spare time I hope to present some effects and techniques but what I mean is that I'm not pursuing GD career anymore. I also have plans to create some indie games in the nearest future and when I have more time (I'm also doing my Masters now) go back to nGENE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-748618096197947059?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/748618096197947059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2011/01/new-job-and-end-of-adventure-with-gd.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/748618096197947059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/748618096197947059'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2011/01/new-job-and-end-of-adventure-with-gd.html' title='New job and the end of adventure with GD?'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5636469600413721149</id><published>2010-12-02T17:16:00.001+01:00</published><updated>2010-12-02T17:18:02.775+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Two of my photos in Explore</title><content type='html'>Two of my photos have been recently Explored (i.e. they are in the daily top 500 according to their "interestingness") on &lt;a href="http://www.flickr.com/photos/wojtek_toman/"&gt;Flickr&lt;/a&gt;. The photos were taken around February but I've uploaded them a few days ago. Both of them are HDRs taken from 3 photos at -2, 0, +2 exposures and tone-mapped in Photomatix. These are:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;border:0;"&gt;&lt;a href="http://www.flickr.com/photos/wojtek_toman/5221825338/" title="Bridge over frozen river (EXPLORED) by Wojtek Toman, on Flickr"&gt;&lt;img alt="Bridge over frozen river (EXPLORED)" height="327" src="http://farm5.static.flickr.com/4114/5221825338_dca3f924c1.jpg" style="border: 0;" width="500" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;border:0;"&gt;&lt;a href="http://www.flickr.com/photos/wojtek_toman/5220641568/" title="Lonely trees (EXPLORED) by Wojtek Toman, on Flickr"&gt;&lt;img alt="Lonely trees (EXPLORED)" height="500" src="http://farm6.static.flickr.com/5085/5220641568_216dd35b9f.jpg" width="333" style="border: 0;"  /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5636469600413721149?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5636469600413721149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/12/two-of-my-photos-in-explore.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5636469600413721149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5636469600413721149'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/12/two-of-my-photos-in-explore.html' title='Two of my photos in Explore'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4114/5221825338_dca3f924c1_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1919529966944539026</id><published>2010-11-10T12:38:00.001+01:00</published><updated>2010-11-10T13:01:40.824+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Back to nGENE development</title><content type='html'>Hi everyone. I had quite a long break from nGENE programming. I was a bit tired I must admit so I had to take a few weeks break from developing it. The A.I.A.D. game got quite a lot of critique after releasing the previous trailers, it was proof to me that I'm not any good at higher level (gameplay) programming :) that's true I prefer low-level coding :) I will work on it for a short time and release the code afterwards. The aim is not to make very good game but rather to proove that one can make games with nGENE already (I fixed dozens of bugs and that was the most important I guess).&lt;br /&gt;&lt;br /&gt;I also started another project, at present it's very simple so there's nothing to show. It's a photo editing software (like GIMP or Photoshop you know). It turns out, it's quite simple and funny to do. Most of the tools and filters require no more than a few hours of work, some of them are quite challenging (I said it's funny :) ), a lot of maths is involved. Also the performance is crucial. When using GIMP for my larger photos it drives me mad when Gaussian Blur with radius set to ~50 takes sooooo much time :) some filters run for 5 and more minutes.&lt;br /&gt;&lt;br /&gt;I would also like to thank everyone on their positive feedback on my HDR photography tutorial. I'm really glad you like it. &lt;br /&gt;&lt;br /&gt;I'm also taking quite a lot of photos. I'm uploading them to Picasa no more but rather to Flickr. Here's some of them:&lt;br /&gt;&lt;br /&gt;&lt;iframe align="center" frameborder="0" height="500" scrolling="no" src="http://www.flickr.com/slideShow/index.gne?group_id=&amp;amp;user_id=46218677@N08&amp;amp;set_id=&amp;amp;text=" width="500"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;Created with &lt;a href="http://www.admarket.se/" title="Admarket.se"&gt;Admarket's&lt;/a&gt; &lt;a href="http://flickrslidr.com/" title="flickrSLiDR"&gt;flickrSLiDR&lt;/a&gt;.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1919529966944539026?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1919529966944539026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/11/back-to-ngene-development.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1919529966944539026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1919529966944539026'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/11/back-to-ngene-development.html' title='Back to nGENE development'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8899613171265184136</id><published>2010-10-08T13:26:00.008+02:00</published><updated>2010-10-13T10:37:25.114+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><title type='text'>HDR photography tutorial</title><content type='html'>&lt;div&gt;&lt;div&gt;With my recent appearance on &lt;a href="http://www.flickr.com/photos/wojtek_toman/"&gt;Flickr&lt;/a&gt; and uploading a bunch of my &lt;a href="http://www.flickr.com/photos/wojtek_toman/sets/72157624607480590/"&gt;HDR photos&lt;/a&gt; (and &lt;a href="http://www.flickr.com/photos/wojtek_toman/sets/72157624914562098/"&gt;B&amp;amp;W HDR photos&lt;/a&gt;) some people started to ask me questions like "&lt;i&gt;what software do you use for HDR?&lt;/i&gt;" or "&lt;i&gt;what settings do you use to achieve this effect?&lt;/i&gt;". I decided to write a tutorial on that to thank everyone on their positive feedback on my attempts. I'm definitely not a pro but I believe I got the HDR quite right and can share some thoughts on that.&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;div&gt;Answer to the first question is crucial as depending on the choice of software the results can be really different. I use &lt;a href="http://hdrsoft.com/"&gt;Photomatix Pro 4&lt;/a&gt; all the time. The other option to go is Photoshop CS 5 which have HDR support built-in. These are the most popular ways of doing HDR these days, one giving best results. I'm going with the first one for several reasons:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Photomatix Pro is a way cheaper (costs something like $100) than Photoshop,&lt;/li&gt;&lt;li&gt;Photomatix focuses on HDR whereas Photoshop is a whole image editing package, for further post-processing I simply use GIMP (somewhat limited but free),&lt;/li&gt;&lt;li&gt;some tests available on the net show that it outperforms Photoshop in the most of statistics (performance, results),&lt;/li&gt;&lt;li&gt;With release of version 4, Photomatix automated a lot of things, like noise reduction and reducing ghosting artifacts thus saving quite a lot of time.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;What is HDR?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Many people misunderstand concept of HDR (&lt;i&gt;High Dynamic Range&lt;/i&gt;). It's not a special effect in its very sense. It's just a way to hack our cameras sensors' and monitors' limitations. Although I have nothing against overdone HDR (provided it's done on purpose and with full awareness) but many beginners in HDR processing just don't understand what it's all about.&lt;br /&gt;&lt;br /&gt;The problem is the typical scene can have contrasts of 100.000:1 or even much higher. This ratio tells the difference between the brightest and darkest point of the scene. The contrast in reality is sometimes so high that even our eyes don't get all of it (try moving from very dark room to the open sunlit space - at first everything is just white then your eyes adapt to it but look back and the room seems to be completely black although just a while ago you could see all the details pretty well). The good example is a forest with a lot of shadows and sunlight coming through the leaves, or a dark cave from which we take photo of a very sunny outdoors. In other words our cameras cannot capture detail both in shadows and highlights and even if they could there is no monitor capable of displaying that wide range of contrast.&lt;br /&gt;&lt;br /&gt;HDR is just a trick. It uses wide contrast photo and maps it to this limited colour space of the monitor in the process known as tone-mapping. It improves contrast locally not globally as curves tool would do. Another example: try to shoot forest and clouds at the same time, you will either end up with overexposed sky&amp;amp;clouds or underexposed forest depending for what you set your exposure. One of the solution for this is to use ND graduation filter or use HDR. With HDR contrast for the clouds and forest will be enhanced locally so you will have them both properly exposed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Taking HDR photo&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Although you can tone-map a single RAW photo using Photomatix using multiple RAWs will definitely yield better results. Sometimes there is no other option so tone-mapping a single photo is definitely a useful feature:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm5.static.flickr.com/4138/4931114023_3b61aa4b08_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://farm5.static.flickr.com/4138/4931114023_3b61aa4b08_b.jpg" width="133" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You can also use multiple jpgs but you will be faced with all limitations of this format as normally. I usually take 3 photos with auto-bracketing at 2 EVs break. Using 3 photos is quite intuitive:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;1 goes for shadows,&lt;/li&gt;&lt;li&gt;1 for midtones,&lt;/li&gt;&lt;li&gt;1 for highlights.&lt;/li&gt;&lt;/ul&gt;In the most outdoor scenes 3 photos is enough but sometimes you may need 5, 7 or even more photos to get best results (especially when shooting indoors and showing outdoors, eg. through a window).&lt;br /&gt;&lt;br /&gt;I start with finding the best exposure for my midtones photo and then bracket it at 2 fullstops (2 EVs) hence I sometimes end up with exposures sequence like -3, -1, +1 instead of the most common -2, 0, +2 sequence.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Important thing to note: &lt;/b&gt;always shoot in &lt;i&gt;Aperture Priority &lt;/i&gt;or fully&lt;i&gt; Manual Mode&lt;/i&gt; (and change Shutter Speed value between the photos). The reason for that is you need to have depth of field stay the same between the photos, the results could get a bit weird if -2 photo would have aperture of f/11.0 and +2 photo would have f/2.8 :) crazy thing, isn't it :) ?&lt;br /&gt;&lt;br /&gt;Another thing to keep in mind is that HDR generally increases the noise in the image. So you have to reduce it as much as possible when shooting so &lt;i&gt;ISO 100 &lt;/i&gt;is a must in the majority of cases. You also have to have your photos perfectly aligned so shooting from a tripod is another thing you should consider, preferably using remote shutter release... OK, to be honest, I often shoot handheld in burst mode (~ 6 FPS helps a lot :) ) but shooting handheld using 10-22 mm lens at 10 mm most of the time is quite easy. Try it with 50 mm or longer lens and it's not that easy anymore :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Processing in Photomatix&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When you get to tone-mapping your photo in Photomatix you will be presented with quite a number of sliders. Photomatix offers a few ways of tone-mapping, I use &lt;i&gt;Tone Mapping -&amp;gt; Details Enhancer&lt;/i&gt; most of the time as it is the most flexible mode. If you have files (tiffs, jpgs) you edited before tone-mapping it might be a good idea to use &lt;i&gt;Exposure Fusion&lt;/i&gt; instead. Now I will give description of the most important options and give the values I use most of the time:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;strength - between 90 - 100 - as it is the strength of the effect. I like strong but still natural effect so high value is necessary.&lt;/li&gt;&lt;li&gt;colour saturation - between 50 - 80. Higher values in most cases result in overdone effect and I believe most of the guys use something like 100 :)&lt;/li&gt;&lt;li&gt;smoothing - medium or high (in light mode), sometimes very high, never anything else :) rarely I set it to 0 (when not in light mode). Lower values result in surreal effect and can also produce nasty halo artifacts.&lt;/li&gt;&lt;li&gt;gamma - between 1.10 and 1.40. For very dark images I set it to 0.8 - 0.9.&lt;/li&gt;&lt;li&gt;luminosity - change it only occasionally - it boosts/darkens details in shadows and brightens/darkens whole image.&lt;/li&gt;&lt;li&gt;microcontrast - values between 5 - 10 - higher values give the image sharper look and enhance local detail (useful when you have nice textures in your photo).&lt;/li&gt;&lt;li&gt;temperature: between 0.0 - 3.0. But I don't use high temp. values if the photo wasn't shot near the sunsets/sunrises as it works best for them. For a midday something like 1.0 - 1.5 works well for me. For winter scenes I also use positive values to create nice contrast as seen here:&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm5.static.flickr.com/4039/4319582031_6fcafea7e6_z.jpg?zz=1" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://farm5.static.flickr.com/4039/4319582031_6fcafea7e6_z.jpg?zz=1" width="133" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;saturation highlights and saturation shadows - this I tune to get best results (no golden advice), but in most of my photos saturation shadows is about -1, -0.5, sometimes even around -5 to get nice contrast between highlights and shadows and create nice definition for the subject which is usually well lit and thus have more highlights than background.&lt;/li&gt;&lt;li&gt;microsmoothing - I use defaults in most scenarios. Otherwise noise can get really ugly :) for some scenes I decrease it to around 0.5 - 1.0 when there are a lot of details (snow/sand looks best without smoothing).&lt;/li&gt;&lt;li&gt;other options I don't generally touch :) and don't know the reason for their very existence :)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Further processing&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Your photo at this stage might be finished or what is more probable requires further tweaks and improvements. In the most cases I need only to modify curves/levels a little bit and apply &lt;i&gt;Unsharp Mask&lt;/i&gt;. Sometimes it's also necessary to get rid of halo artifacts. When using Photomatix 3.2.9 and older a lot of work was required to get rid of ghosting artifacts too. Now this is hardly the case.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Example&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: small;"&gt;Let's take a look at the HDR photo I've uploaded &lt;a href="http://www.flickr.com/photos/wojtek_toman/5014864573/"&gt;recently&lt;/a&gt; to Flickr:&lt;/span&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm5.static.flickr.com/4150/5014864573_a0739244af_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://farm5.static.flickr.com/4150/5014864573_a0739244af_b.jpg" width="212" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Following bracketed photos were used for it:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div style="float: left;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7yjfJT7EI/AAAAAAAAEPU/g8YAXCbIZxA/s1600/Image00003.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7yjfJT7EI/AAAAAAAAEPU/g8YAXCbIZxA/s200/Image00003.jpg" width="133" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="float: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/TK7y0LrjYhI/AAAAAAAAEPY/k1h6hIkp0zw/s1600/Image00002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/TK7y0LrjYhI/AAAAAAAAEPY/k1h6hIkp0zw/s200/Image00002.jpg" width="132" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7y-WOzNGI/AAAAAAAAEPc/T_miITYFSmw/s1600/Image00001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7y-WOzNGI/AAAAAAAAEPc/T_miITYFSmw/s200/Image00001.jpg" width="133" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Here's some EXIF data for them:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Camera:&lt;/b&gt; Canon 50D&lt;br /&gt;&lt;b&gt;Lens:&lt;/b&gt; Canon EF-S 10-22 mm f/3.5-f/4.5&lt;br /&gt;&lt;b&gt;Focal length:&lt;/b&gt; 10 mm&lt;br /&gt;&lt;b&gt;Aperture:&lt;/b&gt; f/5.6&lt;br /&gt;&lt;b&gt;ISO:&lt;/b&gt; 400&lt;br /&gt;&lt;b&gt;HDR:&lt;/b&gt; 3 RAWs shot handheld (-2, 0, +2), tone-mapped in Photomatix Pro 4 Beta 10, fine-tuned in GIMP 2.6.10&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is how I set ghosted regions in the semi-automatic ghosting artifacts reduction:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7-d449XnI/AAAAAAAAEPg/m9GkhanR_5Q/s1600/01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TK7-d449XnI/AAAAAAAAEPg/m9GkhanR_5Q/s200/01.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;For each of the regions I used 0 EV photo to be used. This works best for me most of the time.&lt;br /&gt;&lt;br /&gt;I used following settings for tone-mapping:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;strength - 100&lt;/li&gt;&lt;li&gt;color saturation - 70&lt;/li&gt;&lt;li&gt;luminosity - 3.0&lt;/li&gt;&lt;li&gt;microcontrast - 7.0&lt;/li&gt;&lt;li&gt;smoothing - 1.0&lt;/li&gt;&lt;li&gt;gamma - 1.30&lt;/li&gt;&lt;li&gt;temperature - 2.0&lt;/li&gt;&lt;li&gt;saturation highlights - 3.0&lt;/li&gt;&lt;li&gt;saturation shadows - 0.0&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Rest of the options was set to defaults.&lt;br /&gt;&lt;br /&gt;After finishing processing this photo in Photomatix Pro, I opened it in GIMP and applied S-Curve to enhance contrast a bit. I also used Unsharp Mask to sharpen it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;B&amp;amp;W HDR&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Recently I take quite a lot of black and white HDR photos and it become more and more popular. Here is my example shot:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm5.static.flickr.com/4113/5059669905_821c7720c8_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://farm5.static.flickr.com/4113/5059669905_821c7720c8_b.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;To achieve that there are two options:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Desaturate photo in Photomatix,&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Desaturate photo during further processing&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;Both ways you can achieve similar results, starting with version 4 Photomatix Pro have built-in preset for B&amp;amp;W photos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Thoughts on fast moving objects&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Ok, most of the techniques described here work well for static scenes or ones with the slowly moving objects. What if there are fast moving objects? There are few options in such a case:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Create HDR from a single RAW - I used it a few times and the results were pretty good. The biggest advantage is you need no further processing. The biggest disadvantage is that your dynamic range is rather narrow (compared to 3 or more photos).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-size: small;"&gt;Create HDR from multiple RAWs and use semi-automatic deghosting in Photomatix Pro 4. In previous versions there is no such an option. You mark regions as potentially ghosted and select the photo to use for it. The process is the same as in the example above.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Create HDR from multiple RAWs and use no deghosting in Photomatix Pro - this is most difficult task as you will need to remove deghosting artifacts later on when processing photo in Photoshop/GIMP. This involves erasing parts of the photo and use your exposures photo as other layers. However, this way you can create more interesting blur effects.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8899613171265184136?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8899613171265184136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/10/hdr-photography-tutorial.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8899613171265184136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8899613171265184136'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/10/hdr-photography-tutorial.html' title='HDR photography tutorial'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4138/4931114023_3b61aa4b08_t.jpg' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7213357525297656548</id><published>2010-10-04T18:04:00.002+02:00</published><updated>2011-04-08T16:54:41.857+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>New video from the nGENE sample game</title><content type='html'>Recently I was a bit busy (I was once again away then spent something like one week post-processing my photos) but in the last few days I've been working on the A.I.A.D game I mentioned &lt;a href="http://wtomandev.blogspot.com/2010/09/aiad.html"&gt;here&lt;/a&gt; and &lt;a href="http://wtomandev.blogspot.com/2010/09/simple-game-using-ngene.html"&gt;here&lt;/a&gt;. I made a lot of improvements since the last video although the majority of them is not that obvious as they are mostly bug fixes and mechanics improvements. Regarding graphics I added a few special effects and a few more lights. I added also some sounds (be sure to turn your speakers on!). For this game I started to work seriously on the GUI and you can see the first version of it in this video:&lt;br /&gt;&lt;br /&gt;&lt;object height="444" style="background-image: url(http://i4.ytimg.com/vi/Ci3cEINVgZI/hqdefault.jpg);" width="550"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Ci3cEINVgZI?fs=1&amp;amp;hl=pl_PL"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/Ci3cEINVgZI?fs=1&amp;amp;hl=pl_PL" width="550" height="444" allowscriptaccess="never" allowfullscreen="true" wmode="transparent" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;I will go back to writing 'regular' entries in one to two weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7213357525297656548?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7213357525297656548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/10/new-video-from-ngene-sample-game.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7213357525297656548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7213357525297656548'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/10/new-video-from-ngene-sample-game.html' title='New video from the nGENE sample game'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7962610311339952346</id><published>2010-09-11T11:30:00.005+02:00</published><updated>2010-09-11T13:29:52.422+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>My photo to reach Exlore and Barcelona trip</title><content type='html'>On &lt;a href="http://www.flickr.com/"&gt;Flickr&lt;/a&gt; there's a special kind of ranking of all photos. It's called Explore. It includes 500 most interesting photos of a day (based on comments, views, faves, tags, title, everything). With thousands being uploaded every single minute it's a very small subset of what is added daily by the users. Really hard to get there. And I finally made it to get into it with this photo (view large if possible):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span id="goog_861834222"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://draft.blogger.com/"&gt;&lt;span id="goog_861834222"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/TItLJqBkmvI/AAAAAAAAEHc/xUgeonGt3eg/s320/DONE_IMG_0338.jpg" width="213" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;There are also some of my photos from trip to Barcelona available on Picasa, check them out:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5509833140227997249%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;br /&gt;This photo I consider to be one of my best so far:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/t2FmN9NYcgT7-qJMwwlVQw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_fbfW7HvrHa4/THbdb6Pt8YI/AAAAAAAAEDM/ZOuJfNQzCNA/s288/DONE_IMG_3563_HDR.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7962610311339952346?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7962610311339952346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/09/my-photo-to-reach-exlore-and-barcelona.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7962610311339952346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7962610311339952346'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/09/my-photo-to-reach-exlore-and-barcelona.html' title='My photo to reach Exlore and Barcelona trip'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/TItLJqBkmvI/AAAAAAAAEHc/xUgeonGt3eg/s72-c/DONE_IMG_0338.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3771996542924703230</id><published>2010-09-10T01:01:00.002+02:00</published><updated>2011-04-08T16:54:57.177+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>A.I.A.D.</title><content type='html'>As Inevitable As Death is a work title of the simple game I &lt;a href="http://wtomandev.blogspot.com/2010/09/simple-game-using-ngene.html"&gt;wrote about recently&lt;/a&gt;. The reason I'm writing again about that is that there's new video available. This time I improved existing weapons, added a few ones (eg. homing missiles), added a few new enemies and power-ups (slow-motion for instance), improved GUI a little, improved general graphics and physics, etc. A lot of changes also in the &lt;a href="http://ngene.wikidot.com/"&gt;nGENE&lt;/a&gt;. The progress is quite big I think :)&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="344" style="background-image: url(http://i2.ytimg.com/vi/I1CjHBqC3bE/hqdefault.jpg);" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/I1CjHBqC3bE?fs=1&amp;amp;hl=pl_PL"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/I1CjHBqC3bE?fs=1&amp;amp;hl=pl_PL" width="425" height="344" allowscriptaccess="never" allowfullscreen="true" wmode="transparent" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3771996542924703230?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3771996542924703230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/09/aiad.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3771996542924703230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3771996542924703230'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/09/aiad.html' title='A.I.A.D.'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8822336368184140878</id><published>2010-09-07T20:48:00.002+02:00</published><updated>2011-04-08T16:55:29.190+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>A simple game using nGENE</title><content type='html'>In one of the &lt;a href="http://wtomandev.blogspot.com/2010/09/selective-colouring-for-games.html"&gt;last posts I mentioned&lt;/a&gt; that I'm making a small game using &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech&lt;/a&gt;. It's a top-down scroll shooter (I said it's simple, didn't I :) ?). Currently there is some gameplay, now I'm working on the graphics, adding more weapons, power-ups and enemies, adding sound, GUI etc. What I'm trying to achieve is to use as many of the features as possible thus showing them. I don't mean all those fancy effects I implemented to now but rather usage of different modules ;)&lt;br /&gt;&lt;br /&gt;Here's a short video from an early version:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="344" style="background-image: url(http://i4.ytimg.com/vi/chXOlJUMRyE/hqdefault.jpg);" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/chXOlJUMRyE?fs=1&amp;amp;hl=pl_PL"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/chXOlJUMRyE?fs=1&amp;amp;hl=pl_PL" width="425" height="344" allowscriptaccess="never" allowfullscreen="true" wmode="transparent" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;It's really an early version, I'm working on it only 1 to 3 hours a day but there are many a days when I'm not coding a single line as I do a lot of photography related things recently (just discovered real power of &lt;a href="http://www.flickr.com/photos/wojtek_toman/"&gt;Flickr&lt;/a&gt; you know :) ) but it's a real fun to code even the simplest game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8822336368184140878?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8822336368184140878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/09/simple-game-using-ngene.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8822336368184140878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8822336368184140878'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/09/simple-game-using-ngene.html' title='A simple game using nGENE'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-181676557862974925</id><published>2010-09-06T13:57:00.001+02:00</published><updated>2010-09-06T13:58:12.456+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><title type='text'>Tilt-shift effect in Gimp</title><content type='html'>There is quite a buzz about tilt-shift technique in photography recently. It's all about creating small worlds. Not in the way as described in &lt;a href="http://wtomandev.blogspot.com/2010/06/two-new-tiny-planets.html"&gt;this entry&lt;/a&gt; though. From the proper photo you can make something like a plastic small-scale model. Tilt-shift lenses are pretty expensive (they are used eg. by architecture photographers), so the majority of photos are actually fake tilt-shift done in Gimp or Photoshop. Here's the photo I've just finished using the technique I'm just going to describe:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/TITTCyWDxOI/AAAAAAAAEHE/E1QYOPQAcPk/s1600/tilt_shift_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/TITTCyWDxOI/AAAAAAAAEHE/E1QYOPQAcPk/s320/tilt_shift_1.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Here are the steps to create such an effect:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Take/choose proper photo. What you need is a photo taken from some height as you want to make it look like a small-scale model. The example photo is Barcelona's port taken from the Montjuic Castle with an ultrawide Canon 10-22 mm lens at 10 mm and something like f/11.0 if I remember correctly.&lt;/li&gt;&lt;li&gt;Open the photo in Gimp and crop/tweak it if necessary.&lt;/li&gt;&lt;li&gt;Turn on Quick Mask mode by pressing Shift + Q.&lt;/li&gt;&lt;li&gt;With whole image gone red, select Gradient Tool and set its shape to the Bi-Linear.&lt;/li&gt;&lt;li&gt;Draw vertical line with the Gradient Tool. The line which you will draw is for the part which will be in focus, the rest will be blurred. To put it differently I drew this line in the part which is sharp.&lt;/li&gt;&lt;li&gt;Turn off Quick Mask and thus convert your quick mask to the selection.&lt;/li&gt;&lt;li&gt;Now select Filter -&amp;gt; Blur -&amp;gt; Gaussian Blur and set the radius which works best for your photo. Some people suggests using radius ranging 5 to 10. In the photo above I used as large as 30, however due to pretty high resolution.&lt;/li&gt;&lt;li&gt;Shift + Ctrl + A to deselect everything.&lt;/li&gt;&lt;li&gt;Probably now you will need to enhance curves and saturation of the photo. Exaggeration in this case is a good idea as we want to make it look like a plastic model. Hence I increased the contrast pretty much using curves tool and besides set the saturation (using Colors -&amp;gt; Hue-Saturation tool) to 25.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-181676557862974925?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/181676557862974925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/09/tilt-shift-effect-in-gimp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/181676557862974925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/181676557862974925'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/09/tilt-shift-effect-in-gimp.html' title='Tilt-shift effect in Gimp'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/TITTCyWDxOI/AAAAAAAAEHE/E1QYOPQAcPk/s72-c/tilt_shift_1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6508654255187151076</id><published>2010-09-04T14:03:00.000+02:00</published><updated>2010-09-04T14:03:10.511+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photoshopping games'/><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Selective colouring for games</title><content type='html'>Hi after some break :) Recently I'm busy with taking a lot of photos and coding a game using &lt;a href="http://ngene.wikidot.com/"&gt;nGENE&lt;/a&gt;. Very simple one, not the one I'm designing, but I will write about it in a few next days (I hope to post some screens then). This time I would like to introduce an effect originating from photography - selective colouring (or selective colour) and apply it to the a 3D game. It's another post in the series of &lt;a href="http://wtomandev.blogspot.com/search/label/photoshopping%20games"&gt;photoshopping games&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;The concept is very simple - make everything black&amp;amp;white, everything but the most important object of the scene. The subject. What's the purpose? It's simple, use of this technique has to make the subject stand out, attract attention to it. Therefore it's quite often used in ads, portraits and artistic photography. Here is the example photo I quickly post-processed in Gimp and applied this concept:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/TIIoftU2hjI/AAAAAAAAEGg/d2dRJG9C490/s1600/Image00001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/TIIoftU2hjI/AAAAAAAAEGg/d2dRJG9C490/s320/Image00001.jpg" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;But how to use it for games? That's terribly simple if you use deferred shading renderer. I make use of material buffer to makes things easier. If you are unfamiliar with this concept, here's the explanation. Apart from outputting regular information like depth/position, normals, diffuse and specular I also output material ID. Note that many of the data is constant for the whole material, some change over the surface (like diffuse colour or normal vectors). For those constant ones we can simply use an additional texture (material buffer) which holds them in a following way. Every row of this texture is one material. First row corresponds to the material with ID = 0, second one for material with ID = 1 and so on. Each of the columns in turn holds the specific data. First column can hold information about glow strength for instance, second one emission factor for HDR, etc. Thus we don't have to put it directly to the G-Buffer.&lt;br /&gt;&lt;br /&gt;And here we are. The effect is post-processing one of course. For a given pixel we check it's material ID and based on it, sample the material buffer texture at the given row ((material_ID + 0.5) / texture_height) and given column. As I store it in the first column it is: ((1 + 0.5) / texture_width). Depending on the value I desaturate the colour and output it. It's the case when the colour read from the material texture is black. In the other case (white colour) I simply output the colour from the frame buffer. And here's the final result from nGENE Toolset:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TII05S2l4yI/AAAAAAAAEGk/xoCL69XIldY/s1600/nGENE+Toolset+2010-09-04+13-56-45-52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TII05S2l4yI/AAAAAAAAEGk/xoCL69XIldY/s320/nGENE+Toolset+2010-09-04+13-56-45-52.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6508654255187151076?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6508654255187151076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/09/selective-colouring-for-games.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6508654255187151076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6508654255187151076'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/09/selective-colouring-for-games.html' title='Selective colouring for games'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbfW7HvrHa4/TIIoftU2hjI/AAAAAAAAEGg/d2dRJG9C490/s72-c/Image00001.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2437849307154071367</id><published>2010-08-15T11:15:00.000+02:00</published><updated>2010-08-15T11:15:57.488+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Policy-based design</title><content type='html'>There are numerous programming paradigms available for C++ programmers. One of my favourite ones which I use from time to time is a policy-based design. This paradigm makes good use of meta programming capabilities of C++ and although it might be possible to use it with other modern languages it would be much harder due to immaturity of generic programming in most of them and that is what this paradigm is based on. Also common lack of multiple-inheritance would be a bit problematic. Policy-based design extends reusability and flexibility of code. It can be seen as a compile-time version of the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;In this paradigm we have two kinds of classes - &lt;em&gt;policy classes&lt;/em&gt; (I will call them policies from now on) and &lt;em&gt;host classes&lt;/em&gt;. Policies are specifying behaviour, they are building blocks so to say. Host classes in turn can use these policies to achieve desired higher-level behaviour. For example we might have policies responsible for loading a mesh and drawing it. Concerning loading a mesh we can have policies for loading .3ds, .obj, .x and Collada files. Regarding drawing we might have classes for drawing it normally, using Level of Detail, etc. There is also a host class using those two types of policies to load and draw a mesh. Why policies are cool, is that we could mix any loading policy with any drawing policy and we will be able to load any mesh and draw it a way we want. Instead of creating a strange hierarchy of classes (a lot of inheritance relationships I guess) to provide so many options we could just simply use templates.&lt;br /&gt;&lt;br /&gt;That being said, we implement &lt;em&gt;host classes&lt;/em&gt; as template classes having at least as many template parameters as we want policies to be specified for it. To have more intuitive access to policy classes' methods we also derive from all the policies, eg.:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;template &amp;lt;typename Policy1, typename Policy2, ..., typename PolicyN&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;class A: public Policy1, public Policy2, ..., public PolicyN&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now it's pretty nice because if our class &lt;em&gt;A&lt;/em&gt; has a method called &lt;em&gt;someMethod()&lt;/em&gt; and &lt;em&gt;Policy1&lt;/em&gt; have &lt;em&gt;methodFromPolicy1() &lt;/em&gt;which we want to call from &lt;em&gt;someMethod()&lt;/em&gt; it'll look as simple as that:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;void A::someMethod()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; methodFromPolicy1();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;we thus require all policy classes implementing &lt;em&gt;Policy1&lt;/em&gt; to have a method named &lt;em&gt;methodFromPolicy1()&lt;/em&gt;. If it doesn't a compilation error will arise. BTW policy-based design is the only scenario, I can think of, for which multiple inheritance is useful :) or even necessary :)&lt;br /&gt;&lt;br /&gt;What's more we can of course specify default policies:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;template &amp;lt;typename Policy1=DefaultPolicy1, typename Policy2=DefaultPolicy2, ..., typename PolicyN=DefaultPolicyN&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;class A: public Policy1, public Policy2, ..., public PolicyN&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where &lt;em&gt;DefaultPolicy1, DefaultPolicy2, ..., DefaultPolicyN&lt;/em&gt; are classes defined somewhere in the code specifying default behaviour for our host class. It's useful if we know that default behaviour will be used in the majority of cases.&lt;br /&gt;&lt;br /&gt;When we instantiate our host class we can do something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;A &amp;lt;NonDefaultPolicy1&amp;gt; a;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;a.someMethod();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;if we want to specify a non-default behaviour. &lt;em&gt;someMethod()&lt;/em&gt; will of course call code from &lt;em&gt;NonDefaultPolicy1&lt;/em&gt; (according to the example earlier).&lt;br /&gt;&lt;br /&gt;One of the fundamental rules about policy-based design is that all policies which can be used for a given host has to be orthogonal (or close to be orthogonal because sometimes it's very hard to achieve that). What that means is that policies can't interfere with each other, i.e. one policy can't override or change behaviour of another policy. In other words each policy is not influenced by any other. They have to be completely independent. It is easiest to use in scenarios when we can divide behaviour of a class into several smaller tasks (like loading a mesh and drawing it in the example earlier) but it's not always the case.&lt;br /&gt;&lt;br /&gt;As you can see policies makes code more flexible, loading another 3D file format would only require providing new policy. Drawing it another way, would require another policy. Finally you can think of it as some form of divide &amp;amp; conquer strategy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2437849307154071367?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2437849307154071367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/08/policy-based-design.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2437849307154071367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2437849307154071367'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/08/policy-based-design.html' title='Policy-based design'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8548033859055866740</id><published>2010-08-01T01:08:00.001+02:00</published><updated>2010-10-08T14:53:51.967+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>My new DSLR</title><content type='html'>I've just switched from Canon 400D to Canon 50D and here is my opinion on the latter (the first one is in my opinion a very good camera - all my photos in the last few years were taken using it). The biggest difference at first is in weight and size. Canon 50D weights almost 1 kg (without lens attached) what compared to 0.5 kg of Canon 400D makes a huge difference. When you attach a heavy glass and external flash whole set becomes really heavy. But due to its weight when using some more heavy lenses (telezooms for instance) the set doesn't lean forwards (nor backwards) thus it's easier to work with it. It's also larger and more solid. It lays firmly in hand and the grip is very comfortable.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;One of its greatest advantages is it's very fast. With more than 6 photos in burst mode (compared to mere 3 in Canon 400D which also have shorter bursts) it's easier not to miss that very photo which will make you famous (one can dream, why not :) ?). ISO range is also quite impressive ranging from 100 to 3200 in native mode and with possible extensions (provided by camera firmware I guess) to 6400 and 12800.&lt;br /&gt;&lt;br /&gt;Auto-focus is also great. Fast, precise and recurrent. If your lens have front- or back-focus issues with this camera you can easily get rid of them (using micro adjustments).&lt;br /&gt;&lt;br /&gt;White balance is also doing its job well although as always yellow light causes some confusion to it and it fails in it. In most situations I'm shooting RAWs so I use it mostly to check if everything is more less ok on the camera LCD display (of pretty good quality) and set it afterwards during post-processing.&lt;br /&gt;&lt;br /&gt;There is also Live View mode (i.e. you can use LCD display to compose your photo instead of a viewfinder). Although I don't find it such a great feature it can be useful at times, I guess. For me especially when shooting landscapes with a viewfinder being covered with an eyecap (to prevent light entering through it messing with the carefully chosen exposure). As you can display a grid (two kinds available including&lt;a href="http://wtomandev.blogspot.com/2010/05/royal-baths-park-and-rules-of-thirds.html"&gt; the rule of thirds&lt;/a&gt;) it's very easy to have horizon perfectly aligned (eh horizontally I guess?). Also due to using up to 10x zoom in the Live View mode manual focusing becomes a straightforward task. Viewfinder is yet another story. It's large and covers 95% of the frame (this value is same as in Canon 400D), so composing the shot is much easier and more precise.&lt;br /&gt;&lt;br /&gt;Canon 50D offers pretty good tonal range and thanks to 15 mega-pixel matrix it produces images with a lot of details.&lt;br /&gt;&lt;br /&gt;Even built-in flash is much more powerful (although as Scott Kelby stated in one of his books: built-in flash is there only to ruin your photos) and can be useful as a fill-in flash.&lt;br /&gt;&lt;br /&gt;There are much more pros but they are described in details in a number of tests and reviews available online. The last I'm going to mention is reducing vignetting artifact (the corner of the frame are darker than its middle due to lens features). This artifact is especially visible for my Canon 10-22 mm f/3.5-f/4.5 USM lens and the 50D removes it almost completely (of course when shooting JPGs, with RAWs one can remove it using provided with the camera Digital Photography Professional tool).&lt;br /&gt;&lt;br /&gt;Here are some test photos taken with Canon 50D and Canon 50 mm f/1.8 lens:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5500207884185291521%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8548033859055866740?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8548033859055866740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/08/my-new-dlsr.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8548033859055866740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8548033859055866740'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/08/my-new-dlsr.html' title='My new DSLR'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3972641547331944070</id><published>2010-07-30T10:39:00.000+02:00</published><updated>2010-07-30T10:39:25.373+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Long time, no see</title><content type='html'>There was no info from me for quite a time. I had another break in nGENE Tech development, sorry to everyone for who it caused any troubles or problems. In a few days I'm taking 1 week vacation, after them I'll go back to nGENE programming at full power.&lt;br /&gt;&lt;br /&gt;A few months back I had an idea about a game. Now I started to turning this into something more. Currently I write a short design document to get me started, then I will code it. I have just some crazy (yet pretty simple) idea which I want to see in action (maybe it won't be very playable but seems interesting for me).&lt;br /&gt;&lt;br /&gt;Besides check my blog soon, I will post some interesting things (eg. about policies based design :) ).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3972641547331944070?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3972641547331944070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/07/long-time-no-see.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3972641547331944070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3972641547331944070'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/07/long-time-no-see.html' title='Long time, no see'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1440616904576130534</id><published>2010-06-27T19:07:00.001+02:00</published><updated>2010-06-27T19:08:02.465+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Changes once again and wildlife photograpy</title><content type='html'>For a few weeks now, I've been working as an iPhone Developer. I must admit I'm pretty amazed by this platform and even more by APIs provided by Apple (not by XCode - iPhone/iPad/OS X IDE - though, which is somewhat limited when compared to Visual Studio). At first Objective C caused some doubts as syntax is a bit weird (or really weird to be more exact) with square brackets and @'s characters all over the place but it turned out to be pretty easy to use and nice language.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Although I really can't understand why the calls are made this way:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;[someObject someMethod];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;instead of a more intuitive way:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;someObject.someMethod();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But it's still something to which one can get used to... after some time :) API itself is very elegant and flexible.&lt;br /&gt;&lt;br /&gt;Due to starting this job I was a bit short of time, however, soon I should be back with nGENE development (you know what it is to start new job, a lot of new things, everything seems to be strange).&lt;br /&gt;&lt;br /&gt;Meanwhile I took some photos in the Warsaw ZOO:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5487444260220036945%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;br /&gt;This photo:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/6ktTCZgL0nw1Dn_cU6coMA?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_fbfW7HvrHa4/TCdRfSHy5CI/AAAAAAAADeI/7d5GuhEV0d0/s400/DONE_IMG_0733.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I consider to be my best photo so far. Or one of the best :)&lt;br /&gt;&lt;br /&gt;All of the photos were taken in aperture priority mode using Canon 70-300 mm glass with ISO settings ranging 200 to 1600 (it was a cloudy day and I hadn't tripod with me so it was the only option to freeze motion... and many of these animals are just moving too much).&lt;br /&gt;&lt;br /&gt;You may notice that is another photography related entry in a row but it's due to lack of time. There are some unfinished entries about programming which I hope to publish in a few weeks (days?) from now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1440616904576130534?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1440616904576130534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/changes-once-again-and-wildlife.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1440616904576130534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1440616904576130534'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/changes-once-again-and-wildlife.html' title='Changes once again and wildlife photograpy'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_fbfW7HvrHa4/TCdRfSHy5CI/AAAAAAAADeI/7d5GuhEV0d0/s72-c/DONE_IMG_0733.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8042610402076334637</id><published>2010-06-18T18:51:00.001+02:00</published><updated>2010-06-18T18:53:01.272+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Warmia in Black&amp;White</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Warmia"&gt;Warmia&lt;/a&gt; is a beautiful area in the north east of Poland, full of lakes and dense forests. I shot a lot of photos there but this time the sky was completely gray so my plan to shoot some nice landscape photos with vivid colours had to be abandoned. Instead I decided on shooting some black &amp;amp; white and focus on smaller details, practice image compositing and giving certain feel to the photos. Without further ado, here it is:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5482749662377612769%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8042610402076334637?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8042610402076334637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/warmia-in-black.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8042610402076334637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8042610402076334637'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/warmia-in-black.html' title='Warmia in Black&amp;White'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5036285157354231134</id><published>2010-06-14T18:34:00.000+02:00</published><updated>2010-06-14T18:34:56.009+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Two new tiny planets</title><content type='html'>Some time ago I described photography technique known as &lt;a href="http://wtomandev.blogspot.com/2010/01/tiny-planet-technique.html"&gt;&lt;span id="goog_58737111"&gt;&lt;/span&gt;tiny planet&lt;span id="goog_58737112"&gt;&lt;/span&gt;&lt;/a&gt;. My first attempt at it wasn't that good to be honest but as I improve my skills both in photography and GIMP here is yet another attempt (two actually). This time I used photos which weren't panoramas (single photos shot with wide angle lens). The first was taken in Dahab, Egypt:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/IVa5RkzrZYJJsJev77PBtg?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_fbfW7HvrHa4/TBZWcaIqr-I/AAAAAAAADak/s6BsDHoL4Fg/s400/tiny_4.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And the second one in Royal Baths Park:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/4M59ebvAk5xC1-vBehVqjQ?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_fbfW7HvrHa4/TBZWcKUTOJI/AAAAAAAADag/hhBYIorRlyk/s400/tiny_3.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Using non-panoramic photos required heavy use of cloning, using brush and other tools but the final results are much better I believe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5036285157354231134?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5036285157354231134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/two-new-tiny-planets.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5036285157354231134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5036285157354231134'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/two-new-tiny-planets.html' title='Two new tiny planets'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_fbfW7HvrHa4/TBZWcaIqr-I/AAAAAAAADak/s6BsDHoL4Fg/s72-c/tiny_4.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1707455667686314506</id><published>2010-06-10T18:26:00.001+02:00</published><updated>2010-06-10T18:38:09.608+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='toolset'/><title type='text'>Visual Studio-like GUI in your apps</title><content type='html'>Have you ever wanted to make your tools resemble Visual Studio in terms of GUI? If yes is the answer for this question, then go on with reading. I will describe &lt;i&gt;WeifenLuo DockPanel control&lt;/i&gt; which makes it pretty simple to achieve. It's a fantastic and easy to use control, the only drawback of it is lack of documentation so to actually create something you either have to go through the sources of the control itself or of the provided sample (only one unfortunately). In nGENE Tech Toolset such a GUI is present since the first release. I'm writing this post because I've just updated it to the newest version available (namely 2.3.1). In case you don't know what I'm talking about here is a screenshot:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TBEJzTwVZhI/AAAAAAAADZg/NdsdW4xGI8o/s1600/toolset_dockpanel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TBEJzTwVZhI/AAAAAAAADZg/NdsdW4xGI8o/s320/toolset_dockpanel.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Everything is draggable, can be hidden (or auto-hiding can be enabled) etc. Exactly the same way you can do this in Visual Studio. It even looks very similar - the icons, the colours are all the same.&lt;br /&gt;&lt;br /&gt;You can download WeifenLuo DockPanel 2.3.1 from &lt;a href="http://sourceforge.net/projects/dockpanelsuite/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The best thing about this control is that if you already have toolset written in .NET framework it is very easy to adopt it. I will provide snippets of C++/CLI code to show the basic usage.&lt;br /&gt;&lt;br /&gt;Dockable windows have to derive from DockContent class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;public ref class frmErrorList: public WeifenLuo::WinFormsUI::Docking::DockContent&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;By deriving from DockContent class frmErrorList form gets several new properties. The list of the most useful ones is provided below:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;AllowEndUserDocking&lt;/i&gt; - if set to true then the window will be draggable,&lt;/li&gt;&lt;li&gt;&lt;i&gt;DockAreas&lt;/i&gt; - it's a combination of flags specifying where the window can be docked (top, bottom, left, right, float, document),&lt;/li&gt;&lt;li&gt;&lt;i&gt;TabText&lt;/i&gt; - text which will be visible on the tab.&lt;/li&gt;&lt;/ul&gt;Here is sample code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;AllowEndUserDocking = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;AutoScaleDimensions = System::Drawing::SizeF(6, 13);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;ClientSize = System::Drawing::Size(698, 210);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;Controls-&amp;gt;Add(this-&amp;gt;dgvLog);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;Controls-&amp;gt;Add(this-&amp;gt;tstMsgType);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;DockAreas = static_cast&amp;lt;WeifenLuo::WinFormsUI::Docking::DockAreas&amp;gt;((((WeifenLuo::WinFormsUI::Docking::DockAreas::Float&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;| WeifenLuo::WinFormsUI::Docking::DockAreas::DockTop) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;| WeifenLuo::WinFormsUI::Docking::DockAreas::DockBottom) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;| WeifenLuo::WinFormsUI::Docking::DockAreas::Document));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;Name = L"frmErrorList";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;ShowHint = WeifenLuo::WinFormsUI::Docking::DockState::DockBottom;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;Text = L"Error List";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;TabText = L"Error List";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What changes is how the windows are added and shown in the MDI form. You have to add a WeifenLuo::WinFormsUI::Docking::DockPanel control to your MDI form (which doesn't derive from any of the WeifenLuo controls, i.e. it's a regular WinForms form) and call its default constructor. Setting its parameters doesn't differ from the way it's done for other controls. Here's the code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;ActiveAutoHideContent = nullptr;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;AllowEndUserDocking = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;Dock = System::Windows::Forms::DockStyle::Fill;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;Location = System::Drawing::Point(0, 74);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;Margin = System::Windows::Forms::Padding(2);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;Name = L"dockManager";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;Size = System::Drawing::Size(1158, 456);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;TabIndex = 3;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;this-&amp;gt;Controls-&amp;gt;Add(this-&amp;gt;dockPanel);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where dockPanel is of type DockPanel. Then to show any child window, just call:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;frmErrorList-&amp;gt;Show(dockPanel);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Show() method has several overloaded variants of which this one can be useful too:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;frmErrorList-&amp;gt;Show(dockPanel, DockState::Document);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This way you can specify that frmErrorList is displayed as a document.&lt;br /&gt;&lt;br /&gt;It can also come in handy to save layout (eg. this way you can allow user to customize layout and restore it next time he starts the application) and then restore it. Saving it is straight forward - just call:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;SaveAsXml("layout.xml");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This way layout.xml file is created and you can load it next time.&lt;br /&gt;&lt;br /&gt;Restoring layout is a bit more complicated. You have to make following call:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;dockPanel-&amp;gt;LoadFromXml("layout.xml", deserializeDockContent);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;deserializeDockContent is of type DeserializeDockContent which is created this way:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;deserializeDockContent = gcnew DeserializeDockContent(this, &amp;amp;frmMDIForm::GetContentFromPersistString);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is example implementation of GetContentFromPersistString() method:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;WeifenLuo::WinFormsUI::Docking::IDockContent^ GetContentFromPersistString(System::String^ persistString)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;if (persistString == frmErrorList::typeid-&amp;gt;ToString())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; return frmError;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp;   &amp;nbsp; &amp;nbsp;return nullptr;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Implementing it this way requires you to allocate memory for frmError before making a call to LoadFromXML().&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1707455667686314506?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1707455667686314506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/visual-studio-like-gui-in-your-apps.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1707455667686314506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1707455667686314506'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/visual-studio-like-gui-in-your-apps.html' title='Visual Studio-like GUI in your apps'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/TBEJzTwVZhI/AAAAAAAADZg/NdsdW4xGI8o/s72-c/toolset_dockpanel.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1334846650319484600</id><published>2010-06-07T12:24:00.000+02:00</published><updated>2010-06-07T12:24:28.467+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE Tech going C#</title><content type='html'>I'm really excited to announce that thanks to Amer Koleci &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech&lt;/a&gt; is now available for the SlimDX and C#. I hope that in future it will be possible to use it with XNA and thus make games for XBox and Windows Phone 7.&lt;br /&gt;&lt;br /&gt;You can download it from &lt;a href="http://siriuz.net/~wtoman/nGENE/NGENE_SLIMX.rar"&gt;here&lt;/a&gt;, &lt;a href="http://rs281.rapidshare.com/files/396224029/NGENE_SLIMX.rar"&gt;here&lt;/a&gt; (RARed version) or &lt;a href="http://svn2.assembla.com/svn/ngene/xna/trunk/"&gt;get current version from SVN&lt;/a&gt; (SVN version misses media files). It comes with a simple demo. Hope you like it!&lt;br /&gt;&lt;br /&gt;For using it you will also need &lt;a href="http://slimdx.org/download.php"&gt;SlimDX runtime&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1334846650319484600?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1334846650319484600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/ngene-tech-going-c.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1334846650319484600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1334846650319484600'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/ngene-tech-going-c.html' title='nGENE Tech going C#'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3310501674357453354</id><published>2010-06-05T10:29:00.000+02:00</published><updated>2010-06-05T10:29:07.579+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Parallel task management</title><content type='html'>It took me a lot of time to make this decision (apart from long hours of thinking how to implement it actually). But I finally made it. I refactored &lt;a href="http://ngene.wikidot.com/"&gt;nGENE&lt;/a&gt; to make use of multi-threading/multi-core features in a more serious manner and thus speed up CPU part a bit. In this lengthy post I will try to describe in details approach I used which is heavily inspired by this &lt;a href="http://bitsquid.blogspot.com/2010/03/task-management-practical-example.html"&gt;post from Bitsquid creators&lt;/a&gt; and which can be called hierarchical task management system (HTMS for short :) doesn't it sound professional?).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;What pushed me to made such a decision was thinking about the nGENE. I found out that there are numerous parallelization opportunities. In scene graph each of the nodes at a given hierarchy level is completely independent from its siblings. That is to say we first have to update root node but then we can update all its children in parallel - there is no need to do it sequentially. Same stays true for any given node. But that's not everything. Animation controllers are also independent from each other. Same is true for quad/oct tree nodes (eg. visibility tests) and many other things. GUI/UI update can be performed at any time in parallel to such tasks as scene management or physics update - they don't have to wait for it. That would be a waste not to make use of it.&lt;br /&gt;&lt;br /&gt;I decided to go with the hierarchical task management as the name implies where beginning of one task can be dependent on completing several different ones. Furthermore, each of the tasks can have subtasks which have to be completed in order to complete their parent (mentioned scene graph update can be one big task with updates of all of its nodes being subtasks) and thus proceed with the next task in the flow. Therefore think of it as of the graph or even better - a flow.&lt;br /&gt;&lt;br /&gt;I also keep a pool of worker threads, each of them can perform any task ready for processing. Number of worker threads can be specified by user but by default it equals to a number of logical processors - 1 (this 1 is for main thread). If they have nothing to do they are put to sleep and awaken as soon as a new task arrives.&lt;br /&gt;&lt;br /&gt;Each of the tasks can have priority assigned to it. When there are idle worker threads they can perform tasks with the highest priorities in the open list first. When the task is finished it is removed from this active (or open) list and the next one available for processing (i.e. all its dependencies are resolved) is added to it.&lt;br /&gt;&lt;br /&gt;There is also main thread in which rendering and task scheduling is performed.&lt;br /&gt;&lt;br /&gt;Moreover, each of the tasks can have affinity specified if it is required to run a task on a given processor.&lt;br /&gt;&lt;br /&gt;Such an approach is good for several reasons. One of them is obvious - a lot of things are run in parallel what can result in higher performance (and my tests prove it so far). Besides it eliminates the need for explicit wait/signal calls. Also the flow is quite intuitive so I didn't need to make many changes - I just turned a few things into tasks. And that was it.&lt;br /&gt;&lt;br /&gt;This task scheduling theme will be available in nGENE in a few days with the next SVN commit. It will also contain a lot of bug fixes and minor improvements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3310501674357453354?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3310501674357453354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/parallel-task-management.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3310501674357453354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3310501674357453354'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/parallel-task-management.html' title='Parallel task management'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6498973868020472894</id><published>2010-06-01T10:53:00.002+02:00</published><updated>2010-06-01T18:39:47.751+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>Droplets photography</title><content type='html'>Yesterday it was raining... again. But soon after rainfall sun started to shine. That was a promise of some great photos. So I mounted my DSLR camera on tripod and went outside to shoot some droplets. I was lucky, I found a lot of cobwebs and grass blades covered with hundreds of tiny drops.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Shooting drops can be a bit tricky at first. Auto focusing of cameras doesn't work best on highly reflective objects (for instance drops, mirrors, glass, car's body). Turning to manual focusing mode is of course not a big problem (note that focus lock in most macro scenarios won't work as the differences in depth between object on which we locked and our subject are too big even if it's a mere few millimeters) but when you shoot close ups it becomes a bit of a problem (I didn't use macro lens but +10 dioptres filter lens - much cheaper you know). Having such a narrow perspective and shallow depth of field you have to be very (and I mean very!) precise and patient when turning focus ring. Going slightly too far will result in a completely blurry photo which is sometimes hard to tell from looking on the camera LCD.&lt;br /&gt;&lt;br /&gt;Besides everything seems to move (even if you get rid of hand shake by using tripod and use some sort of remote release) - grass is moved by the wind, the insects run and so forth. So there might be need to change focus between photos.&lt;br /&gt;&lt;br /&gt;I also used some post processing on the photos I'd taken, mainly contrast/brightness adjustments to add more depth and details to the photos but some of them were also processed using &lt;a href="http://wtomandev.blogspot.com/2010/05/orwig-technique.html"&gt;Orwig technique&lt;/a&gt; like in the photo below in which I used it to emphasize importance of drops a bit. If you look at the photo below with some care, you will see my camera in the nearer of the drops ;)&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/B8sQ515BxLUncLkJmUMGlA?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_fbfW7HvrHa4/TAPqndAA55I/AAAAAAAADYM/XM4ZQy-Sayc/s400/DONE_IMG_9252.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;tr&gt;&lt;td style="font-family: arial,sans-serif; font-size: 11px; text-align: right;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here goes the album with the rest of the photos:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5477479508550671873%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6498973868020472894?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6498973868020472894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/06/droplets-photography.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6498973868020472894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6498973868020472894'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/06/droplets-photography.html' title='Droplets photography'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_fbfW7HvrHa4/TAPqndAA55I/AAAAAAAADYM/XM4ZQy-Sayc/s72-c/DONE_IMG_9252.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3142784629377789774</id><published>2010-05-31T14:33:00.003+02:00</published><updated>2010-05-31T16:11:16.524+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Setting thread names for debugging</title><content type='html'>Just a short tip this time. When debugging multi-threading applications it would be a bit easier when threads in Visual Studio had names like "Main Thread", "Rendering Thread", "AI Thread" etc. It would save a few seconds of guessing what is what. As debugging MT apps is rather difficult task by itself every way of making the pain smaller is good :)&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Fortunately it's very easy. Just use following piece of code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;THREADNAME_INFO info;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   info.dwType = 0x1000;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;info.szName = thread_name;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   info.dwThreadID = -1;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   info.dwFlags = 0;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   __try&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;    RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD*)&amp;amp;info);&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   }&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   __except(EXCEPTION_CONTINUE_EXECUTION)&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;   {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yes, it's done by raising an exception.&lt;br /&gt;&lt;br /&gt;dwThreadID being -1 tells that we're setting the name of the current thread (i.e. one from which this code is called). You can specify another ID of course but for me it's quite a convenient way of doing this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3142784629377789774?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3142784629377789774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/setting-thread-names-for-debugging.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3142784629377789774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3142784629377789774'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/setting-thread-names-for-debugging.html' title='Setting thread names for debugging'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1940791540412498595</id><published>2010-05-30T15:28:00.002+02:00</published><updated>2010-09-04T12:04:46.600+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photoshopping games'/><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Orwig technique</title><content type='html'>The more familiar I got with GIMP (the post applies to Photoshop too :) ) and photography techniques, the more obvious for me it becomes that every graphics programmer should take some lessons in using it. Photoshop is a great source of various post-processing effects. Yesterday I came across tutorial about &lt;i&gt;Chris Orwig's technique&lt;/i&gt;. I'm not linking to it as it is Polish language material only. The photographer showed how to enhance the image using it. It's very simple and is useful especially in situations when there are several light sources (strong ones).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;There are several steps to perform:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Obtain base image.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Desaturate base image.&lt;/li&gt;&lt;li&gt;Blend base image with desaturated version using soft light blending mode.&lt;/li&gt;&lt;/ol&gt;First two steps are easy. 3rd one needs some explanation. According to some &lt;a href="http://www.nathanm.com/photoshop-blending-math/"&gt;materials&lt;/a&gt; I found over the web soft light blending mode is specified as follows:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;blended = (blend &amp;lt; 0.5f) ? (2.0f * base * blend + base * base * (1.0f - 2.0f * blend)) : (sqrt(base) * (2.0f * blend - 1.0f) + 2.0f * base * (1.0f - blend));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;base is the base image,&lt;/li&gt;&lt;li&gt;blend is the layer to blend with.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;Here is source image&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TAJnR9XWerI/AAAAAAAADXI/ea1A2qH_l1w/s1600/nGENE+Toolset+2010-05-30+15-24-27-84.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TAJnR9XWerI/AAAAAAAADXI/ea1A2qH_l1w/s320/nGENE+Toolset+2010-05-30+15-24-27-84.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The source image is pretty dull and due to the brightness of light source in the background everything else becomes less visible. Not much of contrast so we're loosing a lot of details. Below is the image with the Orwig effect applied.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/TAJnW2B_pWI/AAAAAAAADXQ/d056IeFpoOE/s1600/nGENE+Toolset+2010-05-30+15-24-33-19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/TAJnW2B_pWI/AAAAAAAADXQ/d056IeFpoOE/s320/nGENE+Toolset+2010-05-30+15-24-33-19.png" /&gt;&lt;/a&gt;&lt;/div&gt;It is good idea to apply it to the scenes with characters to emphasize their presence. Sometimes it can be useful to restore some of the colours but that is subject for another entry.&lt;br /&gt;&lt;br /&gt;Below is the photo without Orwig effect applied:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/TAJt4_Lz6jI/AAAAAAAADXY/AB8mKw6jrqc/s1600/pre_DONE_IMG_6854.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/TAJt4_Lz6jI/AAAAAAAADXY/AB8mKw6jrqc/s320/pre_DONE_IMG_6854.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;And with it:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/TAJuDur3E0I/AAAAAAAADXg/2dJuoZwIpQ4/s1600/DONE_IMG_6854.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/TAJuDur3E0I/AAAAAAAADXg/2dJuoZwIpQ4/s320/DONE_IMG_6854.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;To make this photo better the goat should have its colours back (it is easy to do that by adding mask layer to the grayscale image).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1940791540412498595?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1940791540412498595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/orwig-technique.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1940791540412498595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1940791540412498595'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/orwig-technique.html' title='Orwig technique'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/TAJnR9XWerI/AAAAAAAADXI/ea1A2qH_l1w/s72-c/nGENE+Toolset+2010-05-30+15-24-27-84.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2726138136396572932</id><published>2010-05-29T14:49:00.002+02:00</published><updated>2011-04-08T16:58:44.669+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Time lapse photography</title><content type='html'>Time lapse photography or time lapse movies are what their names imply. This technique of photography can be described as the 'fast-forward' of time. You have to take a lot of photos (probably a few hundred or thousand) and then build the movie from them by putting them in order in which they were taken (eg. in the Movie Maker). Each of the photos is a single frame of a movie so with 30 frames per second you will need as many as 150 photos for a short 5 seconds movie (with Movie Maker you can have only 8 frames per second unfortunately! with Movie Maker Live it's even worse)! And there are time lapse movies lasting for many minutes. To have smooth and constant speed of movement it is required that photos are taken in the same interval (let's say every 10 seconds).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;It should be obvious that sturdy tripod has to be used to avoid any shake between the photos. Besides you probably want to set your camera to manual mode (also focusing should be done manually in many cases). This will ensure that your photos won't change colours/white balance/sharpness due to changing lighting conditions (eg. clouds can appear at some moment and that would cause camera light meter to behave differently than it was at the beginning when the sun was shining) or subject movement.&lt;br /&gt;&lt;br /&gt;Besides I used remote shooting from my laptop (using Canon software and having my DSLR connected via USB). This is for three reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I'm thus sure that interval won't change between the photos - I mean when shooting manually I would have to use timer and for sure I will shoot some photos too early or too late,&lt;/li&gt;&lt;li&gt;With hundreds of photos I would soon run out of memory (I shoot mostly hi-res RAWs). Remote shooting enables you to save photos directly to your hard drive,&lt;/li&gt;&lt;li&gt;It's more convenient. With everything set up I was able to do something completely different like surfing the net.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;Canon users can use some free Canon utilities (eg. EOS Utility) which provides remote shooting.&lt;br /&gt;&lt;br /&gt;Below you can see the example time lapse I took today:&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fel0w67DpTI&amp;hl=pl_PL&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fel0w67DpTI&amp;hl=pl_PL&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;These 16 seconds are fast-forward of two hours. The subject is &lt;a href="http://en.wikipedia.org/wiki/Selaginella_lepidophylla"&gt;Selaginella lepidophylla&lt;/a&gt; - amazing desert plant. Which can survive many months without a single drop of water! I know the example is not perfect but for me it was just the first attempt. I had to move both the subject and the tripod because some shadows appeared at some time which made everything too dark.&lt;br /&gt;&lt;br /&gt;The most impressive piece of work I've ever heard of was time lapse of two years of forest life! That's really amazing and what a sacrifice! Around the web you can also find some wonderful time lapse combined with light graffiti technique.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2726138136396572932?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2726138136396572932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/time-lapse-photography.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2726138136396572932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2726138136396572932'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/time-lapse-photography.html' title='Time lapse photography'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3222666520975500399</id><published>2010-05-24T15:00:00.006+02:00</published><updated>2011-04-08T16:56:13.366+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Heat &amp; Haze effect</title><content type='html'>Heat &amp;amp; haze effect (or simply heat haze which seems to be more proper term even though the first one is more frequently used in regards to RT graphics) is the effect caused by the difference in air temperatures along the view vector. As the light from the object travels to the observer it is reflected and refracted differently by those different medias (reflection is of course caused by particles present in the air). If the air moves slightly (you know warm air travels up and cooler travels down) it can cause shimmering of some objects in the distance. Of course it is only visual impression. This effect can be noticed above hot ground (especially asphalt or scorched desert sand which can cause appearance of mirages) in summer when air seems to float just above it.&lt;br /&gt;&lt;br /&gt;The same effect can be well seen if there are big differences in temperatures, eg. fire is hot but the air several meters from it is much cooler. However internal workings are exactly the same.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Although these are same phenomena the implementation of each of them is slightly different. Both can be done as the post-process effects though. This time I'll describe distance heat haze only.&lt;br /&gt;&lt;br /&gt;What we need for implementation of it is Z-buffer contents. Besides the easiest thing would be to simply displace texture coordinates for reading from the current scene texture.&lt;br /&gt;&lt;br /&gt;The effect is applied starting at some given distance. Think for it for a while. Whenever you see it on the photos, in the movies or in the real world it doesn't start very near the observer but rather further away. It's because close to the observer the differences between temperatures of air are very small so there are not many different medias through which the light rays travel. So these rays aren't refracted that much (each medium refracts it on its own).&lt;br /&gt;&lt;br /&gt;Also this effect is stronger near the ground where air is hotter due to closeness of warm objects so what we have to do is to weaken it along y axis (from maximum strength to 0). Besides what makes it stronger is temperature. We can assume that the hotter the object, the brighter it is. So we just have to calculate luminance of the pixel and multiply final effect by it. It all makes &lt;i&gt;strength&lt;/i&gt; attribute used below.&lt;br /&gt;&lt;br /&gt;So finally we can use sine and cosine functions to apply the effect using time as input. To give some variation we add some random data to it (position is good for that and we can read it from Z-buffer).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;texCoord = strength * float2(sin(timer + position.x), 0.25f * cos(timer + position.z)) * maximumHaze;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the movement along the x axis is stronger. For me it seems this makes the effect more realistic. &lt;i&gt;maximumHaze &lt;/i&gt;is the maximum displacement value and &lt;i&gt;strength&lt;/i&gt; is computed as mentioned above. &lt;i&gt;texCoord&lt;/i&gt; is then used to sample frame buffer. We return this read colour as the final one.&lt;br /&gt;&lt;br /&gt;Here are the results. Note the effect is very subtle but improves the quality of the terrain renderer and realism. Compression makes it even more subtle but in the first few seconds (especially when watching 480p version) you should be able to notice it quite easily.&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/6h9SbJj8bX0&amp;hl=pl_PL&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/6h9SbJj8bX0&amp;hl=pl_PL&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;It will be available in a few days from now in the repository with a lot of other useful changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3222666520975500399?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3222666520975500399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/heat-haze-effect.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3222666520975500399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3222666520975500399'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/heat-haze-effect.html' title='Heat &amp; Haze effect'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-780139379170584570</id><published>2010-05-21T15:25:00.000+02:00</published><updated>2010-05-21T15:25:43.092+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Debugging HLSL shaders</title><content type='html'>When developing for DirectX (or alternatively for XNA or XBox), PIX utility from Microsoft is one of the most important and useful tools for every graphics programmer (apart from tools from ATI/nVidia). Although its capabilities on PC are somewhat limited when compared to the XBox version, it still has a lot to offer. One of the features I like the most and will describe in this entry is shader debugging. It's nowhere near the features of Visual Studio debugger but still can come in handy at difficult times.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;What many programmers do instead of debugging shaders is outputting specific information, like outputting some chosen colour to the render target (white and black are my favourites :) ) in pixel shader if the flow of execution was as predicted or outputting eg. normal vectors as colours. It often helps in finding the root of evil but not always. Such an approach is a bit similar to using cout or printf to output some debugging information from within the C/C++ code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Enabling HLSL debugging&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To make full use of shader debugging capabilities (including debugging HLSL code) &lt;i&gt;D3DXSHADER_DEBUG&lt;/i&gt; flag should be specified during shader compilation. This flag makes compiler insert information about type &amp;amp; symbols, lines numbers etc. i.e. everything what is useful for debugger and makes our debugging life easier.&lt;br /&gt;&lt;br /&gt;Different approaches has to be used for debugging different types of shaders so I'll describe what steps have to be taken to debug both vertex and pixel shaders.&lt;br /&gt;&lt;br /&gt;Of course we have to gather DirectX events in one way or another but as there are several options there it is not covered here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Debugging vertex shaders&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are two ways to get to the vertex shader debugger.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Once events are gathered a thing to do is to find &lt;em&gt;Draw Event &lt;/em&gt;of interest in the &lt;em&gt;Events&lt;/em&gt; list and select &lt;em&gt;Render&lt;/em&gt; tab.&lt;/li&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aBDJqIyFI/AAAAAAAADV8/xlX2B1cwWZo/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aBDJqIyFI/AAAAAAAADV8/xlX2B1cwWZo/s320/1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Right-click in the interesting region of the mesh and select &lt;em&gt;Debug This Pixel&lt;/em&gt; from the context menu. It will show you &lt;em&gt;Pixel History&lt;/em&gt; tab:    &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S_aBpZLEboI/AAAAAAAADWA/0zUWJVktvUE/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S_aBpZLEboI/AAAAAAAADWA/0zUWJVktvUE/s320/2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;In the &lt;em&gt;Pixel History&lt;/em&gt; tab scroll-down to the interesting &lt;em&gt;Draw Event&lt;/em&gt; and click on &lt;em&gt;Debug Vertex n&lt;/em&gt; link to debug chosen vertex:    &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S_aCIHc3NQI/AAAAAAAADWE/1vsyIjeV1i4/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S_aCIHc3NQI/AAAAAAAADWE/1vsyIjeV1i4/s320/3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;This in turn will show you &lt;em&gt;Debugger&lt;/em&gt; tab with both &lt;em&gt;Dissasembly&lt;/em&gt; and HLSL code tabs.    &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/S_aCrzkAlAI/AAAAAAAADWI/nWFZy6SF2pY/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/S_aCrzkAlAI/AAAAAAAADWI/nWFZy6SF2pY/s320/4.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Note that in case you use DirectX 9.0 you may see no code in the HLSL tab. It's because PIXRun file for DX 9.0 doesn't embed HLSL code (for DX 10 and later - it does). If it moved from its original location you will get info that you have to browse for it manually. It is the case for me as I load the shaders from memory and after finishing the application they are of course no longer available.    &lt;li&gt;The second way to get to the vertex shader debugger is to select &lt;em&gt;Mesh&lt;/em&gt; tab and from it &lt;em&gt;PostVS&lt;/em&gt; tab and then to click on the desired vertex. Note that it is even highlighted on the mesh in both the Pre-Vertex Shader, Post-Vertex Shader and Viewport windows. This way you can easily find the vertex you are interested in debugging.&lt;/li&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aDF08NI1I/AAAAAAAADWM/RTZHRhz6r5w/s1600/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aDF08NI1I/AAAAAAAADWM/RTZHRhz6r5w/s320/5.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-size: large;"&gt;Debugging pixel shaders&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Getting to the pixel shader debugging is as easy as getting to the vertex shader debugging. Just right-click on the desired pixel in the render tab, then select &lt;em&gt;Debug This Pixel&lt;/em&gt; and scroll down to the &lt;em&gt;Draw Event&lt;/em&gt; of interest but this time select &lt;em&gt;Debug Pixel&lt;/em&gt; instead of &lt;em&gt;Debug Vertex n&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Debugging options&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;Ok, once we know how to get to the debugger let's see what options of debugging do we have.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aEnkxBN0I/AAAAAAAADWQ/lmKE3cGeM_Q/s1600/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="135" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aEnkxBN0I/AAAAAAAADWQ/lmKE3cGeM_Q/s320/6.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Not that many as in the VS as I said a while back but still quite a few. We can run our code to cursor, we can step (forwards and backwards), we can resume and we can set breakpoints. Apart from it we can view current values of variables and registers (two bottom tabs).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Setting a breakpoint on the line&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To set a breakpoint just select desired line and press F9 to toggle breakpoint or click to the left of the line to toggle it. It's the same as in Visual Studio.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-780139379170584570?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/780139379170584570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/debugging-hlsl-shaders.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/780139379170584570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/780139379170584570'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/debugging-hlsl-shaders.html' title='Debugging HLSL shaders'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/S_aBDJqIyFI/AAAAAAAADV8/xlX2B1cwWZo/s72-c/1.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7911197086809620534</id><published>2010-05-16T11:51:00.000+02:00</published><updated>2010-05-16T11:51:16.136+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Character animation. Part 3 - animation blending</title><content type='html'>With the skeletal animation basics covered in &lt;a href="http://wtomandev.blogspot.com/2010/03/character-animation-part-1-ideas-behind.html"&gt;part 1&lt;/a&gt; and &lt;a href="http://wtomandev.blogspot.com/2010/05/character-animation-part-2-implementing.html"&gt;part 2&lt;/a&gt; of this tutorial it's time to dig deeper into character animation. This time I'm introducing animation blending - a useful technique to procedurally generate new animations and transitions between different animation clips (eg. walking and running) of key framed skeletal animation. Some concepts presented here apply to Inverse Kinematics too so stay focused.&lt;br /&gt;&lt;br /&gt;Let's say you have a character which can run, walk and wave its hands while standing still. 3 animation clips is not much. Besides you would probably like to have animation with the character walking and waving a hand at the same time (but the artist didn't manage to create one unfortunately) and yet another useful thing would be to have smooth transition between walking and running clips instead of switching animations what would result in an ugly and artificial transition.&lt;br /&gt;&lt;br /&gt;Welcome to the world of animation blending then :)&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Animation blending is probably one of the easiest animation techniques. Yet it can be very powerful as it can increase number of animations to the infinite number from just a few base ones.&lt;br /&gt;&lt;br /&gt;As the skeletal animation is nothing more than a set of transformations (local, combined and offset as you probably recall), blending has definitely something to do with them. It's obvious that different transformations can be combined to produce different effects. For instance you can combine translation with scaling to achieve scaling of the object while moving it at the same time what is used when building a skeleton or scene graph hierarchy. You do that by multiplying matrices. There is one problem with multiplication though. It's non-commutative. In case of animation blending that would mean that multiplying transformations responsible for walking with ones responsible for waving a hand would yield different results from the case in which the order of the multiplication was reversed. It's something we don't want for sure. However, the solution is simple. Instead of multiplying the matrices addition has to be used. It's completely acceptable from the mathematical point of view and is what we are looking for.&lt;br /&gt;&lt;br /&gt;Matrices for each of the sets can be multiplied by a floating point value - a weight of the transformation, eg. if you want to make a smooth transition between walking and running you have to set weight for one of the sets to t and for the other one to (1.0 - t) where t is an interpolated value ranging from 0 to 1 with interpolation taking a few frames.&lt;br /&gt;&lt;br /&gt;So if we go back to our local transform of a bone from the previous part of this series it can be now computed as:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;localTransform = animationSet[0].transform * animationSet[0].weight + ... + animationSet[n - 1].transform * animationSet[n - 1].weight;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where n is the number of currently active animation sets (clips).&lt;br /&gt;&lt;br /&gt;Sometimes you can (and should) use 1.0 weight for more than one set at a time. It is desirable in case your animations are blending-friendly. For instance animations can be done this way that some of them affects only legs, some of them arms, or head (with no animation data for anything else what means no key frames/animation keys). So in such a case to animate legs you would set 1.0 weight for walking and 1.0 for waving a hand.&lt;br /&gt;&lt;br /&gt;Another way to go is to set weights depending on the bone. In our case if the character is running it will probably move it hands forward and backwards as the runners do. We want this behaviour for the non-waving hand but for the waving one - not. So we can set weights for walking set for one of the arms to 0.0 and set 1.0 for waving a hand for it.&lt;br /&gt;&lt;br /&gt;This is especially useful when Inverse Kinematics is involved so I will come back to it when describing IK in the later parts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7911197086809620534?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7911197086809620534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/character-animation-part-3-animation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7911197086809620534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7911197086809620534'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/character-animation-part-3-animation.html' title='Character animation. Part 3 - animation blending'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-9036659890080312972</id><published>2010-05-14T14:07:00.003+02:00</published><updated>2010-05-14T14:10:02.392+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Character animation. Part 2 - implementing skeletal animation</title><content type='html'>With the Collada animated meshes supported in nGENE* I finally have some time to post anything here. &lt;a href="http://wtomandev.blogspot.com/2010/03/character-animation-part-1-ideas-behind.html"&gt;A long time ago&lt;/a&gt; I promised animation series but managed to write only one post so far. So it's high time to write something more. This time I will focus on the implementation details of a simple skeletal animation system on the GPU. Next post will be about animation blending. And then morphing will follow.&lt;br /&gt;&lt;br /&gt;* Parsing animation was a real pain, believe me. Collada is good but exporters for Blender definitely are not. They're missing a lot of useful information and the exported file is larger and requires more work with it than it could be according to the Collada specification. Another problem I see now, is that Collada is pretty huge. I mean to write a fully working importer/exporter A LOT of work is required. There are so many options... many things can be achieved in more than one way (rotations for example... quaternions are of course possible but the other option to go is to use Euler angles with any order of the angles possible...).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;First important thing is that with skeletal animation, bones are nothing more but mere transformations (4x4 matrices will do). The reason we often depict them as geometry (lines for example) is purely for simplicity reasons. Besides this transformation is used to position joint of the bone, it doesn't convey information about the length of the bone in any way.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Local and combined transforms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The geometry modified by bones is in turn called - &lt;i&gt;skin&lt;/i&gt; (that's the reason for one of the names of this technique - &lt;i&gt;vertex skinning&lt;/i&gt;). Each bone stores transformation in its local space and we call it &lt;i&gt;local transform&lt;/i&gt; (thus we can call our skinning - &lt;i&gt;local-space vertex skinning&lt;/i&gt;; but &lt;i&gt;world-space vertex skinning&lt;/i&gt; is also possible of course). There is also so called &lt;i&gt;combined transform&lt;/i&gt; which is calculated by post-multiplying the local transform of the bone by its parent combined transform matrix, i.e. it is recursive process started at the root bone. Look at the following pseudo-code (it won't work for root bone of course):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;void calculateCombinedTransform(Bone* bone)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; bone-&amp;gt;combinedTransform = bone-&amp;gt;localTransform * bone-&amp;gt;parentTransform;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; Bone* pChild = bone-&amp;gt;children;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; while(pChild)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; calculateCombineTransform(pChild);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; pChild = pChild-&amp;gt;nextSibling;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; }&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That also means that for the root the following is true:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;pRoot-&amp;gt;combinedTransform = pRoot-&amp;gt;localTransform;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Local transform is eg. responsible for bone rotation around its joint. We can also offset the bone or scale it but those are less frequently used (ok, for root bone translation is quite often used). Combined transform is used to build the skeleton so it could be used for positioning the vertices of the character mesh.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Animating the skeleton&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now how do we animate the skeleton? Well there are numerous possibilities there. We can use Inverse Kinematics, animation blending, Key Frame Animation, we can blend and mix all those techniques together too... in this post I focus on the Key Frame Animation, the rest will be covered in the consequent parts of the series.&lt;br /&gt;&lt;br /&gt;Key frame itself can be thought as some sort of target. For example one key frame might be head looking straight and another one can be head looking to the left. Now, what we need to do is to interpolate between those two frames using time to achieve impression of animation. We could of course save data for each of the frames in between but that would be wasting memory. If the key frames are properly chosen (i.e. there is a sufficient number of them) and yet the interpolation method is good (linear interpolation doesn't work in all cases) it might be difficult to say the difference between key frame animations or having infinite number of frames.&lt;br /&gt;&lt;br /&gt;Depending on the 3D file format used there might be separate keys for translation, scaling and rotation or there might be simple transformation matrices. The first approach can be found in .x files. Both of them can be found in Collada. Also the number of keys for each of the transformations might be different and yet they can occur in different times of animation cycle so it might be good decision to store separate keys for each type of the transformation.&lt;br /&gt;&lt;br /&gt;Then animating is as simple as interpolating between the keys of a given type and building transformation matrix from them. Then this transformation matrix is used as the bone's local transform.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Bind pose&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another important term is a &lt;i&gt;bind pose&lt;/i&gt;. Bind pose is a default layout of the character mesh - a pose in which the bones were bound to it at the stage of creation by artist. That means that for such a pose all local transform (and thus combined transform matrices too) are also default.&lt;br /&gt;&lt;br /&gt;The reason I'm talking about it is simple. Note that as the skin is one continuous mesh the vertices are not in the bone space (rather in character space) what means that we cannot simply use bone combined transform matrix to position them. And here offset transform comes into action - it transform vertices in the bind pose from bind space to the space of the respective bone. When the vertex is in a space of a given bone transforming it by a combined matrix of this bone will position it properly in the character space (remember combined matrices build the skeleton).&lt;br /&gt;&lt;br /&gt;Calculating offset transform is simple if you note that another name of it is &lt;i&gt;inverse bind pose&lt;/i&gt;... yes it is enough to invert world space bind pose matrix of a given bone. Even though this process is very simple it is often not necessary to perform it manually as many 3D file formats contain this information (for example .x file or Collada). The less processing, the better :) But is definitely worth knowing.&lt;br /&gt;&lt;br /&gt;Therefore final bone transformation matrix can be described as:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;finalTransform = offsetTransform * combinedTransform&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Animating on the GPU&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Final matrix is then used in the vertex shader. Note that it will suffice to pass only 12 (4x3 matrix) values for each of the matrices instead of all 16 values as one of the columns (in row major) or rows (in column major) does not contain any useful information. So we only need to pass this data as an array to the shader.&lt;br /&gt;&lt;br /&gt;At mesh creation time in the loader we have to also create proper vertices. Apart from regular position, normal and texture coordinates we need to feed up our shaders with additional information, namely:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;i&gt;bones indices&lt;/i&gt; - indices of the bones influencing the given vertex. In most game scenarios 4 bones per vertex is enough. It is therefore a common practise to use a single int variable to store this data. Thus, each byte contains index of one influencing bone.&lt;/li&gt;&lt;li&gt;&lt;i&gt;bones weights&lt;/i&gt; - for each of the bones influencing the vertex the weight is how much this bone affects the vertex with 0.0 meaning no influence at all and 1.0 full influence. Typically, we need 4 float values to pass this information.&lt;/li&gt;&lt;/ol&gt;Both bones indices and bones weights are specified by artists during model animating in a 3D program. They don't specify the indices directly, however, exporters write this information for us.&lt;br /&gt;&lt;br /&gt;So now to the shader part. Look at the code below (from DX SDK):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;float bonesWeightsArray[4] = (float[4])IN.bonesWeights;&lt;br /&gt;int bonesIndicesArray[4]   = (int[4])D3DCOLORtoUBYTE4(IN.bonesIndices);&lt;br /&gt;&lt;br /&gt;float3 pos = 0.0f;&lt;br /&gt;float3 normal = 0.0f;&lt;br /&gt;&lt;br /&gt;for(int i = 0; i &amp;lt; bonesNum - 1; i++)&lt;br /&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; lastWeight = lastWeight + bonesWeightsArray[i];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;       pos += mul(IN.position, boneMatrices[bonesIndicesArray[i]]).xyz * bonesWeightsArray[i];&lt;br /&gt;&amp;nbsp;       normal += mul(float4(IN.normal, 0.0f), boneMatrices[bonesIndicesArray[i]]).xyz * bonesWeightsArray[i];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;lastWeight = 1.0f - lastWeight;&lt;br /&gt;&lt;br /&gt;pos += (mul(IN.position, boneMatrices[bonesIndicesArray[bonesNum - 1]]).xyz * lastWeight);&lt;br /&gt;normal += (mul(float4(IN.normal, 0.0f), boneMatrices[bonesIndicesArray[bonesNum - 1]]).xyz * lastWeight); &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I believe this snippet is pretty self-explanatory provided you have any experience with vertex shaders programming. If not... it's high time to learn it ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-9036659890080312972?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/9036659890080312972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/character-animation-part-2-implementing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9036659890080312972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9036659890080312972'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/character-animation-part-2-implementing.html' title='Character animation. Part 2 - implementing skeletal animation'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5480384982633273955</id><published>2010-05-04T12:35:00.004+02:00</published><updated>2010-05-04T12:39:54.241+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><title type='text'>Royal Baths Park and the Rule of Thirds</title><content type='html'>Two days ago I made yet another attempt at photography (long walks are good for that). This time I went to the Royal Baths Park (Lazienki Krolewskie w Warszawie -&amp;gt; info for Polish readers to avoid any confusion :) ) and took pics of some animals and plants.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;I had a chance to capture several animals including a squirrel, mandarin duck and even a roe deer. This last caused some amazement to all visitors as it hardly ever can be met there (actually I'd seen it for the first time in the dozen or so visits there). I was also shocked especially because everyone was pointing in one direction. With my eagle sight (you know - refraction, radial blur, bloom etc.) I couldn't find out what this fuss was about. I'd seen a squirrel. Regular one, nothing strange :) or at least nothing extraordinary... but ok - then I realized that there was a roe deer standing between the trees. Big one. I was lucky enough to get as close as about 2 meters from it. Damn and this day I hadn't taken tele zoom lenses with me. What a pity. But still from this distance even a mere 50 mm did its job pretty nicely.&lt;br /&gt;&lt;br /&gt;This time apart from showing my photos I'll write about something more too - the Rule of Thirds, one of the most important guidelines in photography composition (I'm still trying to learn this rule and I must admit I fail in the majority of cases but it's good to know that there is something like that). Composition rules in general make photos stand out and improve their quality. That is when good composition is used you will easily tell the difference between good and not that good (or simply put - bad) photo. Even if the rest of the photo is the same (eg. techniques used, lenses, light, contrast).&lt;br /&gt;&lt;br /&gt;The idea is simple - the imaginary 3x3 grid is put on the image when taking a photo. The most interesting subject/point of the photography should be put either on one of its lines or when applicable in one of the points of intersection. When there is a large subject (eg. a tree) you can put it on the line (vertical I guess). When the point of interest is small (eye, shell, some insect etc.) it is better to put it in the intersection point. The reason for this is simple. We humans tend to focus on this points (and lines) and if there is something interesting we find such an image appealing and interesting.&lt;br /&gt;&lt;br /&gt;As one image is worth more than a thousand of words, look at the photo below:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S9_zKzHfQUI/AAAAAAAADQA/urWN_k_5fEY/s1600/DONE_IMG_8559.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S9_zKzHfQUI/AAAAAAAADQA/urWN_k_5fEY/s320/DONE_IMG_8559.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And now look at the imaginary grid I drew in GIMP:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S9_zMj6KtgI/AAAAAAAADQE/aIgvf7o2VB4/s1600/GRID_DONE_IMG_8559.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S9_zMj6KtgI/AAAAAAAADQE/aIgvf7o2VB4/s320/GRID_DONE_IMG_8559.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;The thing to note is that I put pigeon's eye in the upper right point of intersection. The photo itself isn't that good (I couldn't get closer to it... all attempts to do that caused pigeons to fly away) but if I put there a blade of grass the impression would be much worse :)&lt;br /&gt;&lt;br /&gt;The same technique can be applied (and probably should) when taking screenshots in games so it's good to know about that. Considering games it can be even easier. Instead of imagining a grid we can really put it on the screen, ideally compose the image, disable a grid and grab the screenshot. Thus our games will look better in still than they really should :P&lt;br /&gt;&lt;br /&gt;And finally the gallery of photos:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5467051417330851713%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5480384982633273955?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5480384982633273955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/royal-baths-park-and-rules-of-thirds.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5480384982633273955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5480384982633273955'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/royal-baths-park-and-rules-of-thirds.html' title='Royal Baths Park and the Rule of Thirds'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/S9_zKzHfQUI/AAAAAAAADQA/urWN_k_5fEY/s72-c/DONE_IMG_8559.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4243870572778841121</id><published>2010-05-01T11:05:00.000+02:00</published><updated>2010-05-01T11:05:43.864+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>Site - one year after</title><content type='html'>Not long time ago a year passed since I'd started this blog. Before that I was writing only in Polish language somewhere else. Switching to English was a wise decision it seems. I can share my ideas and results of my work (both in programming and photography fields) with a much wider audience and yet I get more feedback on them. This suggestions help me improve techniques I use, think more carefully about them or sometimes even made me to completely rethink some of them.&lt;br /&gt;&lt;br /&gt;I hope that in general my posts are useful or interesting but I would be glad for any comments here about what you will prefer to read and what is boring/useless in my posts so I can improve their quality in the following year.&lt;br /&gt;&lt;br /&gt;I have a lot of draft posts waiting for editing and publishing. They cover various areas like animation, multi-threading, gameplay and AI so stay tuned :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4243870572778841121?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4243870572778841121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/05/site-one-year-after.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4243870572778841121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4243870572778841121'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/05/site-one-year-after.html' title='Site - one year after'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8750916999409496719</id><published>2010-04-28T16:11:00.001+02:00</published><updated>2010-06-01T10:53:55.051+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>Macro spring photography</title><content type='html'>Today I decided to try my hand at macro photography. About half a year has passed since my &lt;a href="http://wtomandev.blogspot.com/2009/09/photography-light-graffiti-macro-hdr.html"&gt;previous attempt&lt;/a&gt;. Spring is definitely a good time of year for shooting macro as colours are vivid, many plants and animals get back to life after winter.&lt;br /&gt;&lt;br /&gt;This time I almost haven't post-processed the images. The only adjustment was using "auto" for some of the photos. I even haven't used unsharp mask this time!&lt;br /&gt;&lt;br /&gt;Click link below or "read more" to see slide-show:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/tomanw/MacroSpringPhotography?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh5.ggpht.com/_fbfW7HvrHa4/S9g_ppFvMpE/AAAAAAAADL8/pfEgjifVbAI/s160-c/MacroSpringPhotography.jpg" style="margin: 1px 0 0 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5465188132451201681%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8750916999409496719?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8750916999409496719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/macro-spring-photography.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8750916999409496719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8750916999409496719'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/macro-spring-photography.html' title='Macro spring photography'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_fbfW7HvrHa4/S9g_ppFvMpE/AAAAAAAADL8/pfEgjifVbAI/s72-c/MacroSpringPhotography.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4808742069655768176</id><published>2010-04-27T09:26:00.000+02:00</published><updated>2010-04-27T09:26:42.363+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Changes</title><content type='html'>Yesterday was my last day at One2Tribe company. Through last 6 months I've been working as a Java programmer and although I still don't like it (there are some niceties when compared to C++, but from modern languages I prefer C# and C++/CLI) it was pretty funny and useful experience. Now I'm taking a few days off from any work (nGENE doesn't count - I've got a lot of work here and a lot is to come in the following weeks), after that I'll make decisions on the next steps.&lt;br /&gt;&lt;br /&gt;So to the One2Tribe guys reading this entry - thanks! I really enjoyed my stay there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4808742069655768176?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4808742069655768176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/changes.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4808742069655768176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4808742069655768176'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/changes.html' title='Changes'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4557844335514513383</id><published>2010-04-25T20:28:00.005+02:00</published><updated>2010-04-25T20:33:44.023+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Spring photos</title><content type='html'>Today it was a beautiful spring day (finally it was sunny and warm!). I decided to take this opportunity to take some photos (I was just fed up with shooting snow :) ). Here are the results:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/SpringFinally?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh4.ggpht.com/_fbfW7HvrHa4/S9R1sIqYTWE/AAAAAAAADHs/q64Wl39FysY/s160-c/SpringFinally.jpg" style="margin: 1px 0 0 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If you want to view slide show, click "read more".&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align:center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5464121649007185249%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4557844335514513383?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4557844335514513383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/spring-photos.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4557844335514513383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4557844335514513383'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/spring-photos.html' title='Spring photos'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_fbfW7HvrHa4/S9R1sIqYTWE/AAAAAAAADHs/q64Wl39FysY/s72-c/SpringFinally.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-11155588213888768</id><published>2010-04-19T16:00:00.009+02:00</published><updated>2010-04-19T16:00:01.544+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>Some changes to the blog</title><content type='html'>As you probably noticed today I've completely changed the appearance of my blog (note orange &amp; teal - it works ;) ). The reason for that is simple. I was pretty much fed up with the previous one, which I chose at the very beginning of my blogging (three years back I guess, including Polish version of this blog which was first). The changes are... well radical... I will tweak a lot of things in the following days to make it more readable and eye-pleasing :)&lt;br /&gt;&lt;br /&gt;I also fixed some problems with performance on Firefox.&lt;br /&gt;&lt;br /&gt;As for the nGENE everything is a bit delayed (I mean SDK RC2 ;) and the new video of soft particles). Hope to do some of it this week but I have pretty much work with the engine, you know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-11155588213888768?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/11155588213888768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/some-changes-to-blog.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/11155588213888768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/11155588213888768'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/some-changes-to-blog.html' title='Some changes to the blog'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6351985153435376744</id><published>2010-04-13T20:47:00.001+02:00</published><updated>2011-04-08T16:58:51.438+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Soft particles - video</title><content type='html'>Recently I posted a note about &lt;a href="http://wtomandev.blogspot.com/2010/04/soft-particles-what-are-they.html"&gt;soft particles&lt;/a&gt;. Here is how they currently look in nGENE (after removing edge aliasing thanks to &lt;a href="http://sebh-blog.blogspot.com/"&gt;Sebh&lt;/a&gt; suggestion; heat &amp;amp; haze effect doesn't look very good in this video due to compression but softness of particles should be obvious):&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/NzJCSyucmOQ&amp;hl=pl_PL&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/NzJCSyucmOQ&amp;hl=pl_PL&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6351985153435376744?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6351985153435376744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/soft-particles-video.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6351985153435376744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6351985153435376744'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/soft-particles-video.html' title='Soft particles - video'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4381070716434637752</id><published>2010-04-12T20:16:00.013+02:00</published><updated>2010-09-04T12:04:24.927+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photoshopping games'/><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Orange &amp; Teal - colour grading</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NTxqCk8UI/AAAAAAAADBA/AkXUC0g-MyI/s1600/orange_and_teal_hi_contrast.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NTxqCk8UI/AAAAAAAADBA/AkXUC0g-MyI/s320/orange_and_teal_hi_contrast.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If you have read &lt;a href="http://theabyssgazes.blogspot.com/2010/03/teal-and-orange-hollywood-please-stop.html"&gt;the article about orange &amp;amp; teal abyss&lt;/a&gt; in the Hollywood movies you may wonder how such an effect can be accomplished in games. It is very simple and I will cover it in this entry.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Normally, in the image and photography processing a lot of effects (including mentioned &lt;i&gt;orange &amp;amp; teal&lt;/i&gt;) can be achieved by means of editing curves. Typical curves tool in Photoshop or Gimp looks as follows:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NTm8VyStI/AAAAAAAADA4/MOp7K2WCPiE/s1600/curves.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NTm8VyStI/AAAAAAAADA4/MOp7K2WCPiE/s320/curves.png" width="274" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It's one of the most powerful tools and is used in many scenarios, eg. enhancing contrast or changing tonal atmosphere.&lt;br /&gt;&lt;br /&gt;A &lt;i&gt;curve&lt;/i&gt; is a function where arguments are input tones (on the x axis) and the results are output tones (y axis). Normally it is linear (meaning output image doesn't differ from the source one) but to change feeling and atmosphere of the image it is sometimes desirable to change its shape (in many scenarios so called s-curve will do which is presented in the image above). Thus contrast for instance can be enhanced or tonal atmosphere can be altered. Also some special effects can be achieved thanks to that (eg. one can do colour inversion this way). I don't want to cover a theory behind editing curves as there are a lot of tutorials on this subject regarding editing photos in Photoshop and Gimp so now I'm moving to the implementation details.&lt;br /&gt;&lt;br /&gt;If we limit our input and output to the range of [0; 1] - i.e. typical colours range - then it is very simple to achieve this in the shader - this function can be passed as a 1D texture. Arguments are u-coordinates, and results are colours. In case we treat all the channels the same way, it will be texture in gray scale. However, it may be sometimes desirable to operate on red, green and blue channels separately - then it will be regular RGB texture. Underneath is the texture I used for achieving effect from the first image:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8NcsGsM5pI/AAAAAAAADBw/eqUPIsrEnB8/s1600/gradient.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8NcsGsM5pI/AAAAAAAADBw/eqUPIsrEnB8/s200/gradient.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;It is stretched of course to make it easier to analyze. Black (all channels equal 0) is mapped onto black (as all channels are 0 u-coordinate is also 0) as always, however white (all channels equal 1) is mapped to a very light orange (right of the image; u-coordinate being 1).&lt;br /&gt;&lt;br /&gt;For each of the channels we compute their value as:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;colour.r = tex2D(gradingTex, float2(scene.r, 0.5f)).r;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Where &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;scene&lt;/span&gt; is our source image and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;gradingTex&lt;/span&gt; is the function to be used.&lt;br /&gt;&lt;br /&gt;All we have to do is to get the pixel from the scene image and multiply each of its component by the value read from the curve texture at the place equal to the each of the channels.&lt;br /&gt;&lt;br /&gt;Here are some examples using this simple yet so powerful approach:&lt;br /&gt;&lt;br /&gt;Source image:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NVvZew6yI/AAAAAAAADBQ/hBwXQvny-xk/s1600/normal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NVvZew6yI/AAAAAAAADBQ/hBwXQvny-xk/s200/normal.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;High- and low-contrast respectively:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NV4qZ8hDI/AAAAAAAADBY/I6JmkDjbM9o/s1600/hi_contrast.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NV4qZ8hDI/AAAAAAAADBY/I6JmkDjbM9o/s200/hi_contrast.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NV9-ZSL9I/AAAAAAAADBg/ozAZTl-pjXU/s1600/lo_contrast.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8NV9-ZSL9I/AAAAAAAADBg/ozAZTl-pjXU/s200/lo_contrast.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;And once again orange &amp;amp; teal:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NWH82vaNI/AAAAAAAADBo/Dq-pjDTO9Wk/s1600/orange_and_teal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NWH82vaNI/AAAAAAAADBo/Dq-pjDTO9Wk/s200/orange_and_teal.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4381070716434637752?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4381070716434637752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/orange-teal-colour-grading.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4381070716434637752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4381070716434637752'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/orange-teal-colour-grading.html' title='Orange &amp; Teal - colour grading'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbfW7HvrHa4/S8NTxqCk8UI/AAAAAAAADBA/AkXUC0g-MyI/s72-c/orange_and_teal_hi_contrast.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2385278283208926056</id><published>2010-04-10T19:47:00.002+02:00</published><updated>2010-04-10T19:51:24.651+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Soft particles - what are they?</title><content type='html'>&lt;div&gt;Particle systems are a simple way to model complicated volumetric medias like smoke or fire (and also special effects like magic spells, fireworks and so on) by approximating them by a small set of objects known as particles. Of course, if we were to make it fully realistic we would have to use billions of tiny particles but instead we use hundreds or thousands of large ones at most.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Traditional real time (I mean used in games) particle systems are created by rendering multiple small camera-faced 2D quads (or point sprites) all over the medium volume with some sort of blending enabled (which is often additive blending to avoid need of depth sorting). The quads have textures assigned to them which convey information about colour and transparency of the particle. Particles are animated (i.e. change position in 3D, colour, transparency, linear and angular velocity, radius etc.) according to the specified equations and faded out as their lifetime ends. For some uses Perlin noise will do, for other different approaches have to be used.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Although "traditional particle systems" are still commonly used in games (even in some newer ones), they have several disadvantages, of which 2 are especially undesirable:&lt;/div&gt;&lt;div&gt;1) hard edges - they are especially visible on the object's boundary with which particles collide. That is particles are not smoothly blended with the environment and yet you can notice several layers of particles.&lt;/div&gt;&lt;div&gt;2) when going through the medium constant popping occurs. You can notice it when going through the smokescreen for instance when particles appear and disappear as you move, although they should be visible all the time as smokescreen can be thought as some sort of fog.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The reason for this is simple. Particles are 2D quads (meaning their depth dimension is 0) whereas the rest of the scene is fully 3-dimensional. So particles are not continuous but are rather discretely distributed. Look at the picture below:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8C0DSGR8jI/AAAAAAAADAk/AiN8_hfTtbM/s1600/traditional.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8C0DSGR8jI/AAAAAAAADAk/AiN8_hfTtbM/s320/traditional.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you see there is a lot of empty space between particles considering depth, what causes effect I wrote above. So a particle is behind or in front of a 3D object. There are no shades between.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The easy solution is here for several years now and is called soft volumetric particles (or simply - soft particles, spherical billboards and under several different names). What's funny about this is that this approach is very similar to rendering traditional particles and yet the results are much more pleasing and the aforementioned artifacts are completely removed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The thing to note is that each particle have its own radius as presented below:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8C0ISfa71I/AAAAAAAADAs/sUWdTHgRsq4/s1600/new.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8C0ISfa71I/AAAAAAAADAs/sUWdTHgRsq4/s320/new.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can therefore think of it as of a sphere... but we still want to render particles as 2D, quads - not spheres, for performance reasons (however, I once came across approach using spheres geometry... as far as I remember it was called mega-particles and the results were very very good especially for the large explosions - the benefit is also that it's easier to lit such systems as normals are available).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, if we have depth buffer the solution is pretty straight forward. We just have to compare values stored in the z-buffer with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;modified_depth&lt;/span&gt; value of the particle, where:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;modified_depth = particle_depth - 2 * radius&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;By multiplying radius by 2 we move back by particle diameter and thus render it's "back face".&lt;br /&gt;&lt;br /&gt;Then if this value is greater than scene depth at this point it means that particle at this pixel is behind the geometry and thus it doesn't influence final image. When it is smaller or equal in turn, it means that it is in front of scene's geometry or it "overlaps" it. Therefore it should be blended with the rest of the scene.&lt;br /&gt;&lt;br /&gt;We therefore use this computed value as a factor to compute particle's transparency (multiplied eg. by particle's density). &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is a lot of updates going on regarding nGENE. Next weekend I hope to release updated SDK with some of the bugs fixed and a lot of improvements.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There was a lot of fuss around soft particles when DX 10 was out (due to one of the demos in the SDK, I guess) but the truth is that this technique can be done easily on the pre DX10 GPUs too.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Here are some pics from nGENE's particle system (I improved it slightly in the last few days):&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8CwRjd0a_I/AAAAAAAAC_c/29pynhmKJDo/s1600/1.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8CwRjd0a_I/AAAAAAAAC_c/29pynhmKJDo/s200/1.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8Cw2e3G3SI/AAAAAAAAC_8/03WW57W4ofs/s1600/2.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/S8Cw2e3G3SI/AAAAAAAAC_8/03WW57W4ofs/s200/2.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8Cw78iGvyI/AAAAAAAADAE/KFdYB7KKBa0/s1600/3.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8Cw78iGvyI/AAAAAAAADAE/KFdYB7KKBa0/s200/3.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8CxDKledEI/AAAAAAAADAM/384fanqEXsQ/s1600/4.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/S8CxDKledEI/AAAAAAAADAM/384fanqEXsQ/s200/4.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8CxIz7W45I/AAAAAAAADAU/kD0mJ5MrOpA/s1600/5.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/S8CxIz7W45I/AAAAAAAADAU/kD0mJ5MrOpA/s200/5.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8CxPbQ3LRI/AAAAAAAADAc/05XpQ2eFTPo/s1600/6.png" imageanchor="1" style="margin-left: 0em; margin-right: 0em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S8CxPbQ3LRI/AAAAAAAADAc/05XpQ2eFTPo/s200/6.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;BTW finally there is a game project in development which uses nGENE... yeah and I'm not the author of the game. I'm really happy about that, I believe the guys will succeed and that it will boost nGENE's popularity. I will write more about that soon. What I can say now is that nGENE started to improve very quickly because the developers don't hesitate to write about their doubts and wishes what make me rethink some of the functionalities, fix bugs and in general improve general image.&lt;br /&gt;&lt;br /&gt;Besides, thanks to that I got a lot of motivation to work on nGENE in the last few weeks and improved/fixed so many things (current version is 0.1.6.5 and includes few thousand more lines than recently released SDK 0.1.6).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2385278283208926056?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2385278283208926056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/04/soft-particles-what-are-they.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2385278283208926056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2385278283208926056'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/04/soft-particles-what-are-they.html' title='Soft particles - what are they?'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/S8C0DSGR8jI/AAAAAAAADAk/AiN8_hfTtbM/s72-c/traditional.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5941898580940295730</id><published>2010-03-30T11:33:00.005+02:00</published><updated>2010-05-15T12:14:32.884+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><title type='text'>Dahab landscape photograpy</title><content type='html'>It's time to publish last sets of photos taken in Dahab, Egypt. This time - landscape photography, including sunsets, sea and a few HDR. Also a few pics were shot using long exposure. Read more to see slideshow or open the link below to visit Picasa album:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/DahabLandscape?feat=embedwebsite" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img height="160" src="http://lh3.ggpht.com/_fbfW7HvrHa4/S7Dym8bwgQE/AAAAAAAAC-A/nhxCpMD_LJE/s160-c/DahabLandscape.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5454125899617173761%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5941898580940295730?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5941898580940295730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/dahab-landscape-photograpy.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5941898580940295730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5941898580940295730'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/dahab-landscape-photograpy.html' title='Dahab landscape photograpy'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_fbfW7HvrHa4/S7Dym8bwgQE/AAAAAAAAC-A/nhxCpMD_LJE/s72-c/DahabLandscape.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8264426750850599193</id><published>2010-03-21T14:53:00.000+01:00</published><updated>2010-03-21T14:53:33.334+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE Tech SDK 0.1.6</title><content type='html'>After quite a long time there is another SDK distribution of &lt;a href="http://ngene.wikidot.com/"&gt;nGENE&lt;/a&gt; - this time coming with all (I hope) required redistributables so there shouldn't be as many crashes as previously :) . It contains binaries, samples, tutorials, class reference and full source code.&lt;br /&gt;&lt;br /&gt;Although it is still RC1 version, the code will be subject to only small changes. The most of the bugs I predict could be related to missing dlls or media files, not working shortcuts creation in the installer and stuff like that.&lt;br /&gt;&lt;br /&gt;There's no point in listing changes since version 0.1 as this list would be just too long - almost everything have changed since then.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The download is available &lt;a href="http://siriuz.net/~wtoman/nGENE/nGENESDK_0_1_6_RC1.exe"&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I also hope to post some nice news about nGENE soon.&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8264426750850599193?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8264426750850599193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/ngene-tech-sdk-016.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8264426750850599193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8264426750850599193'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/ngene-tech-sdk-016.html' title='nGENE Tech SDK 0.1.6'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1563685581054355202</id><published>2010-03-14T18:51:00.001+01:00</published><updated>2010-04-19T09:43:39.954+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Dahab B&amp;W photos</title><content type='html'>In &lt;a href="http://wtomandev.blogspot.com/2010/03/animals-of-dahab.html"&gt;one of the last posts&lt;/a&gt; I wrote about taking photos of animals in Dahab. This time it's B&amp;amp;W photography. Frankly speaking it's my first attempt at this technique ever. So mistakes were inevitable of course. I can only say that B&amp;amp;W is different from anything else. You have to think in a completely different manner (forget about colours, think about brightness and contrast)... Visit the link below or read more to view slideshow:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/DahabInBlackAndWhite?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh4.ggpht.com/_fbfW7HvrHa4/S50frW4Ou8E/AAAAAAAACx4/WZJC4ae0KA0/s160-c/DahabInBlackAndWhite.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5448545953924430785%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1563685581054355202?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1563685581054355202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/dahab-b-photos.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1563685581054355202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1563685581054355202'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/dahab-b-photos.html' title='Dahab B&amp;W photos'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_fbfW7HvrHa4/S50frW4Ou8E/AAAAAAAACx4/WZJC4ae0KA0/s72-c/DahabInBlackAndWhite.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4645254068045945553</id><published>2010-03-11T22:01:00.016+01:00</published><updated>2010-03-12T20:39:12.234+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='techniques'/><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>nGENE web demo (Windows only!)</title><content type='html'>I promised to upload demo to the website... and here it is. One of the simplest nGENE demos, yet it serves well as a proof-of-concept of &lt;a href="http://wtomandev.blogspot.com/2010/03/how-to-make-3d-game-running-in-website.html"&gt;this technique&lt;/a&gt;. The demo can take several minutes to start as in the background it downloads all required resources (only once unless you will clear cache). So just be patient when nothing seems to happen.&amp;nbsp;I'll optimize it during weekend so if you have slow Internet connection wait till then. Read more to view demo. BTW it is Windows 'exclusive' as nGENE supports no other OSes.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;applet width="405" height="305" archive="http://siriuz.net/~wtoman/bin/applet.jar" code="JNIApp.class"&gt;&lt;br /&gt;&lt;param name="jnlp_href" value="http://siriuz.net/~wtoman/bin/ngene.jnlp"&gt;&lt;param name="separate_jvm" value="true" /&gt;&lt;/applet&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4645254068045945553?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4645254068045945553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/ngene-web-demo-windows-only.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4645254068045945553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4645254068045945553'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/ngene-web-demo-windows-only.html' title='nGENE web demo (Windows only!)'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5552096709868879337</id><published>2010-03-09T10:35:00.000+01:00</published><updated>2010-03-09T10:35:10.007+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Character animation. Part 1 - ideas behind skeletal animation</title><content type='html'>Starting with the basics of basics of character animation today I present skeletal animation. This is a fairly easy technique yet it is commonly used in games nowadays. However, I remember reading reviews back in the 90's (I think it was review of Tomb Rider... don't remember which part though) in which reviewers were praising it and it was a real technological innovative (and a real buzzword) then... yeah... life was easier for graphics programmers* :) now it's a real must have of all of the games containing characters... even worse - it is not enough anymore... today games use Ragdoll, Inverse Kinematics and other fancy-named techniques... for the most advanced animation techniques used in games look at Spore or GTA IV.&lt;br /&gt;&lt;br /&gt;* ok I know that's only partially true because computing power nowadays is incomparably higher so we can do more without thinking about every CPU cycle :) &lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Today I will focus only on the concepts behind skeletal animation so consider it a very basic entry, something for beginners I hope. In the consequent notes I'll will cover implementation details of:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Skeletal animation,&lt;/li&gt;&lt;li&gt;Animation blending,&lt;/li&gt;&lt;li&gt;Ragdoll,&lt;/li&gt;&lt;li&gt;Inverse Kinematics,&lt;/li&gt;&lt;li&gt;Morphing.&lt;/li&gt;&lt;/ul&gt;At least that is a long-term plan. I hope to exceed it but we shall see :)&lt;br /&gt;Ok, without further ado. The skeletal animation is based on animals' anatomy. We represent animation by a so called skeleton which is equivalent of animals' skeleton. There are bones which are connected by joints. In more advanced skeletal animation techniques joints can be of different type (eg. spherical, hinge) and can have constraints specified for them (eg. minimum and maximum swing angle). I'll come back to this in the future parts of the animation series.&lt;br /&gt;&lt;br /&gt;Why skeleton was chosen is quite simple. It's pretty natural representation and besides it describes transformations hierarchy pretty well. And hierarchy is important here: note that when you move your shoulder also the position and orientation of your forearm and hand changes. You can also move forearm and hand themselves but this movement is not completely independent (i.e. it is dependent of bones' position which are before it). It means that forearm is a child bone of a shoulder bone and a hand is a child of forearm.&lt;br /&gt;&lt;br /&gt;Also when you change position of your root bone (let's assume it's pelvis) you move yourself around the world but also the rest of your bones are translated and rotated in the world space but they model space position can stay the same.&lt;br /&gt;&lt;br /&gt;Therefore for each bone but root bone you can specify its parent. Root bone is special in a sense it's a child of the scene so it's responsible of changing skeleton's world space transformation.&lt;br /&gt;&lt;br /&gt;Underneath is the image of a typical skeleton (image taken from &lt;a href="http://animadead.sourceforge.net/images/selection.gif"&gt;http://animadead.sourceforge.net/images/selection.gif&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://animadead.sourceforge.net/images/selection.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="http://animadead.sourceforge.net/images/selection.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Simple I hope? If a character holds an object in its hand it means that this object is attached to the hand bone and is moved in relation to this bone. This way you can make your characters carry swords or guns.&lt;br /&gt;&lt;br /&gt;But how to attach this structure to a mesh? There are 2 approaches:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;For each of the bones provide separate mesh object i.e. different one for forearm and different for hand. Each of the meshes is associated with a single bone and is moved and rotated based on the movement and rotation of its bone. It's hardly ever used solution today as it creates ugly breaks between the meshes. Besides this way only one bone can influence each of the meshes what is a bit unrealistic - although you move specified bone mesh not "linked with it" is also influenced. This was used in some old games however.&lt;/li&gt;&lt;li&gt;Use a so called &lt;b&gt;&lt;i&gt;vertex blending&lt;/i&gt;&lt;/b&gt; technique. Each of the vertices have a list of bones influencing it. In theory any number of bones can affect a vertex but in the most scenarios maximum of 4 bones is a sufficient number (sometimes even 2 will do). This approach requires to store this list per vertex. Also each of the bones can influence a vertex using a different weight where 0.0 means no influence at all and 1.0 full influence. Also the sum of weights should equal 1.0. Using 4 bones is convenient because to store this additional data (indices and weights) you have to use only 2 float4 variables. I will write more about this in the next part. To have smooth animation models should have denser mesh in the areas near elbows and knees (actually everywhere where bends are possible).&lt;/li&gt;&lt;/ol&gt;As I already mentioned &lt;a href="http://wtomandev.blogspot.com/2010/03/how-to-make-3d-game-running-in-website.html"&gt;in this post&lt;/a&gt; I'm working on deploying nGENE demos on the website. There is one issue I have to resolve (regarding a bug in Virtual File System I found yesterday) but the idea is to put all the demos on the &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech homepage&lt;/a&gt; so users could run them from there instead of downloading all the resources, installing a lot of additional stuff etc.&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5552096709868879337?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5552096709868879337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/character-animation-part-1-ideas-behind.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5552096709868879337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5552096709868879337'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/character-animation-part-1-ideas-behind.html' title='Character animation. Part 1 - ideas behind skeletal animation'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6700693897431764410</id><published>2010-03-05T22:27:00.002+01:00</published><updated>2010-04-19T10:15:26.669+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Animals of Dahab</title><content type='html'>Some two weeks back I came back from Dahab City, Egypt. It's one of the most famous dive sites in the world (windsurfers and kiters could say the same, I guess). Apart from practicing diving and looking at my friends doing their adv. nitrox/deco. procedures courses I took some photos. Ok... I took many photos but here are those I haven't got rid of. I tried my hand at pretty much everything from nature photography, portraits, B&amp;amp;W to landscape and night photography. I had a lot of fun doing it. So I'm dividing this into a few entries. This time I'm showing animals photography. Dahab is pretty full of cats, dogs, goats, sheeps, camels, etc. They all live on the streets, eating what they find (from rubbish, other animals to calamari at local restaurants).&lt;br /&gt;&lt;br /&gt;Click the link below to visit Picasa album or "read more" to view slideshow:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/AnimalsOfDahab?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh6.ggpht.com/_fbfW7HvrHa4/S5Fs5U2k2bE/AAAAAAAACsw/nxVk9gbqFx0/s160-c/AnimalsOfDahab.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5445253156573600177%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6700693897431764410?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6700693897431764410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/animals-of-dahab.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6700693897431764410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6700693897431764410'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/animals-of-dahab.html' title='Animals of Dahab'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_fbfW7HvrHa4/S5Fs5U2k2bE/AAAAAAAACsw/nxVk9gbqFx0/s72-c/AnimalsOfDahab.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8798708653413377465</id><published>2010-03-04T14:29:00.001+01:00</published><updated>2010-03-04T14:30:42.600+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>How to make 3D game running in a website? (or nGENE meets web)</title><content type='html'>Recently there is a lot of fuss around some 3D engines like Unity and Torque. One of their cool features is that the games made in them can be run in the website even though the engine itself and the game can be written in pure C++ and use DirectX. This makes it easier for players as they don't have to explicitly download and install the game. They just visit the website, the game runs in a window, when the boss enters they have only to switch tab :) ... easy as that. Besides it's easier for developers as they can use existing code base without need to provide some wrappers in languages like Java or C# thus making a game more multiplatform then ever before. Yet the target audience is wider because almost everyone these days have access to the Internet.&lt;br /&gt;&lt;br /&gt;Hardcore FPS game on facebook... :) ? Why not if it is already possible?&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;I wondered how one can achieve this and the solution I came up with a few days back is easier than I actually predicted it to be. I don't know if Unity or Torque teams use similar approach but it works for me and it works well :) I think that they use more complex solution but what the hell :)&lt;br /&gt;&lt;br /&gt;Demo should be available on-line somewhere around next week. I hope to find some hosting by then. &lt;br /&gt;&lt;br /&gt;I knew that I could simply wrap my engine in Java/C#... but that would be tedious task and nothing more but waste of time. I ended up with a solution which required me to add only two additional methods (about 5 lines in length) on C++ game code side. Not bad.&lt;br /&gt;&lt;br /&gt;The first obvious thing for me was that I had to load engine dll somehow. But most of the web technologies I know don't allow that (Flash, Director or Silverlight)... for security reasons. Or at least I don't know how this could be easily achieved :) However, there is one technology which supports it out of the box for sure - Java and its applets... it may sound strange at first but it's true.&lt;br /&gt;&lt;br /&gt;Tutorial how to embed OGRE in website is available &lt;a href="http://www.brighthub.com/hubfolio/matthew-casperson/articles/52773.aspx"&gt;here&lt;/a&gt;. I used it when it came to creating jnlp file.&lt;br /&gt;&lt;br /&gt;In short the steps to run a game in the website are following (detailed description of the process is provided later on):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install JDK and Eclipse/NetBeans :)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Configure your Visual Studio (or other IDE) so it sees libs and includes from JDK.&lt;/li&gt;&lt;li&gt;Create a Java applet code with at least one method marked as &lt;i&gt;native&lt;/i&gt; as we will use JNI mechanism (more on that later).&lt;/li&gt;&lt;li&gt;Compile Java code to get .class file.&lt;/li&gt;&lt;li&gt;Run &lt;i&gt;javah.exe&lt;/i&gt; on your Java class. It will create C/C++ header file with method declaration.&lt;/li&gt;&lt;li&gt;Add resulting file to the C++ project and provide method definition for the native method.&lt;/li&gt;&lt;li&gt;Build your C++ project as .dll.&lt;/li&gt;&lt;li&gt;Add .dll and all its dependencies to the Java project.&lt;/li&gt;&lt;li&gt;Build jars for Java code and dlls. jar is nothing but an archive so you can put virtually anything inside it.&lt;/li&gt;&lt;li&gt;Sign all jars. It is required as you use native libraries.&lt;/li&gt;&lt;li&gt;Deploy applet on the website :)&lt;/li&gt;&lt;li&gt;Play your game? &lt;/li&gt;&lt;/ol&gt;By default in Java you can't use native code explicitly. But you can force it to do this through the JNI - &lt;i&gt;Java Native Interface&lt;/i&gt; mechanism. It allows you to load native libraries (.dll or .so) and call native code from them :) All you have to do on the Java side is creating a class with some methods marked as &lt;i&gt;native&lt;/i&gt;. This keyword works in a similar manner to the &lt;i&gt;abstract&lt;/i&gt; one but instead of looking for the implementation in the Java code or jars it looks for it in the native libraries (eg. dll).&lt;br /&gt;&lt;br /&gt;Hence, a simple Java class (in App.java file) might look like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class App extends Applet {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public App() {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public void init() {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; loadLibrary("engine");&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; startEngine(); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;native void startEngine(); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;};&lt;/div&gt;&lt;br /&gt;where "engine" is name of the library (eg. engine.dll). &lt;br /&gt;&lt;br /&gt;Then for such a file you have to call following command from command line:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;javah.exe App&lt;/div&gt;&lt;br /&gt;This will create App.h file with some JNI related code in it (not much though). This file should be added to your C++ project and implementation of the method has to be provided. Excerpt from such a file is provided underneath:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JNIEXPORT void JNICALL Java_JNIApp_startEngine(JNIEnv*, jobject);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;The rest of the file are mainly #defines and #ifdefs so there is no purpose on putting them here.&lt;br /&gt;&lt;br /&gt;Note that JNI added some additional parameters to the method declaration. However as I won't use them they won't be covered in this entry. &lt;br /&gt;&lt;br /&gt;And now example function definition:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JNIEXPORT void JNICALL Java_JNIApp_startEngine(JNIEnv*, jobject)&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Engine* pEngine = new Engine();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; pEngine-&amp;gt;init();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; pEngine-&amp;gt;start();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It only initializes the engine and starts it (here you can load resources, setup renderer, sound and whatever you want...)&lt;br /&gt;&lt;br /&gt;After adding this code you have to build you C++ project as .dll not .exe! This is important as otherwise you will have no access to this stuff. And we're done with modifying game code!&lt;br /&gt;&lt;br /&gt;To ease the implementation of the applet itself I used &lt;a href="http://www.eclipse.org/swt/"&gt;SWT library&lt;/a&gt; which helps in creating GUI. Below is simple method setting up GUI:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected Display display;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected Canvas canvas;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected java.awt.Canvas awtParent;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected org.eclipse.swt.widgets.Shell swtParent;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected void setupGUI()&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; setLayout(new java.awt.GridLayout(1, 1));&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; awtParent = new java.awt.Canvas();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; add(awtParent);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; display = new org.eclipse.swt.widgets.&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Display();&lt;br /&gt;&amp;nbsp; swtParent = org.eclipse.swt.awt.SWT_AWT.&lt;wbr&gt;&lt;/wbr&gt;new_Shell(display, awtParent);&lt;br /&gt;&amp;nbsp; swtParent.setLayout(new org.eclipse.swt.layout.&lt;wbr&gt;&lt;/wbr&gt;FillLayout());&lt;br /&gt;&amp;nbsp; canvas = new Canvas(swtParent, SWT.NO_BACKGROUND);&lt;br /&gt;&amp;nbsp; swtParent.open();        &lt;br /&gt;&lt;br /&gt;&amp;nbsp; setSize(800, 600);&lt;br /&gt;&amp;nbsp; validate();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; windowHWND = canvas.handle;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;Note the last line. Canvas has integer handle property which in Windows is the same as HWND (I don't know its interpretation for Linux systems)... so you can easily pass it to the C++ code and on its side call:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;HWND hwnd = (HWND)handle;&lt;/div&gt;&lt;br /&gt;where handle is passed Java applet handle. That is more probable than not that your renderer will require it.&lt;br /&gt;&lt;br /&gt;To update window (canvas) we have to create message loop. As long as the applet is valid, it will redraw itself and thus allow us to update engine as well: &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;protected void enterRenderLoop()&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; while (!swtParent.isDisposed())&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; canvas.redraw();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; display.readAndDispatch();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;However we didn't inform engine when it can update (although we know it should be updated when applet is repainted). As we want to do this on paint event we have to add paint listener to our applet's &lt;i&gt;&lt;span style="font-family: inherit;"&gt;init()&lt;/span&gt;&lt;/i&gt; method:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public void init() &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Thread thread = new Thread(new Runnable() &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void run() &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setupGUI();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; startEngine(windowHWND);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; canvas.addPaintListener(new PaintListener() {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void paintControl(org.eclipse.swt.&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;wbr&gt;&lt;/wbr&gt;events.PaintEvent e) { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oneFrame();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div class="ii gt" id=":2q" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="ii gt" id=":2q"&gt;Note that I also created another native method: &lt;i&gt;oneFrame()&lt;/i&gt; which is rensposible of updating engine (draws single frame, update physics, etc.). Not the best solution but it is present here for simplicity reasons. Besides &lt;i&gt;startEngine()&lt;/i&gt; now accepts additional integer parameter: window handle what I mentioned before.&lt;/div&gt;&lt;div class="ii gt" id=":2q"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="ii gt" id=":2q"&gt;So we now finished coding our applet. Now its time to put everything to the jars. Quite good idea is to have at least 2 jars:&lt;/div&gt;&lt;div class="ii gt" id=":2q"&gt;&lt;ul&gt;&lt;li&gt;Java side code,&lt;/li&gt;&lt;li&gt;Native code, dlls and game resources (shaders, game levels, etc.).&lt;/li&gt;&lt;/ul&gt;Reason for that is that we will have to specify which jars contain native resources (dlls) later on when embedding applet on the website.&lt;br /&gt;&lt;br /&gt;To create those jars call:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;jar.exe cf applet.jar *.class&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;jar.exe cf engine.jar engine.dll media.zip&lt;/div&gt;&lt;br /&gt;The first call archives Java code, the second native resources.&lt;br /&gt;&lt;br /&gt;The next step is to sign your jars. It is required as you use native dlls and for security reasons your applet would be very limited in functionality otherwise (and probably you will keep getting exceptions telling that unsigned resource was found...). For this you first have to create certificates:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;keytool -genkey -keystore myKeystore -alias myself&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;keytool -selfcert -alias myself -keystore myKeystore&lt;/div&gt;&lt;br /&gt;And using this certificate sign your jars:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;jarsigner.exe -keystore myKeystore -storepass password jarfile.jar myself&lt;/div&gt;&lt;br /&gt;Note that you have to sign all jars, also swt.jar used for GUI creation. &lt;br /&gt;&lt;br /&gt;One of the last steps is to define applet definition. For that JNLP file is used. Create file demo.jnlp and put into it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;jnlp href="ogre.jnlp"&amp;gt;&lt;br /&gt;&amp;lt;information&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;Demo&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;vendor&amp;gt;Your Name Goes Here&amp;lt;/vendor&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;offline-allowed /&amp;gt;&lt;br /&gt;&amp;lt;/information&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;resources&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;jar href="applet.jar" main="true" /&amp;gt;&lt;br /&gt;&amp;lt;/resources&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;resources os="Windows"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;nativelib href="swt.jar"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;nativelib href="engine.jar"/&amp;gt;&lt;br /&gt;&amp;lt;/resources&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;applet-desc&lt;br /&gt;&amp;nbsp;&amp;nbsp;name="Demo"&lt;br /&gt;&amp;nbsp;&amp;nbsp;main-class="App"&lt;br /&gt;&amp;nbsp;&amp;nbsp;width="640"&lt;br /&gt;&amp;nbsp;&amp;nbsp;height="480"&amp;gt;&lt;br /&gt;&amp;lt;/applet-desc&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;security&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;all-permissions/&amp;gt;&lt;br /&gt;&amp;lt;/security&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/jnlp&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;information tag contains basic information about applet, its vendor, title etc. offline-allowed tag allows application to be run offline (by double clicking on the demo.jnlp file). You can prevent this behaviour by not adding this tag.&lt;br /&gt;&lt;br /&gt;resource tags are very important. They include jars applet uses. Note that native ones are in separate "Windows" tag and within nativelib - not jar. main attribute means that this jar contains applet's main class.&lt;br /&gt;&lt;br /&gt;Then there is also applet-desc tag containing information about applet size, main class (App in our case), etc.&lt;br /&gt;&lt;br /&gt;The final step is to put this jnlp onto the website:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;applet width="640" height="480"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;param name="jnlp_href" value="demo.jnlp"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;param name="separate_jvm" value="true" /&amp;gt;&lt;br /&gt;&amp;lt;/applet&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;jnlp_href param is url to jnlp file.&lt;br /&gt;&lt;br /&gt;Now you can run your game in the website - ha!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8798708653413377465?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8798708653413377465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/03/how-to-make-3d-game-running-in-website.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8798708653413377465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8798708653413377465'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/03/how-to-make-3d-game-running-in-website.html' title='How to make 3D game running in a website? (or nGENE meets web)'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3313943886748320243</id><published>2010-02-28T12:04:00.000+01:00</published><updated>2010-02-28T12:04:46.971+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE update... at last</title><content type='html'>Ok, I've just committed to the SVN repository. Current version is 0.1.5 and you can download it from trunk or from this address:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://svn2.assembla.com/svn/ngene/tags/version-0.1.5"&gt;http://svn2.assembla.com/svn/ngene/tags/version-0.1.5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The list of changes is pretty long... a lot of fixes and improvements. The biggest addition is definitely animation system with skeletal animation and animation blending. It is still buggy and code is still ugly (cleaning it takes much more time than anticipated) but I will work hard on it starting from next week. From next week I will also start to work on more advanced animation techniques like ragdoll and inverse kinematics.&lt;br /&gt;&lt;br /&gt;Also SDK (with installer, exes and ready to use dlls) will be made available in two weeks time (I hope to release it next weekend but who knows what will happen during the week...).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;WARNING: if you use Visual Studio 2008 or newer you have to open project for VS 2005. This is because at my current computer I have no VS 2008/2010 installed... I will fix it soon.&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3313943886748320243?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3313943886748320243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/02/ngene-update-at-last.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3313943886748320243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3313943886748320243'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/02/ngene-update-at-last.html' title='nGENE update... at last'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7777984434044035228</id><published>2010-02-11T09:02:00.000+01:00</published><updated>2010-02-11T09:02:14.204+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Small delay regarding nGENE update</title><content type='html'>I promised to finally commit new release of nGENE this week. However, I'd forgotten about a little thing. Tomorrow I'm taking a week off (holidays!) and will have no access to my PC during it. It's therefore more probable that the update will be made available about 21st or 22nd February. There are a few things I still have to polish so I can't commit it today. Sorry for this delay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7777984434044035228?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7777984434044035228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/02/small-delay-regarding-ngene-update.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7777984434044035228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7777984434044035228'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/02/small-delay-regarding-ngene-update.html' title='Small delay regarding nGENE update'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5645038167391285762</id><published>2010-02-05T10:44:00.001+01:00</published><updated>2010-02-05T10:44:52.195+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Past awareness of AI</title><content type='html'>The technique I'm going to describe today is based on the article I've read some time ago. Sometimes it is desirable to give AI agents some sort of short-term memory to make them adapt to the player tactics or to the changes in their environment. For example in the FPS game bots could avoid those spots on the map where they have been killed a few times. Same would apply to choosing those places on the level from which it is easiest to get rid of the player.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;The application of the idea is tightly coupled to the map representation used in the game. In general, the concept is to put some spots on the map in which various statistics are gathered if event of specified type occurs (eg. kill). The placement of these spots as I said depends on the map representation. They can be uniformly distributed all over the level or they can be placed in the nodes of the navigation graph. If you have waypoints/fightpoints you can use them too.&lt;br /&gt;&lt;br /&gt;The results influence computations of various algorithms. For instance if A* algorithm is used for path planning then the cost of going through the given node could be modified based on the frequency of bot being spotted or killed at this very point (of course, proper values of modifiers have to be found in such a case). This way a bot would try to avoid this place but not at all cost. If there is no other way (or it would take too long) it will take the risk and go this path but it can for instance be more cautious, crouch and stop from time to time, seek for cover etc.&lt;br /&gt;&lt;br /&gt;Gathering of data can be done on the fly (i.e. as the game progresses) but it can also be done by developers to encode some data on the levels during development stage to give enemies better awareness of the environment and produce more challenging AI. This way not only will the bots behave more intelligently but also the control over them will be greater than in the completely procedural approach.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It is worth to note that this idea can be used in all sort of games, not only FPS. For example in RTS enemy can make traps in points through which player's troops ride and yet which is convenient to make a trap (eg. it is a forest passage or canyon).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;There will finally be update for nGENE (in about week or so). Pretty huge, containing animation (skeletal animation + animation blending, path following etc... however, IK will be implemented later but luckily I have already done this some time ago so I hope to reuse huge parts of it) and a lot of bug fixes and new stuff. I also made a decision of changing versioning scheme. Starting from this next update (version 0.1.5) the version changes will be much more frequent.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;As I'm really back to nGENE development now I will also post more technical (i.e. regarding engine development) entries again... and I'll start with the animation series (I'd promised article on this but haven't found time to do this earlier - sorry guys).&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5645038167391285762?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5645038167391285762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/02/past-awareness-of-ai.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5645038167391285762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5645038167391285762'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/02/past-awareness-of-ai.html' title='Past awareness of AI'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7821465012694897925</id><published>2010-01-31T20:54:00.005+01:00</published><updated>2010-05-15T12:15:10.072+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><title type='text'>Snow HDR once again</title><content type='html'>Today I once again tried to take some HDR photos with snow and ice as the main subject. Click the link below to open Picasa album or "read more" to view embedded slideshow:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/SnowHDR2?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh4.ggpht.com/_fbfW7HvrHa4/S2Xeq76w5vE/AAAAAAAAClY/Gzu7YWyax2k/s160-c/SnowHDR2.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.pl&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.pl%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5432993354712409841%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.pl/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7821465012694897925?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7821465012694897925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/snow-hdr-once-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7821465012694897925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7821465012694897925'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/snow-hdr-once-again.html' title='Snow HDR once again'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_fbfW7HvrHa4/S2Xeq76w5vE/AAAAAAAAClY/Gzu7YWyax2k/s72-c/SnowHDR2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7154101547722012666</id><published>2010-01-29T18:53:00.003+01:00</published><updated>2010-05-15T12:15:32.473+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><title type='text'>Snow HDR - another attempt</title><content type='html'>Today I had very good day. Not only I finally finished studies but also had a chance to capture some very nice photos. It was a sunny day and as there is a lot of snow and ice it was a promise of great pictures. For the very first time I was shooting HDRs using 3 RAWs (up to now I used 3 JPGs). There is some difference I must admit. One of the photos I consider my best HDR so far (guess which one :) ).&lt;br /&gt;&lt;br /&gt;So here are the results (click the link to visit Picasa or "read more" to view slideshow here):&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/SnowHDR?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh3.ggpht.com/_fbfW7HvrHa4/S2MdPwWxkZE/AAAAAAAACgc/GcdflXT2Tx8/s160-c/SnowHDR.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.pl&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.pl%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5432217732054618513%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.pl/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;I hope you like them :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7154101547722012666?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7154101547722012666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/snow-hdr-another-attempt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7154101547722012666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7154101547722012666'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/snow-hdr-another-attempt.html' title='Snow HDR - another attempt'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_fbfW7HvrHa4/S2MdPwWxkZE/AAAAAAAACgc/GcdflXT2Tx8/s72-c/SnowHDR.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1355308388803716202</id><published>2010-01-28T09:01:00.000+01:00</published><updated>2010-01-28T09:01:24.907+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Tiny planet technique</title><content type='html'>This is my first attempt at photography/postprocessing technique known as tiny planet (aka small planet).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/S2Cuo317mkI/AAAAAAAACcs/qjV638m_H-c/s1600-h/tiny_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/S2Cuo317mkI/AAAAAAAACcs/qjV638m_H-c/s320/tiny_1.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;div align="left" class="separator" style="clear: both; text-align: left;"&gt;It is not ideal but illustrates the concept nicely. Tiny planet is about turning a photo into a small planet. All you need is some wide panorama photo. It is highly recommended to use 180 or even 360 degrees panorama to get best results. I had no photo like that in my archives and no opportunity to take it so I went with a photo shot using 10mm focal length. Not ideal but after some tweaks I was able to use it.&lt;br /&gt;&lt;/div&gt;&lt;div align="left" class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left" class="separator" style="clear: both; text-align: left;"&gt;When you have a photo like that you have to follow 3 simple steps:&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li align="left" class="separator" style="clear: both; text-align: left;"&gt;Change image dimensions so they are equal. Proportions will be lost as height will be stretched but don't worry about that :)&lt;/li&gt;&lt;li align="left" class="separator" style="clear: both; text-align: left;"&gt;Flip the image in y axis.&lt;/li&gt;&lt;li align="left" class="separator" style="clear: both; text-align: left;"&gt;Apply polar coordinates.&lt;/li&gt;&lt;/ol&gt;&lt;div align="left" class="separator" style="clear: both; text-align: left;"&gt;Easy, isn't it?&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1355308388803716202?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1355308388803716202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/tiny-planet-technique.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1355308388803716202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1355308388803716202'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/tiny-planet-technique.html' title='Tiny planet technique'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/S2Cuo317mkI/AAAAAAAACcs/qjV638m_H-c/s72-c/tiny_1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7553159033650614771</id><published>2010-01-27T21:23:00.001+01:00</published><updated>2010-01-27T21:25:05.356+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Pixelize effect</title><content type='html'>Remember the times of the first 3D games on PC? Remember that photorealistic graphics? Yeah sure... now run your favorite game from the 90's... not looking good anymore, I guess :) ? About two years back I found an interesting effect on gamedev.net in some of the projects (don't remember the title unfortunately). The game was pretty modern, used all those fancy shaders but it looked as if it was from the times I'm writing about. Huge pixels were virtually everywhere! I decided to implement similar effect in nGENE and did it long time ago. I've never described it here so I'm doing it know. For your information - I'm not the author of the algorithm. I found it somewhere (book or article). Here is the result:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S2CFvuk-pnI/AAAAAAAACck/7onG8Ihn6fE/s1600-h/pixels.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S2CFvuk-pnI/AAAAAAAACck/7onG8Ihn6fE/s200/pixels.jpg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;With shaders achieving such an effect is relatively easy as a post-process effect (well you can also decrease resolution of course... but sometimes you may want to toggle only this effect). So you can still use all the HDRs, SSAOs and things like that and still make a game stylized like this.&lt;br /&gt;&lt;br /&gt;There are few simple steps to do this (let's suppose we want to achieve effect of having an image with dimensions = float2(80.0, 60.0) tiles):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Calculate size of a single tile ("pixel") as &lt;i&gt;size = float2(1.0, 1.0) / dimensions&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Calculate &lt;i&gt;pixel_base = IN.texCoord - fmod(IN.texCoord, size)&lt;/i&gt;. It is the upper left corner of a single tile (pixel). This way you will have only dimensions.x times dimensions.y different pixels.&lt;/li&gt;&lt;li&gt;Offset pixel_base by 0.5 * size. As this will be used as texture coordinates in the next step we thus simply make it a centre of the texel.&lt;/li&gt;&lt;li&gt;Sample your frame buffer at this point.&lt;/li&gt;&lt;/ol&gt;I know it is simple and useless for most of the time... but who cares :) .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7553159033650614771?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7553159033650614771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/pixelize-effect.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7553159033650614771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7553159033650614771'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/pixelize-effect.html' title='Pixelize effect'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/S2CFvuk-pnI/AAAAAAAACck/7onG8Ihn6fE/s72-c/pixels.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8222643281166213307</id><published>2010-01-23T08:05:00.009+01:00</published><updated>2010-01-24T08:18:20.699+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='common mistakes'/><title type='text'>Too much functionality evil</title><content type='html'>There is one common thing to all game designers of the world I think - they have this very tendency to put all their brightest ideas into the game. Or at least they want to... but luckily sometimes it is possible to force them not to do so (by telling them something is impossible for instance :) ). But lets put jokes aside and talk about this problem seriously. For many a designer, especially beginner ones, putting a lot of functionality and features into the game sounds and is cool. They claim: who wouldn't want to have a choice of 32 character classes, 200 spells and to have 100 enemies to fight with? When I was making my first game (cRPG) several years back I made the same mistake and after nearly 3 years of development decided to abandon the project.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;There are several problems related to such an approach:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;adding a single functionality requires in many cases new code (including scripts) to be written or assets to be prepared by artists. This makes development longer. The longer the development, the less competitive the game (technological side of things ages very quickly). If a functionality doesn't require such things it is not new at all.&lt;/li&gt;&lt;li&gt;balancing such a game is a real nightmare. More probable than not you'll end up with a game where certain items/weapons/spells/races/cars or their specific combinations are much more powerful than others... and so no one will even make any effort to use the rest (especially if you develop multiplayer focused game). Do you think that eg. Blizzard is not capable of providing 10 races instead of mere 3? The guys out there definitely have budget and time to do this but they are aware that they will ruin balance of the game (and giving Blizzard as an example here is done purposedly as their games are really well-balanced).&lt;/li&gt;&lt;li&gt;there is no real fun in playing such a game even though idea to put as much as possible to the game sounds pretty cool at first. Having too much choice will leave many players lost. Especially if new functionalities aren't added throughout the game but are available soon after the start.&lt;/li&gt;&lt;li&gt;many features means many places where bugs can be introduced. Testing it would be a lengthy process and it is hard to predict all possible scenarios. That is adding one functionality could result introduction of bugs in the other one.&lt;/li&gt;&lt;/ul&gt;The solution is pretty simple: write your ideas down, think about them for some time and rate them using 0 - 10 grades. Add only those features which have 10 mark, and consider for future addition those which reached 9.&lt;br /&gt;&lt;br /&gt;Thanks to all game designers I've worked with for inspiration to write this entry :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8222643281166213307?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8222643281166213307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/too-much-functionality-evil.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8222643281166213307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8222643281166213307'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/too-much-functionality-evil.html' title='Too much functionality evil'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5051262886115957814</id><published>2010-01-21T12:26:00.005+01:00</published><updated>2010-01-24T08:18:41.973+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gameplay'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Needs-driven AI</title><content type='html'>I'm recently putting some serious effort to deepen my knowledge of AI and techniques used for it in games as I came up with some interesting idea for a simple game (of course to be created using nGENE) and at first have to create simple prototype to see if it is playable at all or if it only my wrong impression. So from now on I'll write not only about 3D graphics, effects, photography and diving but also random thoughts and ideas on artificial intelligence :) Of course my concepts may seem a bit immature for regular AI developers so I'm open for suggestions.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;I gave some thoughts to the behavioural approach.&lt;br /&gt;&lt;br /&gt;The living organisms in general have &lt;i&gt;needs&lt;/i&gt; they have to fulfil. They feel (and so do we) hunger, thirst, fear, cold etc. To accomplish this they have to complete various tasks (&lt;i&gt;goals&lt;/i&gt;) built of smaller ones (&lt;i&gt;subgoals&lt;/i&gt;) which are in turn made of more or less atomic operations (&lt;i&gt;actions&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;Here is a short example:&lt;br /&gt;lets say there is a cat which is hungry and there is a mouse in the other room.&lt;br /&gt;&lt;br /&gt;A need is to eat (and thus reduce hunger) and the goal is to catch and finally eat the mouse. Prior to eating it, though, cat have to find a way to another room (besides if the room is locked, the cat will have to find out how to magically slip through the doors), spot the mouse, chase it for some time and catch it. These are subgoals. Actions here are movement, following, picking up an object (mouse), eating it etc.&lt;br /&gt;&lt;br /&gt;Sometimes there are multiple needs at a time and then the agent have to select which of them is of greater importance. To name basic needs one can use for instance Maslow's hierarchy of needs. According to it the more important ones are survival needs (for a mouse more important it would be to escape the cat than eat cheese and probably become dinner for somebody else at the same time) then follow safety needs, psychological needs (related to feelings and emotions) and other more and more abstract ones (eg. self-actualization). If there are several needs from the same hierarchy level active at the moment than the solution is to proceed with a more urgent one. If needs were described using 0 - 100 ratings where 0 means least and 100% urgency than it is pretty simple to choose next need to process. If there were many needs with the same rating then choosing them at random would be possible.&lt;br /&gt;&lt;br /&gt;Also lower priority needs (like need of self-development) and the associated goals can be thought of as some long-term plans. &lt;br /&gt;&lt;br /&gt;Goal which will help in fulfilling given need can be found in the goal space using any of popular heuristic algorithms (eg. A*). AI agent has to have opportunity to perceive and evaluate its environment to find its current needs and possible solutions to fulfil it. This in turn can be done using events mechanism ie. environment notifies agent of its state.&lt;br /&gt;&lt;br /&gt;I'm implementing some of the AI related things for nGENE but I think it won't be part of engine itself. Probably I make it downloadable as a separate library/module to make it more reusable and besides I don't want to put any gameplay elements into the core. Maybe I will put this code into the provided framework but it is still to be decided.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Besides it seems my simple &lt;a href="http://wtomandev.blogspot.com/2009/09/night-vision-effect.html"&gt;night vision technique I presented&lt;/a&gt; some time ago developed a bit and is now available for &lt;a href="http://www.geeks3d.com/20100119/night-vision-post-processing-shader-in-blender-game-engine/#more-6727"&gt;Blender game engine&lt;/a&gt;&lt;/b&gt; :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;I'm back to nGENE development. Now I'm moving my development environment to a much more powerful PC. nGENE should benefit from it, especially as it has 64-bit CPU and as far as I remember there were some issues on 64-bit architectures. Also different GPU will give me opportunity to finally get rid of some nasty artifacts which were found on some graphic cards above GF 9xxx series.&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5051262886115957814?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5051262886115957814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/needs-driven-ai.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5051262886115957814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5051262886115957814'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/needs-driven-ai.html' title='Needs-driven AI'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-5576547190348866077</id><published>2010-01-19T12:05:00.007+01:00</published><updated>2010-04-19T10:09:44.928+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Shaped Bokeh photography</title><content type='html'>During last weekend I decided to try yet another technique of taking photos, known as shaped bokeh. You can read about it in a number of places, eg. &lt;a href="http://lullaby.homepage.dk/diy-camera/bokeh.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bokeh in general is a term (originating from Japanese) meaning artistic blur in out of focus areas. This effect is achieved by pure photography - post-processing is not necessary.&lt;br /&gt;&lt;br /&gt;It looks especially well for weak light sources like lamps on the christmas tree which turn into circles.&lt;br /&gt;&lt;br /&gt;Here is an example photo I took:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/ShapedBokeh?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh4.ggpht.com/_fbfW7HvrHa4/S1Ra-CfEJhE/AAAAAAAACVk/PcNli5RN9R0/s160-c/ShapedBokeh.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;This bokeh thing normally would have more or less circular shape. The shaped bokeh in turn is a way to give it desired shape. I tried my hand with hearts (as you can see in the image above and stars but you can use whatever shape you want (I've seen as complex as leaves) provided you will be capable of shrinking it.&lt;br /&gt;&lt;br /&gt;The reason bokeh is circular is simple - it is the shape of the aperture hole (ok some lenses have polygonal aperture hole but still they approximate circle...). So the trick is to change aperture... or rather add another one. This is quite simple compared to changing aperture shape of the lens I believe :)&lt;br /&gt;&lt;br /&gt;To do this all you have to do is to take a small piece of black sheet, cut a circle from it with a diameter equal to lens diameter. In the middle of it you have to cut desired shape (eg. a star). Note it has to be pretty small - about diameter of aperture hole. The last step is to put it on a lens using tape. In the article I linked you can see more detailed instructions (with images!) on how to do this.&lt;br /&gt;&lt;br /&gt;Another important aspect is that you have to use lenses with pretty large aperture to get best results. Even though it is recommended to take photos using aperture of about f2.0 I succeeded with f4.5 (using tele lens about 150 mm focal length).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-5576547190348866077?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/5576547190348866077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/shaped-bokeh-photography.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5576547190348866077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/5576547190348866077'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/shaped-bokeh-photography.html' title='Shaped Bokeh photography'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_fbfW7HvrHa4/S1Ra-CfEJhE/AAAAAAAACVk/PcNli5RN9R0/s72-c/ShapedBokeh.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7154407250261535666</id><published>2010-01-03T16:18:00.013+01:00</published><updated>2010-01-03T21:21:35.504+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Water splashes</title><content type='html'>Yesterday I took some photos of fruit being dropped into the jug filled with water to capture splashes which it causes. The link to the Picasa album is below:&lt;br /&gt;&lt;br /&gt;&lt;table style="width: 194px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: transparent url(http://picasaweb.google.com/s/c/transparent_album_background.gif) no-repeat scroll left center; height: 194px;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/WaterSplashes?feat=embedwebsite"&gt;&lt;img height="160" src="http://lh4.ggpht.com/_fbfW7HvrHa4/Sz_KYBull9E/AAAAAAAACNo/_eCJqxj-x3A/s160-c/WaterSplashes.jpg" style="margin: 1px 0pt 0pt 4px;" width="160" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-family: arial,sans-serif; font-size: 11px; text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/tomanw/WaterSplashes?feat=embedwebsite" style="color: #4d4d4d; font-weight: bold; text-decoration: none;"&gt;Water splashes&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The idea was based on the &lt;a href="http://photo.tutsplus.com/tutorials/shooting-editing-a-high-speed-fruity-water-splash/"&gt;article I've recently read&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Here is how I setup the scene:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/S0Cy3_aNWDI/AAAAAAAACOg/mvGxSANmYu0/s1600-h/scene.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/S0Cy3_aNWDI/AAAAAAAACOg/mvGxSANmYu0/s320/scene.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I took photos in a complete darkness on the quite reflective table using external flash as the only source of light. Flash was triggered manually. To avoid too strong light I diffused it a little (in my case mere white paper sheet in front of flash did its job). Besides to have objects lit from both sides I used "reflector" - I just put a blanket of kitchen foil to the left of the object and opposite to the flash. Behind object I put black cover.&lt;br /&gt;&lt;br /&gt;I shot using manual mode (same for focusing of course). Exposure times were around 2 seconds with apperture set at about F14.&lt;br /&gt;&lt;br /&gt;The procedure to take a single photo is following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Set camera to remote triggering with a few seconds timer (10 in case of my Canon).&lt;/li&gt;&lt;li&gt;While timer is ticking take fruit and prepare to drop it into the jug.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When exposing a picure starts drop fruit.&lt;/li&gt;&lt;li&gt;When fruit hits water surface manually trigger flash.&lt;/li&gt;&lt;/ol&gt;I ended up with about 150 photos from which I chose 4 and processed them in Gimp.&lt;br /&gt;&lt;br /&gt;OK, I'm going back to nGENE :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7154407250261535666?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7154407250261535666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2010/01/water-splashes.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7154407250261535666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7154407250261535666'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2010/01/water-splashes.html' title='Water splashes'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_fbfW7HvrHa4/Sz_KYBull9E/AAAAAAAACNo/_eCJqxj-x3A/s72-c/WaterSplashes.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-623099522234203781</id><published>2009-12-31T17:00:00.026+01:00</published><updated>2010-01-03T11:26:42.709+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><title type='text'>CoD: Modern Warfare 2 rocks!</title><content type='html'>In the last few days I've been playing Call of Duty: Modern Warfare 2 and I have to say one thing - this game is awesome! Absolutely fantastic! Brilliant! Amazing... Even though I'm not a FPS fan of any sort and I prefer RPGs and strategy games and had been playing Dragon Age, I stopped to play CoD for "just a brief moment"... and I've been playing it ever since.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;This is one of only a few games which make you believe you're part of the action. It is hard to think different way when you see your alter ego falling into the abyss and being saved in the very last second by your companion or when you have to run away weaponless and injured from the local gang territory and finally to jump on full speed to the chopper (or into the void...). The impression of being there is therefore very strong.&lt;br /&gt;&lt;br /&gt;Even though the plot is a bit naive at times, it is packed with action, interesting battles with various enemies and sudden twist and turns. There is no place for boredom. In one moment you climb a mountain, then plant a bomb, and just a few minutes later you escape on the snowmobile riding crazily through the forest chased by countless enemies. There is a lot of a variety considering missions. Sometimes you just have to battle your way through the enemy troops, sometimes you have to rescue prisoner or catch a terrorist... There is also a very controversial mission in which you take part in the terrorist attack - on the bad guys' side... During the missions you use number of weapons and sometimes vehicles (not very often though). There is really a vast choice of tools of destruction :) from pistols to turrets and even predator drones... The game makes heavy use of scripts but it made it easier for designers to create interesting plot. But still AI agents behave in a quite intelligent way: they seek for cover, try to escape or hide when shot, try to flank, use smoke grenades (and then kill you easily thanks to thermal optics), etc.&lt;br /&gt;&lt;br /&gt;What is important for me as a graphics programmer is that this game is looking very well and besides runs smoothly (while still looking good) even on some older hardware configurations. That's really amazing - this game looks better than the majority of games available on the market and yet have higher framerate... Textures are of pretty high quality, most of the popular effects are used, animations look as if they were real and so on. It is really difficult to find something bad in the graphics. The only glitch I can think of is sky - it is pretty obvious it is a simple skydome/skybox.&lt;br /&gt;&lt;br /&gt;I'm not very competent when it comes to audio but for me everything sounds ok :)&lt;br /&gt;&lt;br /&gt;Summing up - this game is definitely above average. It is actually one of the best games I played in 2009. I really recommend it to everyone (of course above 18 years old line...) :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Soon - there will be some news on nGENE as I'm back to developing it (and make some serious progress :) ).&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-623099522234203781?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/623099522234203781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/12/cod-modern-warfare-2-rocks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/623099522234203781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/623099522234203781'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/12/cod-modern-warfare-2-rocks.html' title='CoD: Modern Warfare 2 rocks!'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8439126378711690277</id><published>2009-12-27T11:05:00.002+01:00</published><updated>2009-12-27T11:12:20.161+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='site'/><category scheme='http://www.blogger.com/atom/ns#' term='other'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Snow (rendering and photos) and some random ramblings</title><content type='html'>My diploma project is almost ready (more than 100 pages on pattern recognition techniques... maybe I'll succeed in publishing it here - it's a quite interesting graphs related subject - I'm still thinking if there are any possible uses for game development) &lt;b&gt;so I'll definitely have more time both for writing new entries here and what is even more important for nGENE development&lt;/b&gt; (I already started working on it after a break) as for the last two months I haven't worked much on it. &lt;br /&gt;&lt;br /&gt;Recently it was snowing a lot in Warsaw (and all over Europe and in some parts of USA I guess) so I had a chance to go and shoot some nice photos (results are by the end of this entry). I made some mistakes regarding white balance settings and exposure but all in all I managed to post-process them to such extent they resemble snow scenery.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;I want to write about something else this time, however. What struck me during walk through the snowdrifts is that there is no game with realistically looking snow... Really! Ok, there are some games looking good on a cloudy day but when it is sunny the results are not that convincing. Crysis had the best snow I can think of but... it was more like ice (same stands true for CoD: Modern Warfare 2 I'm currently playing). Sometimes it's even worse - developers put some texture with more or less white/blue/gray hue and they think it imitates snow well. It does not!&lt;br /&gt;&lt;br /&gt;Most of the implementations of the snow effect ignores one important aspect of real snow, namely that it reflects light in all possible directions making impression of tiny sparkles appearing all over the place. Snow on a sunny day behaves like millions of tiny crystals adding a lot of brilliance to the scene.&lt;br /&gt;&lt;br /&gt;I'm having several ideas on the matter and have to test them (first tests weren't successful to be honest).&lt;br /&gt;&lt;br /&gt;I also recently became interested in genetic algorithms and machine learning techniques. I came up with an idea for a simple game-experiment (or experiment-game - dunno what it'll be more). If only I found some time, I'll implement it (of course using nGENE as a presentation layer :) ).&lt;br /&gt;&lt;br /&gt;I also made a decision on making nGENE Toolset source code publicly available as several people asked me for it. I have to refactor it a bit first but it'll be ready for download in about a month I think.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IMPORTANT:&lt;/b&gt; One more thing. For anyone linking directly to my blog, if link to your site/blog doesn't appear in links section here just give me a hint and I'll add it. I want to be fair with you guys.&lt;br /&gt;&lt;br /&gt;And here are the pics:&lt;br /&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5419140648598337361%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8439126378711690277?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8439126378711690277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/12/snow-rendering.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8439126378711690277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8439126378711690277'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/12/snow-rendering.html' title='Snow (rendering and photos) and some random ramblings'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4485924685120396803</id><published>2009-12-12T15:38:00.001+01:00</published><updated>2009-12-14T17:07:45.802+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><title type='text'>HDR + Wide-angle</title><content type='html'>I wrote about HDR photography several times before. Recently I bought new wide-angle lens and today had a chance to shoot some photos with it. The day was rather dull but I succeeded&amp;nbsp; in taking a few pictures. They are also available &lt;a href="http://picasaweb.google.com/tomanw/HDRWarsaw#"&gt;in my picasa album&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5414353920222527169%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;EDIT: yesterday I uploaded a few more photos to the HDR album. I hope you will also like them.&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4485924685120396803?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4485924685120396803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/12/hdr-wide-angle.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4485924685120396803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4485924685120396803'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/12/hdr-wide-angle.html' title='HDR + Wide-angle'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1625775294035252730</id><published>2009-11-27T15:37:00.000+01:00</published><updated>2009-11-27T15:37:05.453+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Changes, changes, changes</title><content type='html'>Hi all! I'm pretty busy recently so I don't have that much time to write new entries here. I finally found new job in Poland. It's not in gamedev but still I'm working on something what is pretty interesting and different from what I did up to now. I'm also busy with my diploma project regarding patterns recognition using graph-based approach (graph similarity measuring and matching to be more exact). Those are the reasons why I'm not making any updates to nGENE Tech but I soon will get back to it. So stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1625775294035252730?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1625775294035252730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/11/changes-changes-changes.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1625775294035252730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1625775294035252730'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/11/changes-changes-changes.html' title='Changes, changes, changes'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6480370824382174708</id><published>2009-10-18T14:15:00.006+02:00</published><updated>2009-10-18T14:20:34.229+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='procedural'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Creation and rendering of clouds</title><content type='html'>A few days ago I promised to write a short description of the technique I used for creating nGENE Tech dynamic clouds. I believe they look pretty ok and the technique itself isn't that complicated even though it may sound scary for some people at first (greetings goes to &lt;a href="http://vipagames.pl/"&gt;Vipa&lt;/a&gt; - Polish indie games developer :) ).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/StckYqL7WCI/AAAAAAAAB7o/hKCQo3galxs/s1600-h/nGENE_0401.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/StckYqL7WCI/AAAAAAAAB7o/hKCQo3galxs/s320/nGENE_0401.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;As always for clouds generation I used Perlin noise which allows creating a basic shape of the clouds (and other things like marbles, fire etc. :) ). I simply followed the guidelines of &lt;a href="http://www.noisemachine.com/talk1/" target="_blank"&gt; Ken Perlin&lt;/a&gt; i.e. what we have to do is to sum a few noise octaves with different weights and frequencies like that:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;table border="0" cellpadding="0" cellspacing="0" height="141" style="border-collapse: collapse; width: 220px;"&gt;&lt;col style="width: 57pt;" width="76"&gt;&lt;/col&gt;  &lt;col span="2" style="width: 54pt;" width="72"&gt;&lt;/col&gt;  &lt;tbody&gt;&lt;tr height="21" style="height: 15.75pt;"&gt;   &lt;td class="xl70" height="21" style="height: 15.75pt; text-align: center; width: 57pt;" width="76"&gt;&lt;b&gt;octave ID&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl69" style="text-align: center; width: 54pt;" width="72"&gt;&lt;b&gt;frequency&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl70" style="border-left: medium none; text-align: center; width: 54pt;" width="72"&gt;&lt;b&gt;weight&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl71" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;1&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl67" style="text-align: center;"&gt;1&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl68" style="border-left: medium none; text-align: center;"&gt;0.5&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl72" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;2&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl66" style="border-top: medium none; text-align: center;"&gt;2&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl65" style="border-left: medium none; border-top: medium none; text-align: center;"&gt;0.25&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl72" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;3&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl66" style="border-top: medium none; text-align: center;"&gt;4&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl65" style="border-left: medium none; border-top: medium none; text-align: center;"&gt;0.125&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl72" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;4&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl66" style="border-top: medium none; text-align: center;"&gt;8&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl65" style="border-left: medium none; border-top: medium none; text-align: center;"&gt;0.0625&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl72" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;5&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl66" style="border-top: medium none; text-align: center;"&gt;16&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl65" style="border-left: medium none; border-top: medium none; text-align: center;"&gt;0.03125&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="height: 14.25pt;"&gt;   &lt;td class="xl73" height="19" style="border-top: medium none; height: 14.25pt; text-align: center;"&gt;…&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl66" style="border-top: medium none; text-align: center;"&gt;…&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl65" style="border-left: medium none; border-top: medium none; text-align: center;"&gt;…&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;I won't cover this step in details as it is described in a number of other places.&lt;br /&gt;&lt;br /&gt;The number of octaves impacts clouds quality and unfortunately performance (and at some point the quality improvement is negligible but the cost of computing this iteration - is definitely not). If we used such a plain algorithm we would achieve something like the "clouds" in the image below:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SPB18kftiXI/AAAAAAAAAh8/EPvopt0SNLc/s1600-h/clouds.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5255830448590653810" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SPB18kftiXI/AAAAAAAAAh8/EPvopt0SNLc/s200/clouds.jpg" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;These clouds are definietely not convicing enough to be used in modern games as they are flat and have unnatural shade. Once I overcame this using several photographs of real clouds for different weather as textures which I then sampled in pixel shader and added this sampled value to the final result. But it was several years back and now even that is not enough.&lt;br /&gt;&lt;br /&gt;What makes clouds look so 3D as they look? The answer is simple. Light. Each ray going through the cloud is scattered, reflected and refracted on the water drops. Simulating this would be too computationally expensive for games of course as there are too many drops and rays (from point of view of games they are infinite) so a different solution had to be proposed.&lt;br /&gt;&lt;br /&gt;And Jean-Francois Dube came with it. He claimed that it is sufficient to make cloud darker in the areas where it is denser (in the middle) to simulate self shadowing this way. Look at the image below:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/SPB2Ggt6anI/AAAAAAAAAiE/fh_dUQTtpBk/s1600-h/cloud_sketch.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5255830619375168114" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/SPB2Ggt6anI/AAAAAAAAAiE/fh_dUQTtpBk/s200/cloud_sketch.jpg" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;The cloud should be almost white at the left edge but should be much darker in the position of point P. Besides the rays come from the left so the right edge also should be in shadow (I mean darker).&lt;br /&gt;&lt;br /&gt;What we have to do to simulate such shading is to trace a ray from the Sun position to the lower part of the cloud (denoted by P point). So we basically sample our height-map several times (I use as many as 64 iterations in nGENE) and test if a ray is currently inside the cloud i.e. a value sampled from height-map is greater than 0 (or some other threshold). If it is, we increase cloud density value by the value read multiplied by some parameter (0.1 for instance).&lt;br /&gt;&lt;br /&gt;But wait a moment. I mentioned some height-map. Yes, we'll need one here. The easiest way to get it is to render Perlin noise to texture. And then in the second pass to ray trace it. This first step is only required when a new height-map is needed what is not that frequent and I'll come to it at the end of this entry. The height-map creation step should use lesser number of octaves as otherwise some nasty aliasing artifacts will occur (number from 4 to 8 works well in most cases). The resolution of height-map is also of your choice and influences quality of the result. For some scenes 256x256 will suffice, for others 1024x1024 would be preferrable.&lt;br /&gt;&lt;br /&gt;After when we know final density at a given point we have to calculate real scattering as:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;scattering = 1.0f / exp(density * 0.4f);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Some magic going on here. Well you can alter these magic number but it works ok for me (and someone, namely Dube, probably spent some time choosing the right values). &lt;br /&gt;But that's only a beginning. Now we have shadowed clouds but they don't change colour during the day whereas they should have pink colour in the morning and red during sunset. So they still look unnatural. What I did was simple. I picked three clouds colours for different day phases:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;for the morning (pink),&lt;/li&gt;&lt;li&gt;for the noon (white),&lt;/li&gt;&lt;li&gt;for the sunset (almost red... sometimes some orangish colour will also do).&lt;/li&gt;&lt;/ul&gt;This way we have &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;cloudColour&lt;/span&gt; value I'll use later.&lt;br /&gt;&lt;br /&gt;These values I obtained from several photos I got from around the web. According to the time of the day I just interpolate between them. More clever solution would be to have a 1D texture with colour values for each hour. If I find some time, I will create it and submit it here.&lt;br /&gt;&lt;br /&gt;Now another observation is that clouds colour varies over the sky (it is most vivid where sun rays point and fades towards horizon). According to the cloud image earlier the parts of the clouds opposite the sun are in shadow.&lt;br /&gt;&lt;br /&gt;If we think of the sky as of a rectangle with real coordinates ranging 0 to 1 the sun during a day (moving from east to the west) will have a position of [ x, 0.5 ] on it at a given time of day. "x" will change during the day to simulate the sun movement and it'll be 0 at dawn and 1 at dusk. The very other coordinate can stay constant for simplicity reasons. Now these coordinates coorespond to the texture coordinates of the sky dome object. For any given time of day clouds have a given colour where there is sun and they change colour to white away from it. Besides farther from the sun the clouds become more transparent (especially on the horizon). So for each pixel we can find how far away it is from current sun position by:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;distance = length(IN.textureCoordinates - sunPosition);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And then interpolate:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;colour = lerp(cloudColour, 1, distance);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here I don't test if distance is greater than 0 nor I normalize anything (I do it a bit differently in nGENE shaders) but I just want to show general idea. &lt;br /&gt;&lt;br /&gt;So far so good. But clouds would be boring if they would be the same all the time. So two more things do are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;change texture coordinates to simulate wind,&lt;/li&gt;&lt;li&gt;store two clouds textures at a time and lerp between them to make clouds change their shape, density, cover etc. These would require updating clouds textures but it is not that frequent to be costly (unless you want to do it every frame... but in most cases updating them every a dozen or so seconds works well).&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/StsGZ6t2ndI/AAAAAAAAB7w/QCNbOchqTFQ/s1600-h/nGENE_0398.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/StsGZ6t2ndI/AAAAAAAAB7w/QCNbOchqTFQ/s200/nGENE_0398.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6480370824382174708?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6480370824382174708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/making-clouds.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6480370824382174708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6480370824382174708'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/making-clouds.html' title='Creation and rendering of clouds'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/StckYqL7WCI/AAAAAAAAB7o/hKCQo3galxs/s72-c/nGENE_0401.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1973004102569341718</id><published>2009-10-13T22:08:00.006+02:00</published><updated>2009-10-13T22:11:37.617+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='procedural'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>nGENE clouds finished, new site's record</title><content type='html'>Just to keep you updated. It's the final appearance of clouds in nGENE. I'll leave them as they look for some time. This ugly textured ship is just added because I don't like screens without foreground.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/StTcg7S0JDI/AAAAAAAAB7g/mbE-jt0IfL0/s1600-h/nGENE_0403.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/StTcg7S0JDI/AAAAAAAAB7g/mbE-jt0IfL0/s320/nGENE_0403.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Detailed description of the way I achieved such an effect will be provided shortly. For now saying that they are done using Perlin noise will suffice though.&lt;br /&gt;&lt;br /&gt;BTW yesterday more than 600 unique visitors visited this blog (with more than 1500 page loads). Thank you all. That's always nice to post here with hope that someone will read it.&lt;br /&gt;&lt;br /&gt;I also added my &lt;a href="http://ngene.wdfiles.com/local--files/start/CV_En.pdf"&gt;CV&lt;/a&gt; to this site if anyone cares :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1973004102569341718?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1973004102569341718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/ngene-clouds-finished-new-sites-record.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1973004102569341718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1973004102569341718'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/ngene-clouds-finished-new-sites-record.html' title='nGENE clouds finished, new site&apos;s record'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/StTcg7S0JDI/AAAAAAAAB7g/mbE-jt0IfL0/s72-c/nGENE_0403.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3741858438608837742</id><published>2009-10-11T22:05:00.001+02:00</published><updated>2009-10-13T21:59:44.476+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='procedural'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE clouds improved</title><content type='html'>There was something about nGENE clouds I didn't like... so I spent about 3hrs today fixing them. Now they finally work with HDR and in general look better than they ever had. I also optimized them a little.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/StI5R1oHuRI/AAAAAAAAB7Y/WjEbydJ3TNg/s1600-h/nGENE_0392.jpg" imageanchor="1" style="clear: left; float: left;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/StI5R1oHuRI/AAAAAAAAB7Y/WjEbydJ3TNg/s200/nGENE_0392.jpg" /&gt;&lt;/a&gt; &lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/StI5JHZW_pI/AAAAAAAAB7Q/XjK3uSOUpWI/s1600-h/nGENE_0385.jpg" imageanchor="1"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/StI5JHZW_pI/AAAAAAAAB7Q/XjK3uSOUpWI/s200/nGENE_0385.jpg" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3741858438608837742?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3741858438608837742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/ngene-clouds-improved.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3741858438608837742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3741858438608837742'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/ngene-clouds-improved.html' title='nGENE clouds improved'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/StI5R1oHuRI/AAAAAAAAB7Y/WjEbydJ3TNg/s72-c/nGENE_0392.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-9154688600472941163</id><published>2009-10-10T13:12:00.017+02:00</published><updated>2009-10-11T13:35:42.341+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Depth of Field</title><content type='html'>Time for a description of another &lt;a href="http://ngene.wikidot.com/"&gt;nGENE&lt;/a&gt; effect. This time I'll write about depth of field effect which is useful to emphasize importance of part of the scene.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/StBqCzl6niI/AAAAAAAAB6Y/nV6xzQGZn34/s1600-h/nGENE_0369.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/StBqCzl6niI/AAAAAAAAB6Y/nV6xzQGZn34/s320/nGENE_0369.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;This effect, as many others, have its origins in photography. By playing with aperture denoted by f-numbers you can focus on any single element be it a flower as in this photo:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBIV5rzw3I/AAAAAAAAB6I/ARmvNI_0T00/s1600-h/IMG_4122.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBIV5rzw3I/AAAAAAAAB6I/ARmvNI_0T00/s320/IMG_4122.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Or a drop:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/StBJsMfnctI/AAAAAAAAB6Q/GwwcfcgYxFo/s1600-h/IMG_4371.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/StBJsMfnctI/AAAAAAAAB6Q/GwwcfcgYxFo/s320/IMG_4371.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;In the above photos I took some time ago we would say that depth of field is shallow (or very shallow in the last image) what is equivalent to shallow focus. Same is true for the rock from nGENE at the beginning of this post. On the other side for lanscapes for example we want to have focus on as much as possible (well at least usually...) so we will have deep depth of field (or deep focus). In photography it comes at no cost. Actually it is only a side-effect to how lenses work.&lt;br /&gt;&lt;br /&gt;But what it can be used for actually? First of all when you want to empasize difference between foreground (or an actor) and the background. Whether it is a model in the portrait or a viewfinder of a sniper rifle in a game, you want it in focus whereas background can be blurred. By focusing on this element we force viewer to look at it, to pay attention to it. We deliver him a message that the rest of the scene is of lesser importance.&lt;br /&gt;&lt;br /&gt;You'd be amazed how many formulae are involved in the depth of field calculation. So I skip this step and we'll do it intuitively. We want simply to have an object at a given distance in focus. Scene in front and behind it should be blurred and the blur strength should be greater, the greater the distance from this focus point is.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Implementation details&lt;/span&gt;&lt;br /&gt;To implement depth of field effect we have to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Downsample the base scene image.&lt;/li&gt;&lt;li&gt;Blur this image horizontally and vertically using gaussian blur.&lt;/li&gt;&lt;li&gt;Composite the image.&lt;/li&gt;&lt;/ol&gt;Ad. 1. that is pretty obvious. I use 1/4th of the base image size.&lt;br /&gt;Ad. 2. sometimes it might be preferrable to use smart blurring to avoid colour bleeding artifacts. To do this you have to take normals and/or depth values into account. However, thresholds are of your choice. For some scene some values work better than others so it is really hard to give any golden values here.&lt;br /&gt;Ad. 3. Composition is where all real magic happens. At this step we have two images:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Base image,&lt;/li&gt;&lt;li&gt;Downsampled and blurred image.&lt;/li&gt;&lt;/ul&gt;We will also need depth map of the scene at this stage.&lt;br /&gt;&lt;br /&gt;By clever joining them we will achieve depth of field effect. How? Well lets first assume that we want image to be in focus at distance "focus". Also between (near; far) the effect is getting sharper the nearer the depth at this point is to focus value. Outside of this range image is completely blurred.&lt;br /&gt;&lt;br /&gt;This HLSL snippet will do this job:&lt;br /&gt;&lt;pre class="Cpp" name="code"&gt;float factor = 0.0f;&lt;br /&gt;if(depth &amp;lt; focus)&lt;br /&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; factor = (focus - depth) / (focus - near);&lt;br /&gt;}&lt;br /&gt;else if(depth &amp;gt; focus)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; factor = (depth - focus) / (far - focus);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; factor = clamp(factor, 0.0f, focalScale);&lt;br /&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;float4 result = float4(lerp(scene.xyz, blur.xyz, factor), 1.0f);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The only value I haven't covered so far is focalScale. It is a simple threshold. Set it to 0.0 and everything will be in focus. Set it to 1.0 and maximum blur will be used outside of the range mentioned.&lt;br /&gt;&lt;br /&gt;There are some limits to all of these values:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;near is in range (0; focus),&lt;/li&gt;&lt;li&gt;far is in range (focus; infinity)&lt;/li&gt;&lt;li&gt;focus is in range (near; far)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Underneath is also short movie presenting alteration of all of the parameters (near, far and focus distance):&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7z-bRNT6JvE&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/7z-bRNT6JvE&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;At the end comparison of two different DoF settings:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBv9cihd9I/AAAAAAAAB6g/RhsljJ7FGvs/s1600-h/nGENE_0373.png" imageanchor="1"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBv9cihd9I/AAAAAAAAB6g/RhsljJ7FGvs/s200/nGENE_0373.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBwIfg9f0I/AAAAAAAAB6o/474aT31_K_E/s1600-h/nGENE_0376.png" imageanchor="1"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/StBwIfg9f0I/AAAAAAAAB6o/474aT31_K_E/s200/nGENE_0376.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;And in one image:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/StByjA5RiRI/AAAAAAAAB6w/XKhVTc4eqYw/s1600-h/gamedev.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/StByjA5RiRI/AAAAAAAAB6w/XKhVTc4eqYw/s320/gamedev.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-9154688600472941163?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/9154688600472941163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/depth-of-field.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9154688600472941163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/9154688600472941163'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/depth-of-field.html' title='Depth of Field'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbfW7HvrHa4/StBqCzl6niI/AAAAAAAAB6Y/nV6xzQGZn34/s72-c/nGENE_0369.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3941542811650477935</id><published>2009-10-08T17:56:00.008+02:00</published><updated>2009-10-08T18:00:40.682+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Some new nGENE screenshots</title><content type='html'>Today I took a break from fightning with animation system (.x file parsing to be precise... I start to believe it's pure evil avoid using it at all cost! :) ) and optimized a few shaders and improved a few others. Here are some new screenshot I took:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/Ss4KS9Y23vI/AAAAAAAAB5Q/BelNWstxMOM/s1600-h/nGENE_0326.jpg" style="float: left;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/Ss4KS9Y23vI/AAAAAAAAB5Q/BelNWstxMOM/s200/nGENE_0326.jpg" /&gt;&lt;/a&gt; &lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/Ss4KYqbl6DI/AAAAAAAAB5Y/9ZClj5cAxLE/s1600-h/nGENE_0335.jpg" style="float: left;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/Ss4KYqbl6DI/AAAAAAAAB5Y/9ZClj5cAxLE/s200/nGENE_0335.jpg" /&gt;&lt;/a&gt; &lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/Ss4KlMPBcxI/AAAAAAAAB5o/rmXQbqhMhLc/s1600-h/nGENE_0322.jpg" imageanchor="1" style="float: left;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/Ss4KlMPBcxI/AAAAAAAAB5o/rmXQbqhMhLc/s200/nGENE_0322.jpg" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/Ss4KhCH4RPI/AAAAAAAAB5g/o0X3SzQsI-s/s1600-h/nGENE_0342.jpg" imageanchor="1" style="float: left;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/Ss4KhCH4RPI/AAAAAAAAB5g/o0X3SzQsI-s/s200/nGENE_0342.jpg" /&gt;&lt;/a&gt; &lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/Ss4Kynl2T0I/AAAAAAAAB54/JU39VI5-X8I/s1600-h/nGENE_0343.jpg" imageanchor="1" style="float: left;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/Ss4Kynl2T0I/AAAAAAAAB54/JU39VI5-X8I/s200/nGENE_0343.jpg" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/Ss4KtWNuFKI/AAAAAAAAB5w/haf2OPbfZLE/s1600-h/nGENE_0360.jpg" imageanchor="1" style="float: left;;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/Ss4KtWNuFKI/AAAAAAAAB5w/haf2OPbfZLE/s200/nGENE_0360.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;For more new screenshots visit &lt;a href="http://ngene.wikidot.com/effects"&gt;nGENE gallery&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3941542811650477935?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3941542811650477935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/some-new-ngene-screenshots.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3941542811650477935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3941542811650477935'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/some-new-ngene-screenshots.html' title='Some new nGENE screenshots'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/Ss4KS9Y23vI/AAAAAAAAB5Q/BelNWstxMOM/s72-c/nGENE_0326.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2855614508702396132</id><published>2009-10-08T13:13:00.003+02:00</published><updated>2009-10-08T13:14:55.807+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Thermal Vision effect</title><content type='html'>Recently I posted an entry about implementation of &lt;a href="http://wtomandev.blogspot.com/2009/09/night-vision-effect.html"&gt;night vision effect&lt;/a&gt;. There is one more effect which is similar in implementation to it and yet visually totally different - thermal vision effect. Maybe a screen below is not of the best choice but I cannot find time right now to take another better suiting one:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/Ss2_32uEjFI/AAAAAAAAB5A/ouiqp9YBT-Q/s1600-h/nGENE_0321.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/Ss2_32uEjFI/AAAAAAAAB5A/ouiqp9YBT-Q/s320/nGENE_0321.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;This effect is present in nGENE for quite a time (since the very first tech demo actually) but I've never described it in details before. Belive me - it is really simple!&lt;br /&gt;&lt;br /&gt;First of all, we have to note that this effect is based on the emission of heat by various scene objects (I was not interested in physically proper model though). The value of emitted heat which I'll henceforward call radiation, is mapped to the appropriate colour where coolest objects are blue and hottest ones - red. The scale might look like this (it's basically a 1D texture):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/Ss26NT2-FjI/AAAAAAAAB44/SD0fIGlFpjo/s1600-h/thermal.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/Ss26NT2-FjI/AAAAAAAAB44/SD0fIGlFpjo/s320/thermal.bmp" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;But how to know what is the radiation value of a given object? Well one can use a special additional map presenting heat emission. It is especially useful for objects with non-uniform heat radiation (like humans' or animals' bodies) but often simpler approach will do. As I use deferred shading I was not really eager to sacrifice one value in G-Buffer specifically for keeping heat emission (as it is not that often used as specular or normals for instance) so I went with another approach.&lt;br /&gt;&lt;br /&gt;As I use HDR I have emission value stored in the G-Buffer but one responsible for light emission not heat... but hey what's the difference really? Usually the more light the object emmitts the warmer it is. Light emission can also mean light reflection (or at least we can interpret it this way). But then what about humans? As far as I know we don't emit light, do we? But still for human bodies (nor for any other objects) the value won't be 0 as otherwise dynamic light adaptation in HDR effect will treat them as completely black... So far so good then.&lt;br /&gt;&lt;br /&gt;But still to make it more appealing I decided to take normal vectors into account. I add dot product of eye vector and normal to the radiation value. Finally I desaturate the pixel to find its luminosity and multiply radiation by it.&lt;br /&gt;&lt;br /&gt;Look again at the screen I posted. It is quite easy to guess where the sun is. It has to be in the invisible part of the screen (opposite to the scene presented). What's more, stones are definitely warm (try to touch one on a sunny day!) same for the house roof. Grass is rarely that warm and tree bark is warm but not hot at most of the times. Ground is usually warm and sky is definitely cold... so it seems it works pretty ok.&lt;br /&gt;&lt;br /&gt;Noise can be achieved same way as I described it in a post about night vision.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2855614508702396132?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2855614508702396132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/thermal-vision-effect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2855614508702396132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2855614508702396132'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/thermal-vision-effect.html' title='Thermal Vision effect'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/Ss2_32uEjFI/AAAAAAAAB5A/ouiqp9YBT-Q/s72-c/nGENE_0321.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1742956293356294188</id><published>2009-10-07T16:25:00.000+02:00</published><updated>2009-10-07T16:25:02.917+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>Some minor changes to the site</title><content type='html'>I fixed a few things on this blog. First of all I removed some of the Polish words appearing here and there (Blogger was restoring some fields' values all the time to their defaults... don't know why). I also added "Read more" link to the most recent entries, so you don't have to scroll for a minute to skip uninteresting and yet lengthy entries.&lt;br /&gt;&lt;br /&gt;I also added backlinks option (doesn't work for Opera... at least for me) and Opinion field. I'd be grateful for ticks as it would tell me if what I write here is of any interest :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1742956293356294188?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1742956293356294188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/some-minor-changes-to-site.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1742956293356294188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1742956293356294188'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/some-minor-changes-to-site.html' title='Some minor changes to the site'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4554409354157004931</id><published>2009-10-05T19:09:00.000+02:00</published><updated>2009-10-07T11:22:34.950+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Just a small picture</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SsonW2tBIqI/AAAAAAAAB4o/EFBdT3Y99pU/s1600-h/nGENE_0320.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SsonW2tBIqI/AAAAAAAAB4o/EFBdT3Y99pU/s400/nGENE_0320.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I have not much to write this time. I'm fixing, improving and busy with animations (it takes more time than I estimated but soon it should be production ready). So I just grabbed this picture from nGENE. It's getting better and better each day :) All of the trees are rendered with full geometry (I should provide progressive mesh mechanism and turn them into billboards at the distance but it can wait... animations can't) so it kills performance pretty nicely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4554409354157004931?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4554409354157004931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/just-small-picture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4554409354157004931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4554409354157004931'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/just-small-picture.html' title='Just a small picture'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/SsonW2tBIqI/AAAAAAAAB4o/EFBdT3Y99pU/s72-c/nGENE_0320.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4869291188404818401</id><published>2009-10-02T19:29:00.004+02:00</published><updated>2009-10-07T11:45:15.744+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Virtual File System</title><content type='html'>Having hundreds or even thousands (or even worse hundreds of thousands...) of files in any game directory has many drawbacks:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It takes longer to install a game as copying many small files is usually slower than copying several larger ones,&lt;/li&gt;&lt;li&gt;Loading a single file takes longer (as we have to open, read and close each of them),&lt;/li&gt;&lt;li&gt;We can run out of possible file handles (as OS limits their number... at least Windows),&lt;/li&gt;&lt;li&gt;Modifying game content and what's worse game scripts is relatively easy as access to them is not secured by any means what especially in case of MMO games can have some serious consequences,&lt;/li&gt;&lt;li&gt;If you want to secure or compress game files you have to do it on a per-file basis.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;For me there is one more disadvantage. I always keep forgetting about including some of the files when submitting &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech demos&lt;/a&gt; and receive many e-mails that demo is not working due to lack of "grass.bmp" texture or something like that (of course I should ensure that missing texture doesn't crash a whole thing but who would care about such things in simple demo).&lt;br /&gt;&lt;br /&gt;VFS (&lt;span style="font-style: italic;"&gt;Virtual File System&lt;/span&gt;) to the rescue. What is OS File System is crystal clear. However, Virtual File System is a bit different. It is basically one, more often than not, large file called a resource file or an archive in which data of other files is stored. As each file (called entry or lump) in the resource file is described using several attributes such as name (or hash of it but we'll come back to it later), size and offset from the beginning, it is possible to easily obtain files stored within and for the engine it works as regular OS folder. Examples of resource files are .zip and .rar but it is quite easy to create something simple on your own and I decided on the latter for nGENE (at first I was considering zlib library for compression but, hell I don't like it due to its API).&lt;br /&gt;&lt;br /&gt;Simple resource file might look like this (I put my brief comments in the square brackets):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[File header section]&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;version ID - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;flags - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;total number of files - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MD5 hash [to detect any unauthorized changes to the file] - 16 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;...&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[File table section]&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File1 name&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File1 size - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File1 data offset - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File2 name&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File2 size - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File2 data offset - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;...&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FileN name&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FileN size - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FileN data offset - 4 bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[File data]&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File1 data - File1 size bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;File2 data - File2 size bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;...&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FileN data - FileN size bytes&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;As you can see resource file begins with a regular header. It contains such useful information as version (necessary to inform users that the archive they use is outdated or to keep backward compatibility), flags (which tell if the files within resource file are encrypted or compressed), total number of files in the resource file (pretty obvious, eh?).&lt;br /&gt;&lt;br /&gt;Then goes file table which contains general information about all the files like their names, size and offsets (and maybe some file specific flags - I come to it later) which tell where the data begins relatively to the resource file beginning. Instead of name you could use some kind of hash (&lt;a href="http://dabroz.scythe.pl/2008/07/17/wirtualny-system-plikow-vfs"&gt;Dabroz&lt;/a&gt; from Polish gamedev community suggested using MD5 here, pretty nice idea but sometimes it is useful to have access to the original names and for debugging purposes it's sometimes easier than trying figuring out what this A35gaeT68h468... thing really stands for).&lt;br /&gt;&lt;br /&gt;Last part of resource file is pure data. It is data which was contained in the original files but here it is one consistent block of bytes perhaps encrypted or compressed but it depends on the flags I mentioned.&lt;br /&gt;&lt;br /&gt;In nGENE I went with the format specified above as I only required something simple (but as nGENE is easily extensible one can provide their own archivers simply and probably I'll provide something else in the future). I wanted to provide as transparent solution for programmers as possible and I believe it works pretty well. Well at least I'm happy with the results :)&lt;br /&gt;&lt;br /&gt;As for the compression I went with a combination of following algorithms (the order is important) I described in the last few weeks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wtomandev.blogspot.com/2009/09/burrows-wheeler-transform.html"&gt;Burrows-Wheeler Transform&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href="http://wtomandev.blogspot.com/2009/09/move-to-front.html"&gt;Move-to-Front&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href="http://wtomandev.blogspot.com/2009/09/run-length-encoding.html"&gt;Run-Length Encoding&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href="http://wtomandev.blogspot.com/2009/09/huffman-coding.html"&gt;Huffman Coding&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;The results are pretty nice. For the nGENE's 'media' folder (that is all the shaders, models, sounds and textures) I got the compression ratio of more than 60% (of course for individual files it can be higher or lower)! Even though many of the files were already compressed on their own. I also use file specific flags to disable compression for these files for which memory save is none or minimal so I can skip costly decompression process for them.&lt;br /&gt;&lt;br /&gt;I also changed "my screenshots" slideshow on the site. I recently found out that it shows only dozen or so recent images but I believe I made some nice pictures earlier too so I switched to the flickrSLiDR which doesn't have this limitation. Also size of the screenshots is larger now so they look better than before.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;EDIT:&lt;/b&gt;&lt;br /&gt;I forgot to give any compare values for the compression I implemented so I did another test (with folder containing a lot of files... not only game files this time):&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;compression ratio = (compressed file size) / (original file size)&lt;/span&gt;.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;with .rar (normal) I got - 37% compression ratio,&lt;/li&gt;&lt;li&gt;with .rar (best) I got -36% compression ratio (almost same as above),&lt;br /&gt;&lt;/li&gt;&lt;li&gt;with .zip (normal) I got - 47% compression ratio,&lt;/li&gt;&lt;li&gt; with .zip (best) I got - 47% compression ratio (almost same as above),&lt;/li&gt;&lt;li&gt;with .7z I got - 32% compression ratio.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;For my own implementation I got 41%. 7z gave the best results but it is no surprise as it uses better substring removal algorithm. nGENE uses plain Run-Length Encoding (which removes only runs of same characters but not longer substrings like ABABABAB) whereas 7z makes use of dictionary based methods. I considered this but the drawback is that dictionary has to be stored somewhere. Also nGENE implementation performs significantly better than popular zip compression (what surprised me a bit :) ) and not that much worse than .rar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4869291188404818401?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4869291188404818401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/10/virtual-file-system.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4869291188404818401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4869291188404818401'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/10/virtual-file-system.html' title='Virtual File System'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8227496670082847410</id><published>2009-09-30T17:56:00.002+02:00</published><updated>2009-10-07T11:45:35.177+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Updated lightning bolts</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SsN-gjeZFDI/AAAAAAAAB3c/cl1CAYDLQ4g/s1600-h/nGENE_0319.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SsN-gjeZFDI/AAAAAAAAB3c/cl1CAYDLQ4g/s320/nGENE_0319.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I updated the &lt;a href="http://wtomandev.blogspot.com/2009/09/storm-is-coming.html"&gt;lightning effects&lt;/a&gt; in the engine. The change is addition of glow and fixing some small issues (and making it 3-dimensional effect instead of 2-dimensional). This time I show how it can simulate electricity (useful for weapons and stuff like that). &lt;br /&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Below is a short movie from &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech&lt;/a&gt; demo showing lightning bolt striking boxes at random:&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/QS0iq1x9k5k&amp;hl=pl&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/QS0iq1x9k5k&amp;hl=pl&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8227496670082847410?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8227496670082847410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/updated-lightning-bolts.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8227496670082847410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8227496670082847410'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/updated-lightning-bolts.html' title='Updated lightning bolts'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/SsN-gjeZFDI/AAAAAAAAB3c/cl1CAYDLQ4g/s72-c/nGENE_0319.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3312514851010137080</id><published>2009-09-29T17:15:00.002+02:00</published><updated>2009-10-07T11:45:43.888+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Burrows-Wheeler Transform</title><content type='html'>And so finally the last post on the compression algorithms is here (also the very first stage in the &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech &lt;/a&gt;VFS compression). This time I'll introduce a Burrows-Wheeler Transform or &lt;i&gt;BWT&lt;/i&gt; for short. The algorithm itself doesn't compress data at all so other methods like &lt;a href="http://wtomandev.blogspot.com/2009/09/huffman-coding.html"&gt;Huffman coding&lt;/a&gt; have to be used with it. But what this transform does is reordering the original data so it would be more compression friendly.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Lets look at an example. Imagine we have a following string (I used lower and upper case only for legibility reasons and assume 'C' and 'c' are actually the same for simplicity sake):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CPPProgramming&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;What we have to do is to shift (roll actually) this string left, one character by one until we reach EOF character (it's not literal it marks only the end of data):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" height="280" style="border-collapse: collapse; width: 123px;"&gt;&lt;col style="width: 325pt;" width="433"&gt;&lt;/col&gt;  &lt;tbody&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt; width: 325pt;" width="433"&gt;CPPProgramming&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;PPProgrammingC&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;PProgrammingCP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ProgrammingCPP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;rogrammingCPPP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ogrammingCPPPr&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;grammingCPPPro&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;rammingCPPProg&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ammingCPPProgr&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;mmingCPPProgra&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;mingCPPProgram&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ingCPPProgramm&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ngCPPProgrammi&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;gCPPProgrammin&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Also note that we don't actually need to hold 14 copies of the string (with large blocks of data the cost would be too high to use this algorithm). Instead 14 pointers are required. First pointing to the beginning of the string, second to the second character, third to the third character etc. &lt;br /&gt;&lt;br /&gt;Next step is to sort these strings using lexicographical ordering what results in a following matrix:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 393px;"&gt;&lt;col style="width: 295pt;" width="393"&gt;&lt;/col&gt;  &lt;tbody&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt; width: 295pt;" width="393"&gt;ammingCPPProgr&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;CPPProgramming&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;gCPPProgrammin&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;grammingCPPPro&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ingCPPProgramm&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;mingCPPProgram&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;mmingCPPProgra&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ngCPPProgrammi&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ogrammingCPPPr&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;PPProgrammingC&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;PProgrammingCP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;ProgrammingCPP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;rammingCPPProg&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr height="19" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; height: 14.25pt;"&gt;   &lt;td height="19" style="height: 14.25pt;"&gt;rogrammingCPPP&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Now look at the very first column, it is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;aCggimmnoPPPrr&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There were definitely no two consecutive characters with 'g' or 'r' values in the original string! So the opportunity to compress it seems.&lt;br /&gt;&lt;br /&gt;However, oddly enough we're not interested in the first column but in the last one (call it L) which doesn't look that interesting:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rgnommairCPPgP&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It looks that the order of the characters is completely random. This column has one important feature though. Each character in it is a prefix to the string starting at this row.&lt;br /&gt;&lt;br /&gt;The output of the algorithm is this column associated by the so called primary index.&lt;br /&gt;&lt;br /&gt;Primary index is a number telling in which row of this L column there is the very first character of the original string. Our string began with 'C' (note that if there were two C's we would need to differentiate between them as only one of them was the first character) so the primary index (counting from 0) is 9.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;How to compress actually&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Remember that character in L column is a prefix to the one in the first column in the given row?&lt;/span&gt; &lt;/span&gt;That means that we have also a copy of the first column which seems to have better compression properties than the L one...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Reverting the transform&lt;/span&gt;&lt;br /&gt;Reverting the transform might seem a bit tricky at first. Actually to make it possible we need something more than just the last column and the primary index. There's need for a so called transformation vector T.&lt;br /&gt;&lt;br /&gt;Value of each of its elements tell the position of the next row from the unsorted list of strings.&lt;br /&gt;&lt;br /&gt;So given the row:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CPPProgramming&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;which originally was in 0th row and now is in 1st we look for the current position of row:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PPProgrammingC&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It can be found under row with the index of 9. So:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T[1] = 9&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Next string (i.e. PProgrammingCP) can be found under index 10 so:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T[9] = 10&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;and so on. For our example T vector is eventually as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T = [6; 9; 1; 12; 7; 4; 5; 2; 3; 10; 11; 13; 0; 8]&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Remember our primary index is 9? And the last column has the form of: rgnommairCPPgP&lt;br /&gt;&lt;br /&gt;Ok, so we decode starting with our primary index.&lt;br /&gt;&lt;br /&gt;Lets take the 9th character from the string i.e. 'C' and output it:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;C&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;than the next index is the one from T vector under current index (for now primary index). &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T[9] = 10&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;L[10] = P&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;CP&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Now current index is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T[10] = 11&lt;/span&gt;...&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; L[11]&lt;/span&gt; is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CPP&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T[11] = 13&lt;/span&gt;, and&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; L[13]&lt;/span&gt; is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CPPP&lt;/span&gt;...&lt;br /&gt;&lt;br /&gt;and so on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A more detailed description of the algorithm and the example implementation can be found &lt;a href="http://marknelson.us/1996/09/01/bwt/"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As for the lightning bolts I improved them a lot but need a few more hours to finish them so the pics and video will be updated then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3312514851010137080?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3312514851010137080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/burrows-wheeler-transform.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3312514851010137080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3312514851010137080'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/burrows-wheeler-transform.html' title='Burrows-Wheeler Transform'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4876600746869461337</id><published>2009-09-27T15:00:00.002+02:00</published><updated>2009-10-07T11:45:56.642+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Storm is coming</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_fbfW7HvrHa4/Sr-R9DRxiII/AAAAAAAAB3U/_olgLuG1glY/s1600-h/nGENE_0312.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/Sr-R9DRxiII/AAAAAAAAB3U/_olgLuG1glY/s320/nGENE_0312.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the last few hours apart from finishing skinning shader, I coded quite an interesting effect (not finished really but as for just a few hours of work I'm quite happy with the results):&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/EtNyQhSNC8k&amp;hl=pl&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/EtNyQhSNC8k&amp;hl=pl&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Lightnings are pretty complex objects but they can be recreated quite easily using very simple and well-known algorithm i.e. a middle point method. Even though it is more often used for procedural terrain generation it can be used with success for lightning bolts rendering as the video above shows.&lt;br /&gt;&lt;br /&gt;Unfortunately I cannot tell exactly whose idea it originally was (as I found the link accidentally long time ago and it considered Flash) but it is not mine for sure :)&lt;br /&gt;&lt;br /&gt;Ok, without further ado. What you basically have to do is to for each segment (at first you have only one segment specified by lightning's start and end points) find its middle point and offset it a little (by some random value smaller than maximumOffset value) along normal vector (perpendicular to the direction vector given by normalize(end - start)). This way 2 new segments will be created:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;segment1 - start: lightning start, end: lightning middle point,&lt;/li&gt;&lt;li&gt;segment2 - start: lightning middle, end: lightning end point.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Then for each of the new 2 segments the procedure have to be repeated recursively until desired number of iterations or divisions was made.&lt;br /&gt;&lt;br /&gt;But it will give us boring lightning-like object with no branches at all (lightnings definitely have them!). So a small modification has to be made. Every time you divide a segment you can also decide (based on the number of branches already added or some probability calculations) whether it should be also split, i.e. whether new branch should begin in the point of division. If yes, new segment is created pointing in the direction of lightning end point with some small distortion:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;branch - start: current middle point, end: current middle point + normalize(current end - current middle) * length * some random offset.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The length is some random value from range &lt;minbranchlength; currentsegmentlenght=""&gt;(minBranchLength, currentSegmentLength). Values larger than currentSegmentLength would allow creation of very long and therefore unrealistic branches. This new segment (or branch) is then processed the same way as others.&lt;/minbranchlength;&gt;&lt;br /&gt;&lt;minbranchlength; currentsegmentlenght=""&gt;&lt;br /&gt;&lt;/minbranchlength;&gt;&lt;br /&gt;&lt;minbranchlength; currentsegmentlenght=""&gt;But it still looks a bit boring. So the solution is to render actually not 1 but 2 lightnings at a time (with the very same start and end points). If each of them has life time L than:&lt;/minbranchlength;&gt;&lt;br /&gt;&lt;minbranchlength; currentsegmentlenght=""&gt; &lt;/minbranchlength;&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;minbranchlength; currentsegmentlenght=""&gt;at 0 generate lightning1 with alpha1 = 1.0&amp;nbsp;&lt;/minbranchlength;&gt;&lt;/li&gt;&lt;li&gt;&lt;minbranchlength; currentsegmentlenght=""&gt;for range (0, L / 2) interpolate alpha1 from 1 to 0.5&lt;br /&gt;&lt;/minbranchlength;&gt;&lt;/li&gt;&lt;li&gt;&lt;minbranchlength; currentsegmentlenght=""&gt;at L / 2 generate lightning2 with alpha2 1.0&lt;/minbranchlength;&gt;&lt;/li&gt;&lt;li&gt;for range (0, L / 2) interpolate alpha2 from 1 to 0.5 and alpha1 from 0.5 to 0&lt;/li&gt;&lt;li&gt;for range (L / 2, L) interpolate alpha2 from 0.5 to 0&lt;/li&gt;&lt;/ol&gt;Now it looks a lot better. But still not good enough. When lightning hits ground everything becomes white for a brief moment (this step is not necessary for rendering electricity related effects though). At first I tried setting some emissive values for different materials and using HDR but the results were not good enough. So I chose a different approach.&lt;br /&gt;&lt;br /&gt;I render lightning bolts to the offscreen render targets and when compositing them with the frame buffer I set its contents to almost completely white for a fraction of a second.&lt;br /&gt;&lt;br /&gt;It is also important to enhance scene contrast a little but that is quite easy and depends on the effect desired. Of course I have still a lot of work to do (add some better glow and fine-tune some parameters) but as I said I'm already pretty happy with the results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4876600746869461337?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4876600746869461337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/storm-is-coming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4876600746869461337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4876600746869461337'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/storm-is-coming.html' title='Storm is coming'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/Sr-R9DRxiII/AAAAAAAAB3U/_olgLuG1glY/s72-c/nGENE_0312.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-37601166362014919</id><published>2009-09-23T19:16:00.002+02:00</published><updated>2009-10-07T11:46:04.941+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Control over time and space</title><content type='html'>Well, sort of :) One of the cool features of deferred shading (I know that for some of you guys, cool and deferred shading just don't match) is that we have full control of what is written to the Z-Buffer (as it is part of G-Buffer). Of course when using post-processing with forward rendering there is also often need to perform special Z pass but in case of deferred shading we're obliged to do that as without it lighting the scene would be just impossible.&lt;br /&gt;&lt;br /&gt;Why is it so cool? Well, lets look at the picture below:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/SrpHdkipeMI/AAAAAAAAB2s/bUai13BFu3w/s1600-h/nGENE_0309.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/SrpHdkipeMI/AAAAAAAAB2s/bUai13BFu3w/s320/nGENE_0309.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;Nothing special at first (don't mind this blue line, I'm using it for testing purposes... for testing sound). Well but the wall with this fancy relief is done using parallax occlusion mapping (so considering geometry it's just a plane with 4 vertices in total). Normally the shadows would be casted on it as it was a plane. That would look a bit weird. So just before outputting data to the G-Buffer I have slightly modified Z values (using computed height value and normal vector) to make it "behave" as it was all modelled and now the shadows are casted properly.&lt;br /&gt;&lt;br /&gt;Funny thing is, you can use this for all sort of effects (to some extent I used it when developing &lt;a href="http://www.gamedev.net/reference/articles/article2642.asp"&gt;my water technique&lt;/a&gt;). Just a few lines in bump mapping shaders improved many scene depth based effects (like SSAO).&lt;br /&gt;&lt;br /&gt;Below is a screenshot from SSAO:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SrpXseUcUeI/AAAAAAAAB20/BEKGkRbbouk/s1600-h/nGENE_311.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SrpXseUcUeI/AAAAAAAAB20/BEKGkRbbouk/s320/nGENE_311.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-37601166362014919?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/37601166362014919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/control-over-time-and-space.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/37601166362014919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/37601166362014919'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/control-over-time-and-space.html' title='Control over time and space'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbfW7HvrHa4/SrpHdkipeMI/AAAAAAAAB2s/bUai13BFu3w/s72-c/nGENE_0309.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-6966773735935843322</id><published>2009-09-23T12:43:00.000+02:00</published><updated>2009-09-23T12:43:43.159+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Night Vision effect</title><content type='html'>Implementing the night vision effect is pretty simple.&lt;br /&gt;&lt;br /&gt;What we have to do is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Read current frame buffer content,&lt;/li&gt;&lt;li&gt;Sample a noise texture using time variant texture coordinates (I modify them by adding &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sin(milliseconds / 1000.0f)&lt;/span&gt; to them),&lt;/li&gt;&lt;li&gt;Add both vectors, &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Multiply everything with green colour i.e. (0.0f, 1.0f, 0.0f) vector.&lt;/li&gt;&lt;/ol&gt;I used this simple procedure to achieve this in nGENE (well jpg compression made it look worse than it really does):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_fbfW7HvrHa4/Srny9O-Q73I/AAAAAAAAB2k/---Ku31mGqY/s1600-h/nGENE_0308.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_fbfW7HvrHa4/Srny9O-Q73I/AAAAAAAAB2k/---Ku31mGqY/s200/nGENE_0308.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-6966773735935843322?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/6966773735935843322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/night-vision-effect.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6966773735935843322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/6966773735935843322'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/night-vision-effect.html' title='Night Vision effect'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbfW7HvrHa4/Srny9O-Q73I/AAAAAAAAB2k/---Ku31mGqY/s72-c/nGENE_0308.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2082385913867168722</id><published>2009-09-21T20:27:00.003+02:00</published><updated>2009-10-07T11:46:15.115+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Move-to-Front</title><content type='html'>Move-to-Front algorithm is a simple data transform which might reduce entropy and thus improve performance of the entropy based compression algorithms like &lt;a href="http://wtomandev.blogspot.com/2009/09/huffman-coding.html"&gt;Huffman&lt;/a&gt;&lt;a href="http://wtomandev.blogspot.com/2009/09/huffman-coding.html"&gt; coding&lt;/a&gt; I described recently. It is also often used with Burrows-Wheeler Transform which is producing sequence with local frequencies correlation (whatever it means). I'll describe BWT later (and that will be the end of the compression algorithm series :) ).&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;Encoding&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At the start of the algorithm there is a list of characters in which each of these characters have index associated with it. Lets say we have alphabet of 5 characters only: a, b, c, d, e and therefore the list initially looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(a, b, c, d, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We also have an example string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccdddcceeeeaaaaacbbb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'c', the first character in the string, have initially index 2 associated with it. Lets output it then:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We're moving it to front (hence the name of the algorithm :) ) so the list looks like this now:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(c, a, b, d, e)&lt;/span&gt; -&amp;gt; note 'c' was moved to front&lt;br /&gt;&lt;br /&gt;Now moving to the next character ('c' again), 'c' have now index 0. We don't have to move it to front as it is already there. So we just output current index i.e. 0:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;20&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Same for the next two 'c' characters:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;2000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then there is 'd' which currently have index 3:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;20003&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We move it to front, what results in list look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; (d, c, a, b, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next two d's:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;2000300&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'c' again (this time with index 1 not 0 as it was previously):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;20003001&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  (c, d, a, b, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then there is 'e' with index 4:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;200030014&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   (e, c, d, a, b)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We output indices of next three e's:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;200030014000...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And so on (the idea should be clear now). But now as you can see we have runs of 0's which we can remove (i.e. compress) using &lt;a href="http://wtomandev.blogspot.com/2009/09/run-length-encoding.html"&gt;Run-Length Encoding&lt;/a&gt; algoritm described earlier.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;Decoding&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 100%;"&gt;Decoding is relatively easy. Lets start with our output:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;200030014000...&lt;/span&gt; (I omit the rest of the string because I just want to present general idea)&lt;br /&gt;&lt;br /&gt;And our list is as it was at the beginning of the encoding procedure:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; (a, b, c, d, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In our input the first character is '2'. We look it up in the list. It is associated with character 'c'. We output it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;c&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lets move it to front:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(c, a, b, d, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then there are 3 zeroes... what means c's again:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cccc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then there is '3' what stands for 'd':&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; (d, c, a, b, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next two characters are also d's:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccddd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'1' stands for 'c':&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccdddc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  (c, d, a, b, e)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'4' stands for 'e' so we then have:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccddde&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(0, 1, 2, 3, 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   (e, c, d, a, b)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And finally:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ccccdddeeee...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pretty easy, isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2082385913867168722?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2082385913867168722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/move-to-front.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2082385913867168722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2082385913867168722'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/move-to-front.html' title='Move-to-Front'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-2684819487330484122</id><published>2009-09-18T10:19:00.003+02:00</published><updated>2009-10-07T11:46:24.087+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Huffman Coding</title><content type='html'>Huffman Coding is another algorithm I use in &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech&lt;/a&gt; VFS compression. I use it as the last stage of compressing a resource file, just after performing &lt;a href="http://wtomandev.blogspot.com/2009/09/run-length-encoding.html"&gt;Run-Length Encoding&lt;/a&gt; on the data.&lt;br /&gt;&lt;br /&gt;The algorithm bases on the character frequencies in the input data.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Lets say we have a string with characters' frequencies like that (order of the characters is not important for this algorithm):&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;a: 10&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;b: 2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;c: 21&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;d: 44&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;e: 78&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;f: 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;None of the other characters occur in the example data.&lt;br /&gt;&lt;br /&gt;Normally each of these characters would be represented using a single byte (8-bits). But we could instead represent each of them using a special dynamic length binary code. The more frequent the character is, the shorter its code should be so the compression ratio would be higher. For instance 'e' (the most frequent one in the example string) could be represented by 1 i.e. a single bit. That means that all of e's characters would require total of 78 bits ~ 10 bytes instead of regular 78 bytes!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;Building the codes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But how to know what code should be associated with each character? That is where Huffman algorithm comes to play. When we already know the frequencies of all characters we're building a special binary tree. Before I go into details on how to do that here is what it'll look for the data above:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SrSfLVE5kdI/AAAAAAAAB2U/I1fXO1sDhlc/s1600-h/huffman.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5383102471599657426" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SrSfLVE5kdI/AAAAAAAAB2U/I1fXO1sDhlc/s200/huffman.jpg" style="cursor: pointer; display: block; height: 165px; margin: 0px auto 10px; text-align: center; width: 200px;" /&gt;&lt;/a&gt;Now when we have a tree such like that obtaining codes is a straight forward task. As you can see characters are put in leaves. Also they frequencies are displayed there. So to get a code of any given character we're going down the tree starting at root with code "" and adding '0' each time we take left branch and '1' when taking right one until we reach our destination character.&lt;br /&gt;&lt;br /&gt;For example for 'f' character the code is '00000' (it is not the same as '0' though!!!) as we're taking left branch five times, for 'c' - '001', for 'd' - '01' and for 'e' - '1'. What is important is that the code is shorter when the character appears more often.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;Building Huffman codes tree&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now the procedure for building Huffman codes tree is as follows. Get two elements from the list of elements (well actually 'list' is not literal here; heap is most commonly used for that) with smallest frequencies and concatenate them in such a way that they form a new tree and the sum of their frequencies is put in their parent node. In first iteration we join 'f' and 'b' (1 and 2 frequencies respectively) and put 3 (sum of their frequencies) in the new tree root.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SrShxtLoq2I/AAAAAAAAB2c/zmDVnfMIl4Q/s1600-h/huffman2.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5383105329928645474" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SrShxtLoq2I/AAAAAAAAB2c/zmDVnfMIl4Q/s200/huffman2.jpg" style="cursor: pointer; display: block; height: 128px; margin: 0px auto 10px; text-align: center; width: 200px;" /&gt;&lt;/a&gt;&lt;br /&gt;This tree is put into the heap and works like a regular element. Then we again choose two smallest elements. As we've just put '3' into the heap we will get 3 and 10 (what stands for 'a' character). We proceed until there is only a single element left and that is our Huffman codes tree.&lt;br /&gt;&lt;br /&gt;Now as we know the codes we have to perform actual data encoding. It is simple. For each of the characters in the input, look up their code in the codes table and return it to the output. Of course the thing to remember is that we have to operate on bits rather than on whole bytes to really compress anything. The following pseudocode does the thing:&lt;br /&gt;&lt;pre class="Cpp" name="code"&gt;unsigned char curr = 0;&lt;br /&gt;usigned int currByte = 0;&lt;br /&gt;usingned int bits = 0;&lt;br /&gt;while(!data.eof())&lt;br /&gt;{&lt;br /&gt;// First get next character from the input&lt;br /&gt;curr = data.getNextCharacter();&lt;br /&gt;// Look up its code in the table&lt;br /&gt;const char* code = huffmanCodes[curr];&lt;br /&gt;&lt;br /&gt;usingned char c = 0;&lt;br /&gt;while(code++)&lt;br /&gt;{&lt;br /&gt;c = code[i];&lt;br /&gt;currByte &amp;lt;&amp;lt;= 1;&lt;br /&gt;// Write one in the least significant bit&lt;br /&gt;if(c == '1')&lt;br /&gt;currByte |= 1;&lt;br /&gt;++bits;&lt;br /&gt;// When whole byte has been filled write it to the output&lt;br /&gt;if(bits == 8)&lt;br /&gt;{&lt;br /&gt;result.write((char*)&amp;amp;currByte, 1);      &lt;br /&gt;bits = 0;&lt;br /&gt;currByte = 0;&lt;br /&gt;}  &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-size: 130%;"&gt;Decompressing data&lt;/span&gt;  What about decompressing data encoded this way? Well for that we have to output something more to be able to reconstruct tree. We have to save the tree itself. For each of the nodes we output: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;0 - when the node is an internal node (1 bit),&lt;/li&gt;&lt;li&gt;1 + character - when the node is a leaf (9 bits). Character means a character with which the leaf is associated, eg. for code '1' it is 'e'.&lt;/li&gt;&lt;/ul&gt;It means some additional data but it is not much. This data is enough to reconstruct a tree. Then decoding is easy. We read data bit by bit and follow the tree branches until we reach the leaf. It means that we found a character and that the next bit belongs to another character. Note that such representation is unambiguous. For instance following bits:  &lt;span style="font-family: courier new;"&gt;111001101&lt;/span&gt;  are decoded into:  &lt;span style="font-family: courier new;"&gt;eeeced&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-2684819487330484122?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/2684819487330484122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/huffman-coding.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2684819487330484122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/2684819487330484122'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/huffman-coding.html' title='Huffman Coding'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/SrSfLVE5kdI/AAAAAAAAB2U/I1fXO1sDhlc/s72-c/huffman.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7909459700091270491</id><published>2009-09-15T09:44:00.005+02:00</published><updated>2009-10-07T11:46:31.848+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Run-Length Encoding</title><content type='html'>This entry will describe RLE (&lt;span style="font-style: italic;"&gt;Run-Length Encoding&lt;/span&gt;) algorithm which is one of the simplest lossless data compression algorithms commonly used as one of the steps of data compression (for instance other steps might involve Burrows-Wheeler Transform, Move-to-Front, arithmetic encoding etc. but I'll write about them later). What it does is going through the block of data and counting consecutive characters with the same value and storing this count value with a character in the output string.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;In its simplest form for a string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;AAAAFFFBAAAAACCDCBBBBBBBB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It outputs:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;4A3F1B5A2C1D1C8B&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As there are 4 As, followed by 3 Fs, followed by a single B, followed by 5 As etc. It is obvious from this example that it is really compressing data... well sort of. Now imagine such a string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ABABABABABABABABAB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The output would be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;1A1B1A1B1A1B1A1B1A1B1A1B1A1B1A1B1A1B&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hmm not the thing we really wanted - the output string is twice as long as the input!&lt;br /&gt;&lt;br /&gt;A better solution is therefore to go through the file. If there are two consecutive characters with the same value count same characters after latter of them and put them after these two characters in the output string. It would mean that the minimum count value would be 0 but for example above output, would be same as input (failed to compress but still better than having data that much larger than original).&lt;br /&gt;&lt;br /&gt;For the string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;AAAAFFFBAAAAACCDCBBBBBBBB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In turn it outputs:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;AA2AFF1BAA3CCDCBB2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A bit worse than previously but still we're compressing at least. What's more the BWT (&lt;span style="font-style: italic;"&gt;Burrows-Wheeler Transform&lt;/span&gt;) algorithm accompanied by Move-to-Front makes data much more friendly for Run-Length Encoding and thus the compression ratio is much higher but as I said I'll describe them later.&lt;br /&gt;&lt;br /&gt;But you may ask why I do care about algorithms such as that. Well I'm currently finishing my implementation of Virtual File System for &lt;a href="http://ngene.wikidot.com/"&gt;nGENE Tech&lt;/a&gt; so I had to implement several algorithms such as ones mentioned to have the ability to compress data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7909459700091270491?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7909459700091270491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/run-length-encoding.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7909459700091270491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7909459700091270491'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/run-length-encoding.html' title='Run-Length Encoding'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4719075604532110971</id><published>2009-09-11T18:39:00.000+02:00</published><updated>2009-09-11T19:01:11.863+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>God rays update</title><content type='html'>I submitted the post about light-shafts phenomenon recently. The movie then contained one serious artifact. I got rid of it a few days ago but I had a chance to record movie only today. It is much much better in my opinion :)&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/8wP_Crjz2H0&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/8wP_Crjz2H0&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4719075604532110971?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4719075604532110971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ngene-update_11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4719075604532110971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4719075604532110971'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ngene-update_11.html' title='God rays update'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-3690138119354686598</id><published>2009-09-10T20:29:00.000+02:00</published><updated>2009-09-10T20:30:15.103+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>nGENE Update</title><content type='html'>This time, screenshots only. Still far away from ok but believe me the changes and fixes are numerous :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlFRvgw6XI/AAAAAAAAB10/y3HLtfvNpiE/s1600-h/nGENE_0288.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlFRvgw6XI/AAAAAAAAB10/y3HLtfvNpiE/s200/nGENE_0288.jpg" alt="" id="BLOGGER_PHOTO_ID_5379907400984750450" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqlFNaXkpAI/AAAAAAAAB1s/hvScyTuE_Ms/s1600-h/nGENE_0290.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqlFNaXkpAI/AAAAAAAAB1s/hvScyTuE_Ms/s200/nGENE_0290.jpg" alt="" id="BLOGGER_PHOTO_ID_5379907326589576194" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlFCH3uvgI/AAAAAAAAB1k/avls_nOLuK4/s1600-h/nGENE_0292.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlFCH3uvgI/AAAAAAAAB1k/avls_nOLuK4/s200/nGENE_0292.jpg" alt="" id="BLOGGER_PHOTO_ID_5379907132645621250" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlE-fHNjRI/AAAAAAAAB1c/zoLwUno5P80/s1600-h/nGENE_0299.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlE-fHNjRI/AAAAAAAAB1c/zoLwUno5P80/s200/nGENE_0299.jpg" alt="" id="BLOGGER_PHOTO_ID_5379907070165093650" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-3690138119354686598?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/3690138119354686598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ngene-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3690138119354686598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/3690138119354686598'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ngene-update.html' title='nGENE Update'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/SqlFRvgw6XI/AAAAAAAAB10/y3HLtfvNpiE/s72-c/nGENE_0288.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-485956035242770420</id><published>2009-09-07T13:40:00.000+02:00</published><updated>2009-09-07T13:53:19.661+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>SSAO and no SSAO... does it really matter</title><content type='html'>It might be a bit out-of-date entry but still better later than never.&lt;br /&gt;&lt;br /&gt;After release of Crysis game, Screen Space Ambient Occlusion (SSAO) became a real 3D game programming community buzzword. Everyone wanted to present their own approach to this technique which in short aims in faking global illumination (or the fact we are unable to implement GI in real-time which would be fast enough to use it in games). When I implemented it in nGENE more than a year ago many people kept me asking if it really makes any difference as there are plenty of other effects which already make 3D worlds realistic enough. Well I made a small comparison finally.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqTzwN1GEEI/AAAAAAAAB0w/Xv8LOJLbwjo/s1600-h/nGENE_0279.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqTzwN1GEEI/AAAAAAAAB0w/Xv8LOJLbwjo/s200/nGENE_0279.jpg" alt="" id="BLOGGER_PHOTO_ID_5378691864658841666" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqTzsdMyCqI/AAAAAAAAB0o/2tdYFl4gKTM/s1600-h/nGENE_0278.jpg"&gt;&lt;img style="cursor: pointer; width: 200px; height: 150px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqTzsdMyCqI/AAAAAAAAB0o/2tdYFl4gKTM/s200/nGENE_0278.jpg" alt="" id="BLOGGER_PHOTO_ID_5378691800065247906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now guess which one uses SSAO and which one doesn't. Pretty obvious, isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-485956035242770420?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/485956035242770420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ssao-and-no-ssao-does-it-really-matter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/485956035242770420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/485956035242770420'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/ssao-and-no-ssao-does-it-really-matter.html' title='SSAO and no SSAO... does it really matter'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fbfW7HvrHa4/SqTzwN1GEEI/AAAAAAAAB0w/Xv8LOJLbwjo/s72-c/nGENE_0279.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-4609305747200013137</id><published>2009-09-06T22:20:00.000+02:00</published><updated>2009-09-06T22:51:47.250+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Grass rendering</title><content type='html'>Rendering grass is a non-trivial task. Even if we decide to go with the most popular technique (i.e. rendering grass as a bunch of billboards), we face a serious problem - huge performance drop.&lt;br /&gt;&lt;br /&gt;There are a few things which can be done to speed up grass rendering though:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;instead of rendering grass billboards separately batch them. Quite natural approach is to make batches as large as terrain patches. This way when terrain patch is known to be culled grass on, it is culled as well.&lt;/li&gt;&lt;li&gt;do not use alpha blending. It would be a real performance killer. Instead go with the alpha testing + dissolving. Dissolving is a cheap way of improving alpha testing quality and make it closer to what we would get if we used alpha blending. Alpha is multiplied by a value read from a dissolve texture which can be something like this:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqQbGRd2m_I/AAAAAAAAB0Y/5cPTwjocvpA/s1600-h/dissolve.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 200px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SqQbGRd2m_I/AAAAAAAAB0Y/5cPTwjocvpA/s200/dissolve.jpg" alt="" id="BLOGGER_PHOTO_ID_5378453649568996338" border="0" /&gt;&lt;/a&gt;Now if we have grass blades batched into tiles it is a good idea to alter reference value between them to make grass further away from the camera dissappear (and thus not influence our precious fill-rate).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There is often one more issue when rendering grass - lighting it. To solve it, I set billboard normal to be the same as terrain normal at the point where the grass blade is positioned.&lt;br /&gt;&lt;br /&gt;I implemented this in nGENE and now grass is no more the biggest bottle-neck :) Of course it still doesn't look that good as it should but I lack better textures (these are pretty low-res):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqQZpoxkSdI/AAAAAAAAB0Q/xq1azGr0L58/s1600-h/nGENE_0275.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SqQZpoxkSdI/AAAAAAAAB0Q/xq1azGr0L58/s320/nGENE_0275.jpg" alt="" id="BLOGGER_PHOTO_ID_5378452058097863122" border="0" /&gt;&lt;/a&gt;There are other things I'm currently improving and fixing in nGENE (damn, I'm trying to improve as much as possible). This week I fixed/improved more than a dozen of things. Next week I dedicate to skeletal animation. One more picture (you can see improved shadows on the building and SSAO):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fbfW7HvrHa4/SqQcIL2wqnI/AAAAAAAAB0g/pCNHxGsx9FI/s1600-h/nGENE_0278.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/SqQcIL2wqnI/AAAAAAAAB0g/pCNHxGsx9FI/s320/nGENE_0278.jpg" alt="" id="BLOGGER_PHOTO_ID_5378454781934217842" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-4609305747200013137?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/4609305747200013137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/grass-rendering.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4609305747200013137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/4609305747200013137'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/grass-rendering.html' title='Grass rendering'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/SqQbGRd2m_I/AAAAAAAAB0Y/5cPTwjocvpA/s72-c/dissolve.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7617539800218762105</id><published>2009-09-02T13:07:00.002+02:00</published><updated>2010-06-01T10:54:56.235+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='hdr'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>Photography: light graffiti, macro, HDR</title><content type='html'>I took last weekend off from programming and computers and went to shoot some photos. There are many techniques I'm interested in but hadn't tried my hand in them or previous attempts were poor at best. These include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;light graffiti,&lt;/li&gt;&lt;li&gt;macro photography,&lt;/li&gt;&lt;li&gt;HDR.&lt;/li&gt;&lt;/ul&gt;I had also this very plan to take some night photos as described &lt;a href="http://wtomandev.blogspot.com/2009/07/dadaj-lake-night-photos.html"&gt;here&lt;/a&gt; but unfortunately weather conditions stopped me from doing this (it was rainy, cloudy and dull).&lt;br /&gt;&lt;b&gt;Light graffiti&lt;/b&gt;&lt;br /&gt;Light graffiti is an interesting technique. What has to be done is to go into some dark room (or shoot during night) and stand in front of the camera dressed in black (to prevent being caught in the picture). We set long exposure time (several seconds should do), low aperture and ISO around 100. Then we take a torch (the weaker, the better - we will have more time to paint) and start drawing... We can paint or write whatever we want. Here is my signature done this way (it's my name for those who don't know this :) ):&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_fbfW7HvrHa4/Sp5I4wuOyAI/AAAAAAAAByw/a5gEVJRig5M/s1600-h/podpis.JPG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5376815145115633666" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/Sp5I4wuOyAI/AAAAAAAAByw/a5gEVJRig5M/s200/podpis.JPG" style="cursor: hand; cursor: pointer; display: block; height: 134px; margin: 0px auto 10px; text-align: center; width: 200px;" /&gt;&lt;/a&gt;&lt;br /&gt;If there was some background, it would be more appealing but I decided to give up idea of adding stars in the background due to the conditions I already mentioned. Even though this text is 2-dimensional there is no restriction of drawing in 3D (all those fancy ribbons and stuff like that).&lt;br /&gt;The only thing to bear in mind is that the result will be flipped as in the mirror. There are two solutions: either to draw in a "flipped mode" or do it afterwards in GIMP or Photoshop. The first one might sound difficult at first but it took me only several minutes to do it this way :)&lt;br /&gt;&lt;b&gt;Macro photography&lt;/b&gt;&lt;br /&gt;For the very next day rainy conditions were forecasted. I was quite nervous and excited about that as I knew it would guarantee great macro photography opportunities. The rain came and when it stopped showering I went for a 3hrs photo session with spiders, snails and droplets. Here are the results as a Picasa slideshow:&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5376801539963714833%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;br /&gt;I used +10 dioptres lens but now it's probably high time to equip myself in a more 'professional' macro lens. Shooting macro is pretty cool. It's almost unbelievable how many details we miss of this small world.&lt;br /&gt;&lt;b&gt;HDR&lt;/b&gt;&lt;br /&gt;In HDR I tried my hand before but this time the results are significantly better I think:&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Ftomanw%2Falbumid%2F5376804705863238113%3Falt%3Drss%26kind%3Dphoto%26hl%3Dpl" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;br /&gt;I used auto bracketing mechanism - camera changes exposure settings between shooting photos. Then these photos have to be combined together using dedicated software. Some of the photos were taken from a tripod and some from hand. Of course I know they are a bit unnatural but after watching several HDR photos on the web I came to a conclusion that hardly anyone tries to achieve realistic effects using this technique.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7617539800218762105?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7617539800218762105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/09/photography-light-graffiti-macro-hdr.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7617539800218762105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7617539800218762105'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/09/photography-light-graffiti-macro-hdr.html' title='Photography: light graffiti, macro, HDR'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/Sp5I4wuOyAI/AAAAAAAAByw/a5gEVJRig5M/s72-c/podpis.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1060555510639343298</id><published>2009-08-27T18:23:00.000+02:00</published><updated>2009-08-27T21:01:42.514+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='effects'/><title type='text'>Light-shafts</title><content type='html'>&lt;p&gt;I took a few hours break from working on the animation system (working on gui, fixing some nasty memory bugs and bugs related to shadows) during last days to code a light-shaft effect. It was one of the effects I always wanted to add to the nGENE because it looks cool, allows to build the feel &amp;amp; atmosphere and besides is pretty easy to implement. However, up to now I could hardly spare any time to do it.&lt;/p&gt;&lt;p&gt;But without further ado let's move to the technique I used (proposed by Jason Mitchell in ShaderX).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Light-shafts are simply visible beams of light sometimes referred under the name of God rays. This phenomenon is caused by light being scattered by particles present in the air like for instance dust. It looks a bit like a smoke or fog.&lt;/p&gt;&lt;p&gt;This is volumetric effect for sure. There are several common ways of implementing volumetric effects. One of the most popular ones which I used in this case is to slice volume into several parallel planes and project some textures onto them to make light-shaft look more convincing (other approaches use 3D textures). Number of planes will influence performance and the quality of the final effect. These planes are rendered perpendicular to the eye vector in such a way that they fill whole view space light-shaft bounding volume.&lt;/p&gt;&lt;p&gt;At first a set of vertices is created filling 1 x 1 x 1 unit cube. Then view space bounding volume of light-shaft is found. Then in the vertex shader by using following trick:&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;/p&gt;&lt;pre name="code" class="Cpp"&gt;float4 stretchedMaxBounds = float4(maxBounds, 0.0f);&lt;br /&gt;float4 pos = float4(minBounds, 0.0f) * IN.position + (stretchedMaxBounds * (1.0f - IN.position));&lt;/pre&gt;&lt;/span&gt;vertices are made to fill whole light frustum. minBounds and maxBounds are boundaries of light frustum bounding box.&lt;p&gt;In pixel shader all scattering related calculations are then performed. The first thing to do is to add light attenuation to make shaft disappear as it goes away from the light source. Regular equation 1 / (distance * distance) works pretty well here.&lt;/p&gt;&lt;p&gt;We could finish at this stage actually but the light shaft would look a bit unnatural. So we're adding a couple of things (by applying textures with projective texture coordinates to our volume slices) to make it better:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Gobo/cookie - a pattern to be applied to all planes,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Animated noise - what makes all the light shaft in nature so beautiful is that as the particles are moved by the air the light shaft seems to be moving,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Shadow - shadow should limit the area where the light-shaft is visible i.e. only pixels not in the shadow should appear foggy.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It is also good idea to use clipping planes to discard those pixels which are not in the light frustum but still are in its bounding volume. Planes to use are actually light frustum planes.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Gobo, cookie&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Gobo also known as cookie is a 2D texture applied to each of the planes. Typically it is used to make shaft disappear in a certain area of the frustum so it serves similar purpose as shadow described later on. The difference is that shadow uses dynamic shadow map whereas cookie is a predefined pattern (for instance cross or flowers) and unless for shadow we do not test for 'z' value to make a decision of occluding pixel or not.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Here is an example cookie texture:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fbfW7HvrHa4/SpbEE9P3oGI/AAAAAAAABtI/tlgMxCoUMX8/s1600-h/gobo1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/SpbEE9P3oGI/AAAAAAAABtI/tlgMxCoUMX8/s200/gobo1.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5374698794752909410" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Animated noise&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;By adding animated noise we can achieve impression of moving air what causes particles to move. By animated noise I mean a typical noise texture being projected using time-changing texture coordinates.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Shadow&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Here we use light shadow map. In nGENE each light shaft can be assosiated with 'real' light source and then utilize it shadow map during rendering. The shadow map is used to hide light shaft where it should be invisible i.e. where there are occluders on the way from light source to a given pixel.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Below you can see light-shafts in action:&lt;/p&gt;&lt;p&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/LzT6w-e2JTo&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/LzT6w-e2JTo&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;There are still some bugs and issues but they will be pretty easy to get rid of.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1060555510639343298?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1060555510639343298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/08/light-shafts.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1060555510639343298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1060555510639343298'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/08/light-shafts.html' title='Light-shafts'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fbfW7HvrHa4/SpbEE9P3oGI/AAAAAAAABtI/tlgMxCoUMX8/s72-c/gobo1.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7461693607080119634</id><published>2009-07-29T09:22:00.000+02:00</published><updated>2009-07-29T09:51:48.085+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><title type='text'>Near future plans for nGENE</title><content type='html'>It took me a lot of thinking recently about the way I should follow with further nGENE development. Here is a small summary of conclusions I came to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;nGENE definitely needs a game to prove its capabilities as a game engine. Therefore, I'll soon try to code something larger than up-to-date demos. It won't be a game by all means but it'll contain some gameplay elements. Besides this way it'll be much easier to spot bugs and flaws as I'll put myself in the position of a game developer. What it'll be is still to be decided, however to options I consider as most probable are: small racing game and fps shooter.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Current nGENE WIP status is not really convenient for potential developers. Therefore, I'll soon change the way it is stored in the repository. Updates to it will be much more frequent (even at daily basis) but at the same time there will be stable versions available for those who doesn't want not-well-tested functionality present.&lt;/li&gt;&lt;li&gt;Animation system is the thing I'm currently working on (amongst other things). The goal is to finish it by the end of summer (and by that I mean the end of september). I'm trying it to make as flexible and effective as possible.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Also problems with nGENE not working on some GPUs (modern ones) has to be definitely addressed. As for now I have no clue what they are caused by (unfortunately I don't have access to some of the top GPUd on which problems occur).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There is one problem (which can be also broken into several smaller problems) though to which I cannot find a good solution. I want nGENE, all it's shaders, techniques and code to be free of charge as long as possible (forever in the best case). However, working this way causes several complications:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have to work somewhere else what makes it impossible to work on nGENE everyday and respond to queries and issues as fast as it should be done. It would be different if nGENE allowed me to earn a living.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It's much more difficult to build up a team. Almost all of the talented guys out there doesn't want to make this only for fun. Money is something what really matters. It means I have to code everything on my own and I have no assets available like 3D models, textures or sound. Ok, I have by downloading them for free from some of the sites but this way there is no consistency as they come from dozens of authors.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;As I stated above I don't want to sell nGENE - I don't even believe anyone would buy it at this stage with lack of animation system or really poor GUI system. What I consider are donations. And here comes the question: I wonder if anyone of you have any experience with them and whether anyone would consider donating project such as an nGENE?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7461693607080119634?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7461693607080119634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/07/near-future-plans-for-ngene.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7461693607080119634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7461693607080119634'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/07/near-future-plans-for-ngene.html' title='Near future plans for nGENE'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-8943578170425186513</id><published>2009-07-14T16:40:00.000+02:00</published><updated>2009-07-14T16:51:58.313+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Dadaj Lake - night photos</title><content type='html'>&lt;p&gt;Recently I have no that much time to work on nGENE Tech (it is temporary though, I have ambitious plans for this summer regarding nGENE).&lt;/p&gt;&lt;p&gt;However, I spared some time to practice night photo shooting last weekend. You can see the results on picasa:&lt;/p&gt;&lt;p&gt;&lt;a href="http://picasaweb.google.com/tomanw/DadajNightPhotos#"&gt;http://picasaweb.google.com/tomanw/DadajNightPhotos#&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Here are some of the pics from the album:&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_fbfW7HvrHa4/SlyaA2Y8zGI/AAAAAAAABbU/ZS0xUZFXOn4/s1600-h/IMG_2912.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_fbfW7HvrHa4/SlyaA2Y8zGI/AAAAAAAABbU/ZS0xUZFXOn4/s320/IMG_2912.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5358326996054887522" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fbfW7HvrHa4/SlyZ6dijp1I/AAAAAAAABbM/GRL8nj7IMEY/s1600-h/IMG_2901.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_fbfW7HvrHa4/SlyZ6dijp1I/AAAAAAAABbM/GRL8nj7IMEY/s320/IMG_2901.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5358326886305081170" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fbfW7HvrHa4/SlyZz8prdOI/AAAAAAAABbE/9SAtcwbzv_A/s1600-h/IMG_2892.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_fbfW7HvrHa4/SlyZz8prdOI/AAAAAAAABbE/9SAtcwbzv_A/s320/IMG_2892.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5358326774397367522" /&gt;&lt;/a&gt;&lt;p&gt;Even though everything is pretty bright and the colours are vivid the night was pretty dark and several minutes long exposures were required to achieve this effect.&lt;/p&gt;&lt;p&gt;What I like about taking photos at night is that the results are somewhat unrealistic, the colours are more artistic so to say. And there is no one but night animals to disturb you.&lt;/p&gt;&lt;p&gt;I have still a lot to practice but the results get better and better each time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-8943578170425186513?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/8943578170425186513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/07/dadaj-lake-night-photos.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8943578170425186513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/8943578170425186513'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/07/dadaj-lake-night-photos.html' title='Dadaj Lake - night photos'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_fbfW7HvrHa4/SlyaA2Y8zGI/AAAAAAAABbU/ZS0xUZFXOn4/s72-c/IMG_2912.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-1277390494662789840</id><published>2009-06-13T19:27:00.000+02:00</published><updated>2009-06-13T20:44:56.503+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='toolset'/><title type='text'>nGENE Tech Toolset is available!</title><content type='html'>&lt;p&gt;I finally managed to finish some simple version of the nGENE Tech Toolset. See it in action below:&lt;/p&gt;&lt;p&gt;&lt;object width="425" height="344"&gt;&lt;embed src="http://www.youtube.com/v/f_CZcj4LMpo&amp;amp;hl=pl&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;You can download it &lt;a href="http://www.mediafire.com/?yzohmggnyil"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-1277390494662789840?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/1277390494662789840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/06/ngene-tech-toolset-is-available.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1277390494662789840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/1277390494662789840'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/06/ngene-tech-toolset-is-available.html' title='nGENE Tech Toolset is available!'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8185650834667529493.post-7683837497174040702</id><published>2009-06-05T08:58:00.001+02:00</published><updated>2009-06-05T09:14:17.599+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nGENE'/><category scheme='http://www.blogger.com/atom/ns#' term='papers'/><category scheme='http://www.blogger.com/atom/ns#' term='diving'/><title type='text'>Article about water on Gamedev.net</title><content type='html'>My article about water rendering in screen-space is finally available on &lt;a href="http://www.gamedev.net/reference/programming/features/ppWaterRender/"&gt;Gamedev.net&lt;/a&gt;! I hope you like it and wait for your comments on the matter. I tried to describe everything as I did it in nGENE Tech. The lecture which I had on the IGK'2009 (Polish Game Developers Conference) was chosen the best presentation of the conference edition. You can also view presentation from IGK (in English - I translated it) &lt;a href="http://www.mediafire.com/?0tnll50fh4n"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As for the nGENE Toolset - sorry for one more delay in releasing it... I'm pretty busy with the exams on the university... hope you understand that. I'll release it ASAP.&lt;br /&gt;&lt;br /&gt;Besides I'm diving a lot recently. I tried cave diving for the first time two weeks ago - and it rocks - and finished my Advanced Nitrox/Deco Procedures TDI course. There is of course a lot of work on the way to become REAL technical diver but I'm happy I finally managed to finish it. Thanks to Czarek Abramowski and Andrzej Górnicki, our instructors, for a really great and tough course!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8185650834667529493-7683837497174040702?l=wtomandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wtomandev.blogspot.com/feeds/7683837497174040702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wtomandev.blogspot.com/2009/06/article-about-water-on-gamedevnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7683837497174040702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8185650834667529493/posts/default/7683837497174040702'/><link rel='alternate' type='text/html' href='http://wtomandev.blogspot.com/2009/06/article-about-water-on-gamedevnet.html' title='Article about water on Gamedev.net'/><author><name>Wojtek</name><uri>http://www.blogger.com/profile/12746925806334085844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://4.bp.blogspot.com/_fbfW7HvrHa4/SsdMvzPvV0I/AAAAAAAAB3w/QYGKYLVCRt4/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
