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

<channel>
	<title>LiAR isn't a raytracer</title>
	<atom:link href="http://liar.bramz.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://liar.bramz.net</link>
	<description>'LiAR isn't a raytracer' is an open source, cross platform, object-oriented and extendable raytracer written in C++ and Python by Bram de Greve.</description>
	<lastBuildDate>Tue, 25 May 2010 19:14:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Building OpenEXR libraries for Windows x64</title>
		<link>http://liar.bramz.net/2010/05/25/openexr-x64-windows-building/</link>
		<comments>http://liar.bramz.net/2010/05/25/openexr-x64-windows-building/#comments</comments>
		<pubDate>Tue, 25 May 2010 19:14:54 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.bramz.net/?p=127</guid>
		<description><![CDATA[LiAR supports the OpenEXR file format for several months now, but I only had it working on 32-bit windows. I was still missing the binaries for the 64-bit build, as you need to build the library yourself. For 64-bit Windows that turns out to be one tricky affair: Only Visual Studio solution files are available [...]]]></description>
			<content:encoded><![CDATA[<p>LiAR supports the <a href="http://openexr.com/">OpenEXR</a> file format for several months now, but I only had it working on 32-bit windows.  I was still missing the binaries for the 64-bit build, as you need to build the library yourself. For 64-bit Windows that turns out to be one tricky affair: </p>
<ol>
<li>Only Visual Studio solution files are available so that rules out nmake.</li>
<li>DLL creation involves an custom build tailored for x86.</li>
<li>The <a href="http://www.microsoft.com/express/Windows/">Visual C++ Express</a> editions are x86 only anyway, so you have to work around that as well.</li>
<li>And surprisingly, it seems that no-one has ever bothered so before because there&#8217;s hardly anything to be found on the web.</li>
</ol>
<p>After several hours of hairpulling, I&#8217;ve finally managed to set up a working x64 build. To document it for future reference, and for other people on the same adventure, here are the magic build steps:</p>
<h3>Setting up the build tree</h3>
<p>The OpenEXR build is rather picky on the build tree layout.  While the absolute location is free for choice, you need to add an extra layer for things to play out nicely.  On my machine, I&#8217;ve put everything in <code>C:\libs-x64\openexr-1.6.1</code>, but that could be just any other location.</p>
<ol>
<li>Download <a href="http://openexr.com/downloads.html">ilmbase-1.0.1.tar.gz and openexr-1.6.1.tar.gz</a>.</li>
<li>Create <code>C:\libs-x64\openexr-1.6.1\openexr</code>.
<p>This extra layer is necessary to make sure the goodies are gathered in <code>C:\libs-x64\openexr-1.6.1\Deploy</code>.  Otherwise, they would end up in <code>C:\libs-x64\Deploy</code>.</li>
<li>Extract <code>ilmbase-1.0.1.tar.gz</code> to<br /> <code>C:\libs-x64\openexr-1.6.1\openexr\ilmbase-1.0.1</code></li>
<li>Extract <code>openexr-1.6.1.tar.gz</code> to<br /> <code>C:\libs-x64\openexr-1.6.1\openexr\openexr-1.6.1</code></li>
</ol>
<h3>Using VC Express for x64 builds</h3>
<p>For Windows, OpenEXR comes with Visual Studio project files only.  So you must use Visual C++ for building.  If you&#8217;re using the <a href="http://www.microsoft.com/express/Windows/">VC Express</a> edition, that&#8217;s a problem because it only has a x86 compiler on board.  And you can&#8217;t directly use the x64 compiler of the <a href="http://en.wikipedia.org/wiki/Microsoft_Windows_SDK">Windows SDK</a>, as that requires nmake makefiles, which you don&#8217;t have.  But you can do it indirectly &#8230;</p>
<ol>
<li>Open a Windows SDK CMD shell. This sets all the required environment variables to use the x64 compiler.</li>
<li><code>"%VCINSTALLDIR%\..\Common7\IDE\VCExpress" /useenv</code> or whatever the location to vcexpress.exe is.
<p>The <code>/useenv</code> switch is important to tell the IDE not to use the default compiler, but to assume the environment is already setup ready to go.  This is exactly why we run this within the Windows SDK shell.</li>
<li>Open a solution and make sure you target the x64 platform.
<p>You won&#8217;t be able to setup a new x64 configuration, but you can just open the Win32 configuration, go to the advanced linker options and specify <code>MachineX64 (/MACHINEX64)</code> as target machine.</p>
<p><a href="http://liar.bramz.net/wp-content/uploads/2010/05/machinex64.png"><img src="http://liar.bramz.net/wp-content/uploads/2010/05/machinex64-300x205.png" alt="" title="Linker &gt; Advanced &gt; Target Machine : MachineX64" width="300" height="205" class="aligncenter size-medium wp-image-139" /></a></li>
<li>Build &#8230;</li>
</ol>
<h3>Building IlmBase</h3>
<p>IlmBase contains the createDLL project that builds a tool for the custom build steps.  You need to tweak its sources to correctly skip names starting with an underscore. Because createDLL assumes the x86 <code><a href="http://msdn.microsoft.com/en-us/library/zkwh89ks.aspx">__cdecl</a></code> calling convention which decorates names with an extra underscore, it actually only skips names that start with at least two underscores.  But the <a href="http://msdn.microsoft.com/en-us/library/9b372w95.aspx">x64</a> calling convention does not decorate them as such, so names starting with a single underscore slip through the net.</p>
<ol>
<li>Start VC Express, open<br/><code>ilmbase-1.0.1\vc\vc8\IlmBase\IlmBase.sln</code> and convert if necessary.</li>
<li>Set the target machine to <code>MachineX64</code> (see above)</li>
<li>Open <code>createDLL.cpp</code> to make the following code changes:
<ul>
<li>Replace <code>/MACHINE:X86</code> by <code>/MACHINE:X64</code> (line 683)</li>
<li>Replace the following (<strong>three </strong>occurrences!)<br />
<blockquote><p>
// symbol starts with two underbars, skip it<br />
else if (buf[0] == &#8216;_&#8217; &#038;&#038; buf[1] == &#8216;_&#8217;) {
</p></blockquote>
<p>by</p>
<blockquote><p>
// symbol starts with underbar, skip it<br />
else if (buf[0] == &#8216;_&#8217;) {
</p></blockquote>
</li>
</ul>
</li>
<li>Build &#8230;
<p>If you get errors like <code>fatal error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'</code>, you should have started VCExpress with the /useenv switch from the Windows SDK CMD shell, as described above.</li>
</ol>
<h3>Building zlib:</h3>
<p>OpenEXR has a dependency on <a href="http://zlib.net/">zlib</a>. So if you don&#8217;t have done so yet, now is the time to build it &#8230;</p>
<ol>
<li>Download <a href="http://zlib.net/">zlib125.zip</a> and extract to <code>C:\libs-x64\zlib-1.2.5</code></li>
<li>Open a Windows SDK CMD shell</li>
<li><code>cd /D C:\libs-x64\zlib-1.2.5</code></li>
<li><code>set Include=C:\libs-x64\zlib-1.2.5;%Include%</code></li>
<li><code>nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF" OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"</code></li>
</ol>
<h3>Building OpenEXR</h3>
<p>OpenEXR expects the zlib headers and libraries to be in the Deploy directory as well, so that&#8217;s where we&#8217;re going to put them.</p>
<ol>
<li>Copy <code>zlib.h</code> and <code>zconf.h</code> from <code>C:\libs-x64\zlib-1.2.5</code> to <code>Deploy\include</code></li>
<li>Copy <code>zdll.lib</code> to both <code>Deploy\lib\Debug</code> and<br/><code>Deploy\lib\Release</code></li>
<li>Copy <code>zlib1.dll</code> to both <code>Deploy\bin\Debug</code> and<br/><code>Deploy\bin\Release</code></li>
<li>Start VCExpress and open<br/><code>openexr-1.6.1\vc\vc8\OpenEXR\OpenEXR.sln</code></li>
<li>Set the target machine to <code>MachineX64</code> (see above)</li>
<li>Build &#8230;</li>
</ol>
<p>That&#8217;s it.  By now you should have a Deploy directory filled with OpenEXR headers and libraries, ready to be used in your x64 build of, for example, LiAR =)</p>
<p>Happy Towel Day!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2010/05/25/openexr-x64-windows-building/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Participating Media &#8230;</title>
		<link>http://liar.bramz.net/2010/05/04/participating-media/</link>
		<comments>http://liar.bramz.net/2010/05/04/participating-media/#comments</comments>
		<pubDate>Tue, 04 May 2010 20:07:39 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.bramz.net/?p=97</guid>
		<description><![CDATA[&#8230; are really good fun. And a huge performance killer too. Especially if you enable in-scattering on your final gather rays. Oh boy, that really hurts! Still playing around with the Sponza atrium, I wanted to do a render of sunlight being casted through the arches on the first floor. Anyway, to cut things short, [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; are really good fun. And a huge performance killer too. Especially if you enable in-scattering on your final gather rays. Oh boy, that really hurts! Still playing around with the <a href="http://hdri.cgtechniques.com/~sponza/">Sponza atrium</a>, I wanted to do a render of sunlight being casted through the arches on the first floor.  </p>
<p>Anyway, to cut things short, here&#8217;s the final render. It only took a ridiculous long time to compute (12 hours on a quadcore). Click on the image for full resolution. Tonemapping has been done in photoshop. Model &#038; textures courtesy of Marko Dabrovic.</p>
<p><a href="http://liar.bramz.net/wp-content/uploads/2010/05/sponza-participating-media.jpg"><img src="http://liar.bramz.net/wp-content/uploads/2010/05/sponza-participating-media-300x200.jpg" alt="" title="Participating Media in Sponza Atrium rendered by LiAR. Model &#038; textures courtesy of Marko Dabrovic." width="300" height="200" class="aligncenter size-medium wp-image-98" /></a></p>
<p>Adding single scattering was easy enough.  Just ray march or sample some points along your camera rays and add light source contributions to each of them using a suitable phase function.  Don&#8217;t forget to add some attenuation &#8211; Beer&#8217;s law comes to mind &#8211; to your camera rays, light rays and photon paths. Basically on anything that travels through your medium.  As phase function, I&#8217;ve chosen to use the widely used <a href="http://www.sundogpublishing.com/AtmosRad323.pdf">Henyey-Greenstein</a> model.  It isn&#8217;t particularly the fastest one around, but as I don&#8217;t have a good profiler (yet ;), I don&#8217;t really know its impact on the render time anyway.</p>
<p>Multiple scattering is somewhat of a different beast, though it&#8217;s <a href="http://en.wikipedia.org/wiki/Monte_Carlo_method_for_photon_transport">not too difficult</a> either. In the photon mapping world, it means augmenting the renderer with a volumetric photon map that records all scatter events during the photon trace pass.  For each photon that travels through a medium, you sample a possible scattering location. In case of a homogenous medium, this is as simple as feeding a uniform variate in the inverse cumulative of the <a href="http://en.wikipedia.org/wiki/Exponential_distribution">exponential distribution</a>, which can yield a travel distance from zero to infinity. If it is nearer than the first surface intersection, you store the photon and sample the phase function for a new direction. Some more details can be found in <a href="http://www.graphics.cornell.edu/~eric/Porto.html">Lafortune and Willems (1996)</a> and <a href="http://www.uni-ulm.de/fileadmin/website_uni_ulm/iui.inst.100/institut/Papers/ugiwpm.pdf">Raab, Seibert and Keller (2008)</a>.</p>
<p>In the rendering pass, I used the beam radiance estimate from <a href="http://zurich.disneyresearch.com/~wjarosz/publications/jarosz08beam.html">Jarosz, Zwicker and Jensen (2008)</a> to collect the in-scattered light from the volumetric map on the camera and final gather rays. This method represents the volumetric photons as spheres, and all photons intersected by a ray contribute to it. In case of camera rays, I ignore &#8220;single scattered&#8221; photons, as I account for single scattering seperately. </p>
<p>Because this operation weights very heavy on the final gather step, I stochastically skip the in-scattering estimate for a number of gather rays.  For each ray, a uniform variate is compared to a quality factor. Only if it is lower, volumetric photons are collected. The result is divided by the quality factor to compensate. That way I can trade speed for accuracy.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2010/05/04/participating-media/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pi and the Sponza atrium</title>
		<link>http://liar.bramz.net/2010/03/14/warming-up-in-the-sponza-atrium/</link>
		<comments>http://liar.bramz.net/2010/03/14/warming-up-in-the-sponza-atrium/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 13:15:19 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.bramz.net/?p=84</guid>
		<description><![CDATA[&#8220;you may expect updates soon&#8221; means &#8220;Look, I&#8217;m working on it, but I can&#8217;t pull all-nighters anymore. So, it&#8217;s going to take a while, OK?&#8221; =) So, a mere three weeks after that previous statement, here&#8217;s my first real update on the LiAR ray tracer. What have I been doing? Well, I concentrated my efforts [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;you may expect updates soon&#8221; means &#8220;Look, I&#8217;m working on it, but I can&#8217;t pull all-nighters anymore. So, it&#8217;s going to take a while, OK?&#8221; =)  So, a mere three weeks after that previous statement, here&#8217;s my first real update on the LiAR ray tracer.  What have I been doing?  Well, I concentrated my efforts on the <a href="http://hdri.cgtechniques.com/~sponza/">Sponza atrium</a>, to get this one rendered correctly and fast enough.  Although it&#8217;s an old challenge, I figured that if I wouldn&#8217;t be able to tackle this one, there&#8217;s no point in trying more up to date ones.  So here&#8217;s a list of things improved over the last couple of weeks:</p>
<ul>
<li>Added <strong>TriangleMeshComposite</strong> which merges the triangle meshes of different objects into one acceleration tree.  This is especially important in the Sponza atrium, as the 34 different <code>TriangleMesh</code> objects in the sponza scene largely overlap.  So ray traversals are going to hit the bounding boxes of most of them, most of the time, and as such the traversal degrades to a linear search of the scene objects.  Using the TriangleMeshComposite, ray traversal visits only one triangle mesh.</li>
<li><strong>LightSky</strong> caches the radiances in a rasterized map, using the same resolution as the CDF map.  This ensures better coherence with the PDFs of the drawn samples (using importance sampling)</li>
<li>Using <strong>Multiple Importance Sampling</strong> for the direct lighting pass solves a lot of the noise issues in the shadows (otherwise, most of the shadow rays are aimed at the sun and thus blocked)</li>
<li><strong>Final Gather step</strong> uses the local effective estimation radius to decide if secondary gather rays are necessary.  Before, it used the global maximum estimation radius, but that one needs to be quite large.  So the secondary gather step was triggered a lot, causing either a huge performance hit, or a quality drop.  In areas with high photon density, this threshold may be lower as the photon map is much more detailed and the need for second gather rays averted.  The rule is now that secondary gathering is only used if the length of the first gather ray is smaller than the effective estimation radius of the photon lookup. Otherwise, it is assued that the first gather step is of sufficient quality.</li>
<li>The <strong>samplers</strong> (Stratifier and LatinHypercube) take into account the pixel super sampling when generating samples for lights, BSDFs, gather rays, &#8230;  For example, when using 3&#215;3 super sampling with 8&#215;8 gather rays each, the stratifier will generate the gather samples on a (3*8)x(3*8) grid.</li>
<li>The shaders now return a <strong>BSDF</strong> instance, caching the texture lookups.  Don&#8217;t know why I haven&#8217;t done this before, but it surely helps with complex textures &#8230;</li>
<li>Added JPEG and OpenEXR <strong>image codecs</strong></li>
<li>Lots of improvements to the <strong>Blender exporter</strong>, though there&#8217;s still lots and lots missing</li>
</ul>
<p>Here&#8217;s a render showing the current state of LiAR.  Click on the image for full resolution.  Tonemapping has been done in photoshop.  Model &#038; textures courtesy of Marko Dabrovic.</p>
<p><a href="http://liar.bramz.net/wp-content/uploads/2010/03/sponza2_liar.jpg"><img src="http://liar.bramz.net/wp-content/uploads/2010/03/sponza2_liar-300x200.jpg" alt="" title="Sponza Atrium rendered by LiAR.  Model &#038; textures courtesy of Marko Dabrovic." width="300" height="200" class="aligncenter size-medium wp-image-90" /></a></p>
<p>Work on a ray tracer is of course never done, and even for this Sponza atrium, there&#8217;s still room for improvement, both quality and performance wise.  Here&#8217;s a bit of a TODO list for the near and far future:</p>
<ul>
<li>Improve final gathering quality, using importance sampling based on the directions of the local photons</li>
<li>Use a profiler to investigate how much can be gained by improving the performance of the ray traversals and Kd-tree lookups</li>
<li>Use caching and subsampling to improve the perfomance and smoothness of the indirect lighting</li>
<li>Add volumetric stuff</li>
<li>Spectral rendering.  Now I&#8217;m using XYZ values everywhere, which is (a) physically wrong and (b) doesn&#8217;t allow dispersion</li>
<li>Implement subtractive lighting to render objects with an existing backdrop in one pass.</li>
<li>Implement the Metropolis Light Transport algorithm</li>
</ul>
<p>Stay tuned, and happy Pi day!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2010/03/14/warming-up-in-the-sponza-atrium/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>liar in a revival</title>
		<link>http://liar.bramz.net/2010/02/20/liar-in-a-revival/</link>
		<comments>http://liar.bramz.net/2010/02/20/liar-in-a-revival/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 13:55:36 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.bramz.net/?p=69</guid>
		<description><![CDATA[OK, it has been more than two years since my last update on liar.bramz.net. Back then, we moved from liar.sf.net to liar.bramz.org to liar.bramz.net, the subversion repository got a new URL, and everything went silent. What happened? Well, I started taking real pictures instead, that&#8217;s what happened &#8230; And I started doing it quite regularly [...]]]></description>
			<content:encoded><![CDATA[<p>OK, it has been <em>more than two years</em> since my last update on liar.bramz.net.  Back then, we moved from liar.sf.net to liar.bramz.org to liar.bramz.net, the subversion repository got a new URL, and everything went silent.  What happened?  </p>
<p>Well, I started taking <a href="http://www.bramdegreve.com/">real pictures</a> instead, that&#8217;s what happened &#8230;  And I started doing it quite regularly as well, mostly concert photography.  Started shooting befriended bands, then I joined <a href="http://www.indiestyle.be/">Indiestyle</a> and later I was the in-house photographer of <a href="http://www.westtalent.be/">Westtalent 2009</a>.</p>
<p>But then, fellow indiestyler <a href="http://www.jaanmeert.be/">Jaan Meert</a> posted on facebook a 3D render of a lego tractor he made for school.  And that&#8217;s got it  itching again &#8230;  I wanted to do 3D renders myself, but it LiAR was severely out of shape.  So shaping has to be done, and after all this time, coding on LiAR is fun again.</p>
<p>Currently, I&#8217;m working on the good old <a href="http://hdri.cgtechniques.com/~sponza/">sponza atrium</a>, to get things in good condition to tackle further challenges.  I&#8217;m using <a href="http://www.blender.org/">Blender</a> as a platform to set up the scene, and export it to a python script for LiAR.  It&#8217;s working as a charm, and you may expect updates soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2010/02/20/liar-in-a-revival/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Plücker coordinates not so good for you?</title>
		<link>http://liar.bramz.net/2007/07/17/plucker-coordinates-not-so-good-for-you/</link>
		<comments>http://liar.bramz.net/2007/07/17/plucker-coordinates-not-so-good-for-you/#comments</comments>
		<pubDate>Tue, 17 Jul 2007 16:49:37 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[in other news]]></category>

		<guid isPermaLink="false">http://liar.bramz.org/2007/07/17/plucker-coordinates-not-so-good-for-you/</guid>
		<description><![CDATA[Christer Ericson, author of Real-Time Collision Detection has written a little article on Plücker coordinates and why they are considered harmful. It&#8217;s great. I never really understood what all the fuss was about, as I could do the Plücker coord tricks as easily with basic 3D linear algebra and its triple product. So, I&#8217;m glad [...]]]></description>
			<content:encoded><![CDATA[<p>Christer Ericson, author of <a href="http://realtimecollisiondetection.net/books/rtcd/">Real-Time Collision Detection</a> has written a little article on Plücker coordinates and <a href="http://realtimecollisiondetection.net/blog/?p=13">why they are considered harmful</a>.  It&#8217;s great.  I never really understood what all the fuss was about, as I could do the Plücker coord tricks as easily with basic 3D linear algebra and its triple product.  So, I&#8217;m glad to see some of the big guys agree!</p>
<p>(via <a href="http://psgraphics.blogspot.com/2007/07/plucker-coords-considered-harmful.html">Pete Shirley&#8217;s Graphics Blog</a>)</p>
<p>&#8220;LiAR is entirely Plücker free&#8221; ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/07/17/plucker-coordinates-not-so-good-for-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>new URL for Subversion access</title>
		<link>http://liar.bramz.net/2007/06/12/new-url-for-subversion-access/</link>
		<comments>http://liar.bramz.net/2007/06/12/new-url-for-subversion-access/#comments</comments>
		<pubDate>Tue, 12 Jun 2007 11:26:50 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.bramz.org/2007/06/12/new-url-for-subversion-access/</guid>
		<description><![CDATA[As of 28 June 2007, Sourceforge will decommission the SVN access URLs starting with https://svn.sourceforge.net/svnroot/. They are replaced by URLs with the project names in front. For LiAR, this looks like https://liar.svn.sourceforge.net/svnroot/. The new URL scheme is part of an upgrade of the Subversion access method to improve its stability. If your local working copy [...]]]></description>
			<content:encoded><![CDATA[<p>As of 28 June 2007, Sourceforge will decommission the SVN access URLs starting with https://svn.sourceforge.net/svnroot/.  They are replaced by URLs with the project names in front.  For LiAR, this looks like https://liar.svn.sourceforge.net/svnroot/.  The new URL scheme is part of an upgrade of the Subversion access method to improve its stability.  If your local working copy uses the old URL, follow the <a href="https://sourceforge.net/docs/E09#notice">switch instructions</a> so that you can still access the repository after 28 June.</p>
<p>PS: I know LiAR has been silent for the last couple of months.  There was just too many other things to take care off.  However, the last couple of weeks, I&#8217;ve resumed coding on LiAR, albeit slowly, so hopefully I will be able to add some new posts in the near future.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/06/12/new-url-for-subversion-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>we&#8217;ve moved to liar.bramz.net</title>
		<link>http://liar.bramz.net/2007/02/08/weve-moved-to-liar-bramz-net/</link>
		<comments>http://liar.bramz.net/2007/02/08/weve-moved-to-liar-bramz-net/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 00:11:06 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.bramz.org/2007/02/08/weve-moved-to-liarbramzorg/</guid>
		<description><![CDATA[We&#8217;ve successfully moved the LiAR home page to http://liar.bramz.net. This should allow us to upload bigger renders, and get better search engine coverage. The old URLs starting with http://liar.sourceforge.net should redirect traffic to the new site so that no links get broken. Share and Enjoy!]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve successfully moved the LiAR home page to <a href="http://liar.bramz.net/">http://liar.bramz.net</a>.  This should allow us to upload bigger renders, and get better search engine coverage.  The old URLs starting with <a href="http://liar.sourceforge.net">http://liar.sourceforge.net</a> should redirect traffic to the new site so that no links get broken.</p>
<p>Share and Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/02/08/weve-moved-to-liar-bramz-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>things learnt while installing VS2005 SP1 &#8230;</title>
		<link>http://liar.bramz.net/2007/02/07/things-learnt-while-installing-vs2005-sp1/</link>
		<comments>http://liar.bramz.net/2007/02/07/things-learnt-while-installing-vs2005-sp1/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 23:09:40 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/02/07/things-learnt-while-installing-vs2005-sp1/</guid>
		<description><![CDATA[If you&#8217;re planning to install Visual Studio 2005 Service Pack 1, keep this in mind: Make sure you have at least three gigs of free space on your C: drive. To be on the safe side, make it four gigs. Windows Update tries to shove this up your arse as a security update, but don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re planning to install <a href="http://msdn2.microsoft.com/en-us/vstudio/bb265237.aspx">Visual Studio 2005 Service Pack 1</a>, keep this in mind:</p>
<ul>
<li>Make sure you have <a href="http://www.virtualdub.org/blog/pivot/entry.php?id=136">at least three gigs of free space on your C: drive</a>.  To be on the safe side, make it four gigs.</li>
<li>Windows Update tries to shove this up your arse as a security update, but don&#8217;t let it.  Do a <a href="http://msdn2.microsoft.com/en-us/vstudio/bb265237.aspx">manual install</a> instead.</li>
<li>Log in as Administrator.  I know you already have super monkey admin powers, but do it anyway.</li>
</ul>
<h3>The aftermath?</h3>
<p>Well, it did solve the test errors we had in the <code>win32_vc8</code> build of <a href="http://lass.sourceforge.net/">Lass</a>, like the <code>fld</code> loading corrupt data on the FPU stack.  It also solved the <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101619">template class member function overload ambiguity</a> we suffered in <code>testUtilThreadFun</code>.</p>
<p>It did cause some other troubles though.  Apparently SP1 screws up on default arguments in function template declarations.  In <code>lass::prim</code>, all intersection functions are implemented in <code>*.inl</code> files with the function declarations being listed in the accompanying <code>*.h</code> file.  These functions have a parameter <code>tMin</code> that defaults to zero.  This worked/works fine on VC6, 7, 7.1 and 8 sans SP1, all GCCs I could get my hands on, but not on VC8 SP1.  It still compiles the code, but at runtime, <code>tMin</code> contains garbage when the default value is used.  Unfortunately, I was unable to reproduce the problem on a smaller scale.  Anyway, the solution to this problem was to move all intersection functions to the header files so that the separate function declarations no longer exist.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/02/07/things-learnt-while-installing-vs2005-sp1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>overriding default compiler options in distutils</title>
		<link>http://liar.bramz.net/2007/01/29/overriding-default-compiler-options-in-distutils/</link>
		<comments>http://liar.bramz.net/2007/01/29/overriding-default-compiler-options-in-distutils/#comments</comments>
		<pubDate>Mon, 29 Jan 2007 21:06:33 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/01/29/overriding-default-compiler-options-in-distutils/</guid>
		<description><![CDATA[While debugging another segmentation fault on linux, I was trying to run LiAR in gdb (actually KDbg). The program crashed somewhere in an allocator, but the reason why was almost impossible to see. The debugging experience was crippled because distutils compiles with full optimization -O3 by default, at least my linux box. If I was [...]]]></description>
			<content:encoded><![CDATA[<p>While debugging another segmentation fault on linux, I was trying to run LiAR in <a href="http://sourceware.org/gdb/">gdb</a> (actually <a href="http://www.kdbg.org/">KDbg</a>).  The program crashed somewhere in an allocator, but the reason why was almost impossible to see.  The debugging experience was crippled because <code>distutils</code> compiles with full optimization <code>-O3</code> by default, at least my linux box.</p>
<p>If I was going to debug it properly, I would have to get rid of that switch and use <code>-O0</code> instead.  But for some mysterious reason, <code>distutils</code> always used <code>-DNDEBUG -g -O3 -Wall -Wstrict-prototypes</code>, regardless of the <code>--debug</code> switch.  It turns out <code>distutils</code> is getting these from the original <code>Makefile</code> used to build Python and stores them, together with the name <code>gcc</code>, in an attribute <code>compiler_so</code> of the <code>CCompiler</code> object.  This attribute is later used to invoke the compiler.</p>
<p>Fortunately, in <code>liar_build_shared_lib</code> and <code>liar_build_ext</code>, we have access to the compiler object.  All we have to do is, before building, to grab <code>compiler_so</code>, remove any <code>-O</code> switch and put an <code>-O0</code> instead:</p>
<pre>def force_no_optimisation(compiler):
    for i in range(4):
        try: compiler.compiler_so.remove("-O%s" % i)
        except: pass
    compiler.compiler_so.append("-O0")

class liar_build_shared_lib(build_clib):
    def build_library(self, lib_name, build_info):
        force_no_optimisation(self.compiler)
        ...

class liar_build_ext(build_ext):
    def build_extension(self, ext):
        force_no_optimisation(self.compiler)
        ...</pre>
<p>What was causing the segmentation fault?  The <code>std::vector</code> in <code>kernel::Intersection</code> was requesting memory for 0 elements.  The <code>lass::util::AllocatorBinned</code> wasn&#8217;t really prepared for that.  Once identified, it was easily fixed &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/01/29/overriding-default-compiler-options-in-distutils/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>shared libraries, RTTI and dlopen</title>
		<link>http://liar.bramz.net/2007/01/28/shared-libraries-dlopen-and-rtti/</link>
		<comments>http://liar.bramz.net/2007/01/28/shared-libraries-dlopen-and-rtti/#comments</comments>
		<pubDate>Sun, 28 Jan 2007 16:02:58 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/01/28/shared-libraries-dlopen-and-rtti/</guid>
		<description><![CDATA[When I tried to run a first render in linux, I got a segmentation fault in the photon mapper because there were no lights. Of course, this shouldn&#8217;t cause a crash (fixed by now), but why were there no lights? I was pretty sure I defined one, and a quick investigation of the scene graph [...]]]></description>
			<content:encoded><![CDATA[<p>When I tried to run a first render in linux, I got a segmentation fault in the photon mapper because there were no lights.  Of course, this shouldn&#8217;t cause a crash (fixed by now), but why were there no lights?  I was pretty sure I defined one, and a quick investigation of the scene graph confirmed this.</p>
<p>Before rendering is started, <code>SceneLight</code> instances are harvested from the scene graph by a visitor <a href="http://lass.svn.sourceforge.net/viewvc/liar/trunk/liar/src/kernel/light_context.cpp?view=markup"><code>LightContextGatherer</code></a> to collect all instances of <code>SceneLight</code> objects.  It&#8217;s an acyclic visitor as described by <a href="http://erdani.org/">Andrei Alexandrescu</a>.</p>
<pre>class LightContextGatherer:
    public util::VisitorBase,
    public util::Visitor&lt;SceneObject&gt;,
    public util::Visitor&lt;SceneLight&gt;
{
    void doVisit(SceneObject&amp;);
    void doVisit(SceneLight&amp;);
};</pre>
<p>The way it works is that if a scene object, for example a <code>LightArea</code>, accepts a visitor, it tries to cast the visitor to <code>util::Visitor&lt;LightArea&gt;</code>. If it succeeds, it will call the appropriate <code>doVisit</code> function.  Otherwise, it tries again using its parent type, in this case <code>SceneLight</code>.  As a result, all lights instances end up in <code>doVisit(SceneLight&amp;)</code>, and all other objects in <code>doVisit(SceneObject&amp;)</code>.</p>
<p>But for some reason, neither <code>doVisit</code> was ever called.  It turned out that the <code>dynamic_cast</code>, used to cast the visitor to the appropriate type, <em>always</em> returned null, even when trying to cast to <code>util::Visitor&lt;SceneObject&gt;</code>.  Huh?</p>
<p>Some googling revealed that GCC 3.0 uses <a href="http://gcc.gnu.org/faq.html#dso">address comparisons to determine type equality</a>.  This obviously has a performance advantage over string comparisons, but doesn&#8217;t work quite well if left and right have a different set of <code>typeinfo</code> instances.  This can when using dynamic linkage, and it certainly doesn&#8217;t help that Python uses <code>dlopen</code> to load extension modules. </p>
<p>Fortunately, the GCC FAQ also mentions a solution which is to link with the <code>-E</code> flag to add all symbols to the dynamic symbol table, and to use <code>dlopen</code> with the <code>RTLD_GLOBAL</code> flag set. For LiAR, the former means adding <code>-Wl,-E</code> to <code>extra_link_args</code> in <a href="http://lass.svn.sourceforge.net/viewvc/liar/trunk/liar/setup.py?view=markup"><code>setup.py</code></a>.  The latter can be done using <a href="http://mail.python.org/pipermail/c++-sig/2005-April/008829.html"><code>sys.setdlopenflags</code></a>.  Proper <code>try/except</code> wrapping ensures that it is only called if appropriate.  At least one linux system did not provide the <code>dl</code> module, but fortunately the same constants also live in <code>DLFCN</code> (also not always available), so that&#8217;s why the heavy nesting.  The code is put at the beginning of <a href="http://lass.svn.sourceforge.net/viewvc/liar/trunk/liar/src/__init__.py?view=markup"><code>__init__.py</code></a>.</p>
<pre>try:
    try:
        import dl
    except:
        try:
            import DLFCN as dl
        except:
            pass
    sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
except:
    pass</pre>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/01/28/shared-libraries-dlopen-and-rtti/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>the bumpy road to the linux build</title>
		<link>http://liar.bramz.net/2007/01/27/the-bumpy-road-to-the-linux-build/</link>
		<comments>http://liar.bramz.net/2007/01/27/the-bumpy-road-to-the-linux-build/#comments</comments>
		<pubDate>Sat, 27 Jan 2007 22:03:06 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/01/27/the-bumpy-road-to-the-linux-build/</guid>
		<description><![CDATA[The description of LiAR says: &#8220;&#8216;LiAR isn&#8217;t a raytracer&#8217; is an open source, cross platform, object-oriented and extendable ray tracer written in C++ and Python by Bram de Greve&#8221;. However, that&#8217;s not entirely true since currently, LiAR only runs on the Windows platform. It&#8217;s time to live up to the promise. To be honnest, I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>The description of LiAR says: <em>&#8220;&#8216;LiAR isn&#8217;t a raytracer&#8217; is an open source, <strong>cross platform</strong>, object-oriented and extendable ray tracer written in C++ and Python by Bram de Greve&#8221;</em>.  However, that&#8217;s not entirely true since currently, LiAR only runs on the Windows platform.  It&#8217;s time to live up to the promise.  To be honnest, I&#8217;ve attempted it before but I ran into troubles and I gave up.  Now I want to pursue it to the end, however.  And while I encounter and overcome the obstacles, I&#8217;ll try to document them.</p>
<p>The goal is to use Python&#8217;s <a href="http://www.python.org/community/sigs/current/distutils-sig/"><code>distutils</code></a> and write a single <code>setup.py</code> to build and install LiAR.  So no <code>make</code> or autotools are allowed.  The idea is that eventually, the <code>setup.py</code> can be used to build LiAR on Windows as well.  I&#8217;ve decided against using <a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a> (eggs) and <a href="http://www.scons.org/">SCons</a> because <code>distutils</code> is already included in the standard libraries of Python. But first, I&#8217;ll be trying to get it working on linux alone, what is already good for quite some challenges.</p>
<p>First, a recap of how LiAR is built.  It consists of different (extension) modules organized in a star topology.  The center module is called the <code>kernel</code> and provides general definitions (<code>Spectrum</code>, <code>Intersection</code>, &#8230;) and abstract classes (<code>SceneObject</code>, <code>Shader</code>, <code>Texture</code>, &#8230;) that are used as vessels and ports by which the concrete modules (<code>scenery</code>, <code>shaders</code>, <code>textures</code>) must communicate.  Each concrete module only depends on <code>kernel</code> (and of course 3rd party libraries if appropriate), and since LiAR is implemented in C++ this means including its headers and linking to it dynamically.</p>
<p>Unfortunately, <code>distutils</code> is not designed for architecture like that.  It can build multiple extension modules in a single package, but they&#8217;re supposed to be independent of each other.  They cannot be linked in a binary way, communication should be done through Python.  Modules don&#8217;t have the usual <code>libfoo.so</code> name anyway.  However, distutils does support the build of C libraries that the extension modules can link against, but only for <em>static</em> libraries and what we need is dynamic linkage.</p>
<p>This calls for a bit of hacking.  Luckily, <code>distutils</code> has a mechanism that allows to add extra custom commands.  This can be used to hijack the <code>build_clib</code> command (for static libraries) and use it to build shared libraries.  A new command <code>liar_build_shared_lib</code> is derived from <code>build_clib</code> and the relevant methods are overridden.  It&#8217;s a bit too long to post here (you can see for yourself in the <a href="http://svn.sourceforge.net/viewvc/liar/trunk/liar/setup.py?view=markup">code repository</a>), but basically it&#8217;s a blend between <code>build_clib</code> and <code>build_ext</code>.  The <code>cmdclass</code> argument in <code>setup()</code> is used to inject <code>liar_build_shared_lib</code> as the new <code>build_clib</code>.</p>
<p>The concrete modules need to be linked to <code>kernel</code>, but a Python extension module does not have the regular <code>libfoo.so</code> name, but simply <code>foo.so</code> instead.  What I&#8217;ve done to solve this, is to create <code>libkernel.so</code> which is <code>kernel</code> sans <code>kernel_init.cpp</code>, and a shallow module <code>kernel.so</code> that consists only of <code>kernel_init.cpp</code>.  This way, all modules can link to a regular library, and <code>kernel.so</code> exposes its content to Python.</p>
<p>By now, things pretty much compile.  I can even <code>import liar</code> in Python, though I must use the <code>LD_LIBRARY_PATH</code> environment variable hack to tell the modules where they can find <code>libkernel.so</code>.  And once I start running some scripts I quickly get segmentation faults.  So there are still some things to solve =)</p>
<p>Also, I need to clean up <code>setup.py</code> a bit, because things were simply thrown together until it worked.  Options are still pretty much hardcoded.  And also, I would like to be install the kernel headers so that custom LiAR extensions can be build using the installed LiAR.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/01/27/the-bumpy-road-to-the-linux-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>clip mapping</title>
		<link>http://liar.bramz.net/2007/01/23/clip-mapping/</link>
		<comments>http://liar.bramz.net/2007/01/23/clip-mapping/#comments</comments>
		<pubDate>Wed, 24 Jan 2007 01:57:38 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/01/23/clip-mapping/</guid>
		<description><![CDATA[I&#8217;ve added clip mapping (*) to LiAR, which is some sort of alpha channel for surfaces. It can be used to create holes in a surface using a texture. The texture is compared to a threshold to determine where the surface should be removed, so that rays can travel undisturbed through the removed parts. This [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve added clip mapping (*) to LiAR, which is some sort of alpha channel for surfaces.  It can be used to create holes in a surface using a texture. The texture is compared to a threshold to determine where the surface should be removed, so that rays can travel undisturbed through the removed parts.</p>
<p>This is different from using a fully transparent BSDF because the latter will split ray paths by inserting a no-op scattering event.  This is especially a major difference for shadow rays in a direct lighting pass: they block on the first scattering event causing the transparent parts to cast shadows. When using clip mapping, no scattering event will be inserted because the surface is not present, and thus shadows will be casted as expected.</p>
<p><img alt="a sphere clip mapped by a CheckerVolume" title="a sphere clip mapped by a CheckerVolume" src="http://liar.bramz.net/images/renders/examples/scenery/clip_map.jpg" /></p>
<p>It&#8217;s implemented as a special scene object <a href="http://liar.svn.sourceforge.net/viewvc/liar/trunk/liar/src/scenery/clip_map.cpp?view=markup">ClipMap</a> that takes a child object and a clip texture.  When the object is tested for ray intersections, a candidate intersection with the child object is searched for, and if one is found the clip texture is evaluated using the local intersection context of the child object. If this yields a value above a threshold, the intersection is accepted.  Otherwise, a new candidate intersection is searched for with an adjusted near limit of the bounded ray.</p>
<p>It was pretty easy to implement, however not without cost.  The intersection context needs to be evaluated independently of the one used for shading.  Worse, the used intersection context may be different depending on <a href="http://liar.bramz.net/blog/fixing-transformations-and-local-geometry/">which level the shader is defined</a>. Also, the function isIntersecting can no longer use any shortcuts, but must perform a full intersection test.</p>
<pre>while (true)
{
    child_-&gt;intersect(sample, ray, intersection);
    if (!intersection)
    {
        result.swap(intersection);
        return;
    }
    child_-&gt;localContext(sample, ray, intersection,
        context);

    if (clipMap_-&gt;lookUp(sample, context).average()
        &gt;= threshold_)
    {
        intersection.push(this);
        result.swap(intersection);
        return;
    }
    ray = bound(ray, intersection.t(), ray.farLimit());
}</pre>
<p>You can try it out for yourself using the <a href="http://liar.svn.sourceforge.net/viewvc/liar/trunk/liar/examples/scenery/clip_map.py?view=markup">clip_map.py</a> example in the examples/scenery directory.</p>
<p>(*) The term clip mapping is being used in <a href="http://www.newtek.com/lightwave/">LightWave 3D</a> and some other renders, and also appears in the book <a href="http://www.3drender.com/light/index.html">Digital Lighting &#038; Rendering</a> by Jeremy Birn. However is also used for naming the act of loading small parts of huge mipmaps to reduce memory requirements.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/01/23/clip-mapping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>subdivision surfaces and UV interpolation problem</title>
		<link>http://liar.bramz.net/2007/01/10/subdivision-surfaces-and-uv-interpolation-problem/</link>
		<comments>http://liar.bramz.net/2007/01/10/subdivision-surfaces-and-uv-interpolation-problem/#comments</comments>
		<pubDate>Wed, 10 Jan 2007 19:45:57 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2007/01/10/subdivision-surfaces-and-uv-interpolation-problem/</guid>
		<description><![CDATA[I&#8217;m trying to use the subdivision surfaces I&#8217;ve implemented to get a smoother surface for car i&#8217;m rendering for PHD Motorsports. The original model has UV coordinates that need to be interpolated as well. As each triangle is split in four, each edge is split two. I&#8217;ve been using the naive assumption that for the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m trying to use the <a href="http://liar.bramz.net/2006/12/12/loop-subdivision-surfaces/">subdivision surfaces</a> I&#8217;ve implemented to get a smoother surface for car i&#8217;m rendering for <a href="http://www.phd-motorsports.com/">PHD Motorsports</a>.  The original model has UV coordinates that need to be interpolated as well.  As each triangle is split in four, each edge is split two.  I&#8217;ve been using the naive assumption that for the UV coordinates of the new vertices, I can use the average of the two original vertices of the edge.  As can be seen from the following renders, that doesn&#8217;t quite work.  The UV mapping gets severely distorted.</p>
<p><img alt="distorition of UV coordinates when using naive UV interpolation in subdivision surfaces" title="distorition of UV coordinates when using naive UV interpolation in subdivision surfaces" src="http://liar.bramz.net/images/renders/misc/subdivision_uv_problem.jpg" /></p>
<p>So, I&#8217;ll have to search for something more clever.  Probably something similar as for the vertex coordinates.  However, I wonder what to do with seams in the texture mapping &#8230;  To be continued &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2007/01/10/subdivision-surfaces-and-uv-interpolation-problem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>loop subdivision surfaces</title>
		<link>http://liar.bramz.net/2006/12/12/loop-subdivision-surfaces/</link>
		<comments>http://liar.bramz.net/2006/12/12/loop-subdivision-surfaces/#comments</comments>
		<pubDate>Wed, 13 Dec 2006 00:01:13 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2006/12/12/loop-subdivision-surfaces/</guid>
		<description><![CDATA[I&#8217;ve implemented subdivision surfaces for the TriangleMesh using the Loop&#8217;s scheme. Triangles are split in four, and the vertices are weighted using masks to produce a smoother surface. This process is repeated a few times, indicated by the subdivision level. The implementation also supports the concept of creases. If an edge of the mesh has [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve implemented <a title="SIGGRAPH 2000 course notes on subdivision surfaces, as a good summary ..." href="http://mrl.nyu.edu/publications/subdiv-course2000/">subdivision surfaces</a> for the TriangleMesh using the Loop&#8217;s scheme. Triangles are split in four, and the vertices are weighted using masks to produce a smoother surface.  This process is repeated a few times, indicated by the subdivision level.</p>
<p>The implementation also supports the concept of creases.  If an edge of the mesh has a crease level different than zero, the subdivision must leave the edge sharp for a number of iterations equal to the crease level.  For example, if an edge has crease level three, and a subdivision of five levels is applied, then the algorithm must leave the edge sharp for the first three iterations, and may only smooth it for the last two.  This will give the edge a sharper appearance than the rest of the mesh.  If the crease level is equal or greater than the subdivision level (for example both level five), then the edge will stay ultra sharp, since the algorithm will never be allowed to smooth it.</p>
<p>In the following image, the same cube is shown for different subdivision and crease levels. There are no vertex normals used, to clearly show the different faces of each resulting triangle mesh.    So no sneaky normal interpolation to give the mesh a smooth appearance!</p>
<p><img alt="The same cube with different settings of subdivision and crease level" title="The same cube with different settings of subdivision and crease level" src="http://liar.bramz.net/images/renders/examples/scenery/loop_subdivision.jpg" /></p>
<p>At three o&#8217;clock, there&#8217;s a perfect cube with subdivison level zero.  Going in counterclockwise order, the subdivision is each time increased by one level.  At nine o&#8217;clock, subdivision level six is reached, resulting in a very smooth object.  Remember there are no vertex normals here!</p>
<p>Continuing in counterclockwise order, the subdivision level is now kept at constant of six, but the crease level of the cube&#8217;s edges is each time increased by one. The circle would be closed again at three o&#8217;clock with both the subdivision and creasing at level six, but this is virtually the same as the original cube (both at level zero), only with a much finer triangle mesh.</p>
<p>You can try all this for yourself using the example <a href="http://svn.sourceforge.net/viewvc/liar/trunk/liar/examples/scenery/loop_subdivision.py?view=markup">loop_subdivision.py</a> in the examples/scenery subdirectory.</p>
<p>PS: you will have to update your Lass installation to use this, since the actual subdivision code is part of Lass.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/12/12/loop-subdivision-surfaces/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FZR in Uffizi (and thin dielectrics)</title>
		<link>http://liar.bramz.net/2006/12/02/fzr-in-uffizi-and-thin-dielectrics/</link>
		<comments>http://liar.bramz.net/2006/12/02/fzr-in-uffizi-and-thin-dielectrics/#comments</comments>
		<pubDate>Sat, 02 Dec 2006 14:28:27 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2006/12/02/fzr-in-uffizi-and-thin-dielectrics/</guid>
		<description><![CDATA[I&#8217;ve reproduced the older FZR render using the Ashikhmin &#038; Shirley BSDF and the Uffizi Gallery light probe. For the glass of the windows and the head lights, I&#8217;ve implemented a new material called ThinDielectric that acts as a thin (but not very) pane of glass. Given an inner refraction index and transparency factor for [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve reproduced the <a href="http://liar.bramz.net/2005/12/15/phd-motorsports-fzr/">older FZR render</a> using the Ashikhmin &#038; Shirley BSDF and the Uffizi Gallery light probe.  For the glass of the windows and the head lights, I&#8217;ve implemented a new material called ThinDielectric that acts as a thin (but not very) pane of glass.  Given an inner refraction index and transparency factor for the medium, it simulates multiple reflections and transmissions due to the bouncing of the light inside the pane.  Maybe I will write it more properly some day, but here&#8217;s how it goes in a nutshell:</p>
<ul>
<li><img class='latexrender' src='/wp-content/plugins/latexrender/pictures/f5f7b4bae0c7f3e1f3526669944e4b30_7.50009pt.gif' title='R = r \left(1 + \frac{\left(1 \minus r\right)^2 t^2}{1 &amp;#8211; r^2 t^2}\right)' alt='R = r \left(1 + \frac{\left(1 \minus r\right)^2 t^2}{1 &amp;#8211; r^2 t^2}\right)'  style="vertical-align:-7.50009pt;"  /></li>
<li><img class='latexrender' src='/wp-content/plugins/latexrender/pictures/d1debff7937ced17463b602cd1e9de2c_5.80951pt.gif' title='T = \frac{\left(1 &amp;#8211; r\right)^2 t^2}{1 &amp;#8211; r^2 t^2}' alt='T = \frac{\left(1 &amp;#8211; r\right)^2 t^2}{1 &amp;#8211; r^2 t^2}'  style="vertical-align:-5.80951pt;"  /></li>
</ul>
<p>with:</p>
<ul>
<li><img class='latexrender' src='/wp-content/plugins/latexrender/pictures/e1e1d3d40573127e9ee0480caf1283d6_1.0pt.gif' title='R' alt='R'  style="vertical-align:-1.0pt;"  /> and <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/b9ece18c950afbfa6b0fdbfa4ff731d3_1.0pt.gif' title='T' alt='T'  style="vertical-align:-1.0pt;"  /> the resulting reflectance and transmittance <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/b137a079d84a4c932ee591ba9d911fdc_3.5pt.gif' title='\left(R + T &lt; 1\right)' alt='\left(R + T &lt; 1\right)'  style="vertical-align:-3.5pt;"  /></li>
<li><img class='latexrender' src='/wp-content/plugins/latexrender/pictures/4b43b0aee35624cd95b910189b3dc231_1.0pt.gif' title='r' alt='r'  style="vertical-align:-1.0pt;"  /> is your usual fresnel reflectance</li>
<li><img class='latexrender' src='/wp-content/plugins/latexrender/pictures/23540960f2328dbdc619a9f6607c4cd4_1.0pt.gif' title='t = \tau ^ {\frac 1 {\cos \theta_t}' alt='t = \tau ^ {\frac 1 {\cos \theta_t}'  style="vertical-align:-1.0pt;"  /> is the transmittance of the medium using Beer&#8217;s law where <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/a6f317b268ae825d94f832f970af607c_1.0pt.gif' title='\tau' alt='\tau'  style="vertical-align:-1.0pt;"  /> is the transparency of the medium and <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/ed9ce17598e0d756f6622f23a5e3d568_2.49998pt.gif' title='\cos \theta_t' alt='\cos \theta_t'  style="vertical-align:-2.49998pt;"  /> is the cosine of the angle of the refracted rays inside the material</li>
</ul>
<p><img title="FZR with PHD-Motorsports skin in Uffizi gallery" alt="FZR with PHD-Motorsports skin in Uffizi gallery" src="http://liar.sourceforge.net/images/renders/phdmotorsports/fzr_uffizi.jpg" /></p>
<p>Model by <a href="http://www.liveforspeed.net">Live for Speed</a>, light probe by <a href="http://www.debevec.org/Probes/">Paul Debevec</a>, custom skin by <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a>.</p>
<p><strong>update:</strong> this render is also featured in the <a href="http://www.flipcode.dxbug.com/board/topic/623/0">#flipcode gallery</a>.</p>
<p><strong>update:</strong> Nicholas &#8220;Ono-Sendai&#8221; Chapman of the <a href="http://www.indigorenderer.com/">Indigo Renderer</a> has pointed out that <a href="http://radsite.lbl.gov/radiance/">Radiance</a> is using a very similar BSDF for their <a href="http://radsite.lbl.gov/radiance/refer/materials.pdf">glass material</a>.  This is not so surprising, since it&#8217;s a very simple extension of the Fresnel equations. The only difference is the distinction between TE and TM waves, which is more correct than what I&#8217;m currently doing.</p>
<p><strong>update:</strong> Leonhard Gruenschloss noticed a few typos in my formulas (see comments).  I&#8217;ve corrected them now Thanks Leonhard! (20 feb. 2007)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/12/02/fzr-in-uffizi-and-thin-dielectrics/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>caustics in the cornell box</title>
		<link>http://liar.bramz.net/2006/11/15/caustics-in-the-cornell-box/</link>
		<comments>http://liar.bramz.net/2006/11/15/caustics-in-the-cornell-box/#comments</comments>
		<pubDate>Wed, 15 Nov 2006 17:24:14 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2006/11/15/caustics-in-the-cornell-box/</guid>
		<description><![CDATA[It&#8217;s been more than a month since last update, so it&#8217;s time for a status report. I&#8217;ve been further playing with photon mapping and some nice shaders. The main additions to the photon mapper itself are the (ir)radiance caching when using the final gather step, and the caustics map. The former was &#8211; I believe [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been more than a month since last update, so it&#8217;s time for a status report.  I&#8217;ve been further playing with photon mapping and some nice shaders.  The main additions to the photon mapper itself are the (ir)radiance caching when using the final gather step, and the caustics map.</p>
<p>The former was &#8211; I believe &#8211; originally suggested by Per Christensen in <a href="http://www.seanet.com/~myandper/abstract/jgt99.htm">Faster Photon Map Global Illumination</a>.  The idea comes from the observation that when using final gathering, a lot of time is consumed by the radiance estimates where final gather rays hit.  When you cache these estimates at selected positions,  You can gain a factor of 5 to 10 in speed, while the error you get by using this approximation will hardly be noticeable due to the nature of the final gathering.</p>
<p>For the caustics photon map, I&#8217;ve used the technique mentioned by Keller and Wald in <a href="http://citeseer.ist.psu.edu/keller00efficient.html">Efficient Importance Sampling Techniques for the Photon Map</a>.  All photons that have gone through a specular event before hitting a diffuse surface, are stored in the caustics map.  All other photons are stored in the global photon map after being selected with a probability of 1/Q, with Q the caustics quality factor.  The Q factor is an easy way to set the resolution of the caustics map.  If you set it higher, it will contain more photons and deliver crispier caustics.  There&#8217;s still some issues with the caustics map though.  I need to add some filtering, and use the convex hull as an area estimate to get crispier caustics and prevent leaking.</p>
<p>To experiment with the caustics, I&#8217;ve added a dielectric Fresnel shader with proper reflection and refraction (see my article <a href="http://www.bramz.net/data/writings/reflection_transmission.pdf">Reflections and Refractions in Ray Tracing</a>), which is of course used for the yellow sphere.  I&#8217;ve deployed a simple medium material system (volumetric shaders), so that I could attenuate the light going through the sphere using <a href="http://en.wikipedia.org/wiki/Beer-Lambert_law">Beer&#8217;s law</a>.  The yellow colour is entirely due to this Beer medium, as the Fresnel shader is &#8230; well &#8230; colourless (greyscale).</p>
<p>For the blue sphere in the back, I&#8217;ve implemented the famous Ashikhmin &#038; Shirley BRDF (<a href="http://citeseer.ist.psu.edu/ashikhmin00anisotropic.html">An Anisotropic Phong BRDF Model</a> and <a href="http://citeseer.ist.psu.edu/ashikmin00anisotropic.html">An Anisotropic Phong Light Reflection Model</a>).  This of course has nothing to do with caustics, but it&#8217;s a very cool shader nevertheless.  Notice the slightly glossy reflection and the Fresnel behaviour at grazing angles.  I do have problems for keeping the photons at constant powers though, the specular lobe bumps power up, but I&#8217;m not really sure if it can be avoided.</p>
<p><img alt="Caustics in the Cornell box" title="Caustics in the Cornell box" src="/images/renders/examples/cornell_box/caustics_2.jpg" /></p>
<p>Where&#8217;s the road going from here?  One thing that I certainly want to add to the photon mapper is importance driven photon shooting, so that we can go crazy with sky lights and windows &#8230; The other is some priority stack for medium materials, to solve the water-in-a-glass problem (more about that later).  And while we&#8217;re at it, we should add more in- and outscattering to the medium materials so we can have fog =)  I&#8217;m also trying to put one of the <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a> cars in the Cornell box, but I seem to have some problems to smooth the mesh properly.</p>
<p>PS: we have reached <a href="http://liar.svn.sourceforge.net/viewvc/liar/trunk/liar/?pathrev=42">revision 42</a> in the subversion repository.  w00t! ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/11/15/caustics-in-the-cornell-box/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>photon mapping with the cornell box</title>
		<link>http://liar.bramz.net/2006/10/10/photon-mapping-with-the-cornell-box/</link>
		<comments>http://liar.bramz.net/2006/10/10/photon-mapping-with-the-cornell-box/#comments</comments>
		<pubDate>Tue, 10 Oct 2006 10:15:25 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2006/10/10/photon-mapping-with-the-cornell-box/</guid>
		<description><![CDATA[Summer is over (already 20 days since September 21), and as promised, we&#8217;re back with some more LiAR stuff =) I&#8217;ve been busy with a few things, the main one being the photon mapper. It&#8217;s not completed yet. Currently we only have a global photon map and a gather step with a full radiance estimate. [...]]]></description>
			<content:encoded><![CDATA[<p>Summer is over (already 20 days since September 21), and as promised, we&#8217;re back with some more LiAR stuff =)</p>
<p>I&#8217;ve been busy with a few things, the main one being the <a title="Photon Mapping on Wikipedia" href="http://en.wikipedia.org/wiki/Photon_mapping">photon mapper</a>.  It&#8217;s not completed yet.  Currently we only have a global photon map and a gather step with a full radiance estimate.  On the agenda are precomputed radiance estimates, importance driven photon shooting, caustic photon maps, &#8230;</p>
<p>The photon mapper does not use the traditional diffuse/specular/absorption Russian roulette of <a title="Global Illumination using Photon Maps (Henrik Wann Jensen, 1996)" href="http://graphics.ucsd.edu/~henrik/papers/ewr7/ewr7.html">Jensen</a>, but rather a full BSDF approach as described by <a title="Extended Photon Map Implementation (Matt Pharr, 2005)" href="http://pbrt.org/plugins/exphotonmap.pdf">Pharr</a>.  This required a complete refactoring of the shaders, which was the other big thing I was working on.</p>
<p>As you could read in an <a title="shaders or BSDFs?" href="/2006/04/18/shaders-or-bsdfs/">earlier post</a>, I was not so happy with my material implementation.  The shaders didn&#8217;t match well with things like photon mapping, so I completely ditched the shader approach for a BSDF one.  I was a bit worried about having to evaluate expensive textures for each BSDF call, so I had to find a way to buffer them.  The solution I&#8217;ve choosen is to compute many values in one call by some kind of iterator approach.</p>
<p>I guess that&#8217;s it for today.  But of course, there&#8217;s still some render to show.  OK, it&#8217;s only a dull <a title="The Cornell Box homepage" href="http://www.graphics.cornell.edu/online/box/">cornell box</a>, but it allows me to check my results more easily because I know what to expect.  Overall, it looks good, but you might notice some problems at the edges of the wall.  Apparently, the final gather doesn&#8217;t work so well over there.</p>
<p><img title="traditional cornell box rendered with photon mapping" alt="traditional cornell box rendered with photon mapping" src="/images/renders/examples/cornell_box/photon_map_1.jpg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/10/10/photon-mapping-with-the-cornell-box/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>summer break &#8230;</title>
		<link>http://liar.bramz.net/2006/06/20/summer-break/</link>
		<comments>http://liar.bramz.net/2006/06/20/summer-break/#comments</comments>
		<pubDate>Tue, 20 Jun 2006 10:44:25 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/blog/2006/06/20/summer-break/</guid>
		<description><![CDATA[Hi all, It&#8217;s been a while since the last update. We can assure you that LiAR isn&#8217;t dead, but unfortunately we have been through some busy months, and some more are coming up, which puts everything on a hold. So there probably won&#8217;t be many updates in the next couple of months either. See you [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all,</p>
<p>It&#8217;s been a while since the last update.  We can assure you that LiAR isn&#8217;t dead, but unfortunately we have been through some busy months, and some more are coming up, which puts everything on a hold.  So there probably won&#8217;t be many updates in the next couple of months either.</p>
<p>See you after the break =)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/06/20/summer-break/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>image based lighting</title>
		<link>http://liar.bramz.net/2006/04/26/image-based-lighting/</link>
		<comments>http://liar.bramz.net/2006/04/26/image-based-lighting/#comments</comments>
		<pubDate>Thu, 27 Apr 2006 00:21:53 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=26</guid>
		<description><![CDATA[My first render using an environment map as skylight &#8230; Using the technique described in Infinite Area Light Source with Importance Sampling by Pharr and Humphreys, it&#8217;s implemented in a breeze &#8230; (thanks Thomas, for pointing out that article =) (Light probe: Grace Cathedral by Paul Debevec)]]></description>
			<content:encoded><![CDATA[<p>My first render using an environment map as skylight &#8230; Using the technique described in <a href="http://pbrt.org/plugins/infinitesample.pdf">Infinite Area Light Source with Importance Sampling</a> by Pharr and Humphreys, it&#8217;s implemented in a breeze &#8230; (thanks Thomas, for pointing out that article =)</p>
<p><img alt="three differnent spheres illuminated by the grace cathedral probe (light probe by Paul Debevec)" src="/images/renders/misc/image_based_lighting.png" /></p>
<p>(Light probe: <a href="http://athens.ict.usc.edu/probes/">Grace Cathedral</a> by Paul Debevec)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/26/image-based-lighting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fixing transformations and local geometry</title>
		<link>http://liar.bramz.net/2006/04/20/fixing-transformations-and-local-geometry/</link>
		<comments>http://liar.bramz.net/2006/04/20/fixing-transformations-and-local-geometry/#comments</comments>
		<pubDate>Fri, 21 Apr 2006 00:04:25 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=25</guid>
		<description><![CDATA[Today, I noticed there was something seriously wrong with the way local differential geometry was treated by transformation objects. Basically, rendering goes like this: find intersection, find geometry of intersection, get shader at intersection, shade using the geometry. However, currently, if the object being intersected is a transformed one (by scenery::Transformation), all local geometry (3D [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I noticed there was something seriously wrong with the way local differential geometry was treated by transformation objects.  </p>
<p>Basically, rendering goes like this: find intersection, find geometry of intersection, get shader at intersection, shade using the geometry.  However, currently, if the object being intersected is a transformed one (by scenery::Transformation), all local geometry (3D point, normal, &#8230;) was transformed to global space, the top level of the transformations.  So, all shading was done in global space.  Is that bad?  Yes.  Imagine a sphere that uses a 3D texture like CheckerVolume, and this sphere moves from the left to the right.  Because the value of the texture is looked up in global space, this means that the sphere will move while the checkerboard pattern is stuck to its global position.  This is not what is wanted.  The pattern should be fixed to the object!</p>
<p>OK, seems easy to solve that: don&#8217;t transform local geometry!  Instead, when shading, transform all global information (eye rays, light rays, &#8230;) to local space.  Well, not exactly &#8230; There&#8217;s a bit of a problem to this approach: suppose you create a complex object using CSG and some transformations, then every part of that object will have its own local space.  If you apply one 3D texture to the complex object, you&#8217;ll notice that you won&#8217;t get a continuous texture: it will jump from one local space to another.</p>
<p>So, we need a combination of both.  Basically, from the observation above, we want to do the shading in the coordinate space of the (compound) object the shader was attached to (let&#8217;s call it shader space).  The untransformed sphere in the first case, the complete CSG object in the latter.  When retrieving local geometry, transform it up (towards global space) until you get to the object with the shader attached.  From there, keep track of a single transformation from shader to global space.</p>
<p>Using this approach, we get the following result.  One sphere with radius 1 is instanced three times: once without transformation, and two times scaled up by a factor 2.</p>
<ul>
<li>The middle sphere is the untransformed sphere and a shader attached with a standard CheckerVolume texture.  For this one, local space = global space = shader space.</li>
<li>The left sphere is a second instance of the middle sphere, but scaled up by a factor of two.  The shader space is still the local space of the untransformed sphere. As result the texture is scaled up together with the object. </li>
<li>The right sphere is a third instance of the same sphere, however this time, the shader is attached to the transformed sphere.  This means that the shader space = global space.  As result, the pattern has the same size of the untransformed sphere.</li>
</ul>
<p><img src="/images/renders/examples/scenery/transformation.png" alt="Transformations and shader space" /></p>
<p>script: <a href="http://svn.sourceforge.net/viewcvs.cgi/liar/trunk/liar/examples/scenery/transformation.py?view=markup">examples/scenery/transformation.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/20/fixing-transformations-and-local-geometry/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>shaders or BSDFs?</title>
		<link>http://liar.bramz.net/2006/04/18/shaders-or-bsdfs/</link>
		<comments>http://liar.bramz.net/2006/04/18/shaders-or-bsdfs/#comments</comments>
		<pubDate>Tue, 18 Apr 2006 21:51:14 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=24</guid>
		<description><![CDATA[I&#8217;m in a bit of a design dilemma right now &#8230; Currently, materials are implemented as shaders. This is similar to the RenderMan Interface. Each material is a piece of code that gets executed when the ray tracer hits the surface, and yields the outgoing radiance (the colour to be rendered). That&#8217;s great, we have [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m in a bit of a design dilemma right now &#8230; Currently, materials are implemented as shaders. This is similar to the <a href="https://renderman.pixar.com/products/rispec/index.htm">RenderMan Interface</a>.  Each material is a piece of code that gets executed when the ray tracer hits the surface, and yields the outgoing radiance (the colour to be rendered).  That&#8217;s great, we have maximum flexibility, and we keep open the possibility to be somewhat, more-or-less compatible to the RenderMan Interface.</p>
<p>Add photon mapping to the mix (or another GI thingy like path tracing, radiosity, &#8230; though radiosity might still do with the shaders above?).  Suddenly, those shaders aren&#8217;t so cute anymore.  Since photon mapping basically shoots a photon at a surface, and wants to know in what direction that photon will be scattered.  This is very BRDF oriented.  We can&#8217;t really do that with shaders, or can we? </p>
<p>So here&#8217;s the dilemma &#8230; abandon shaders, or come up with a solution that fits both?  What solution?</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/18/shaders-or-bsdfs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cornell box (direct lighting only)</title>
		<link>http://liar.bramz.net/2006/04/17/cornell-box-direct-lighting-only/</link>
		<comments>http://liar.bramz.net/2006/04/17/cornell-box-direct-lighting-only/#comments</comments>
		<pubDate>Mon, 17 Apr 2006 17:39:26 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=23</guid>
		<description><![CDATA[Today, I&#8217;ve being translating the ever-famous Cornell box to a python module. Of course, I also had to make some render, so here it is. Since I still only have direct lighting (ok ok, I really need to fix that =), the result is not so terrific. But there&#8217;s at least soft shadows ;) The [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I&#8217;ve being translating the ever-famous <a href="http://www.graphics.cornell.edu/online/box/">Cornell box</a> to a <a href="http://svn.sourceforge.net/viewcvs.cgi/liar/trunk/liar/examples/cornell_box/geometry.py?view=markup">python module</a>.  Of course, I also had to make some render, so here it is.  Since I still only have direct lighting (ok ok, I really need to fix that =), the result is not so terrific.  But there&#8217;s at least soft shadows ;)</p>
<p><img src="/images/renders/examples/cornell_box/direct_lighting.png" alt="Cornell box (direct lighting only)" /></p>
<p>The scripts are available in the <a href="http://svn.sourceforge.net/viewcvs.cgi/liar/trunk/liar/examples/cornell_box/">examples/cornell_box directory</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/17/cornell-box-direct-lighting-only/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>area lights</title>
		<link>http://liar.bramz.net/2006/04/16/area-lights/</link>
		<comments>http://liar.bramz.net/2006/04/16/area-lights/#comments</comments>
		<pubDate>Sun, 16 Apr 2006 18:51:06 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=22</guid>
		<description><![CDATA[Today, I&#8217;ve been playing a bit with area lights &#8230; They are implemented as a scene object scenery.LightArea that takes another scene object as light surface. I&#8217;m not entirely happy with it, but here&#8217;s some tests &#8230; The first one is the good ol&#8217; red sphere with a spherical area light. The entire scene is [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I&#8217;ve been playing a bit with area lights &#8230;  They are implemented as a scene object scenery.LightArea that takes another scene object as light surface.  I&#8217;m not entirely happy with it, but here&#8217;s some tests &#8230;</p>
<p>The first one is the good ol&#8217; red sphere with a spherical area light.  The entire scene is also illuminated by a blueish sky.  9 samples per pixel, 16 light samples for the sphere and 36 for the sky.</p>
<p><img src="/images/renders/examples/scenery/light_area.png" alt="area light ..." /></p>
<p>Happy Buddha under a bright white sky &#8230;  9 samples per pixel, 64 light samples</p>
<p><img src="/images/renders/misc/buddha_whitesky.png" alt="happy buddha under a white sky" /></p>
<p>The sky surface is a bit troublesome because it LiAR isn&#8217;t exactly designed to cope with points at infinity.  Currently, it&#8217;s just a giant normal sphere, but it should be examined how we can improve that.</p>
<p>We also need to be able to texture map the area lights so that we can use a nice HDR image as sky =)</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/16/area-lights/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion</title>
		<link>http://liar.bramz.net/2006/04/16/subversion/</link>
		<comments>http://liar.bramz.net/2006/04/16/subversion/#comments</comments>
		<pubDate>Sun, 16 Apr 2006 17:57:12 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=21</guid>
		<description><![CDATA[We&#8217;re glad to announce that we&#8217;ve migrated the LiAR source code from the CVS to a Subversion (SVN) repository. SVN is generally available on sourceforge since February, and by making this move, we&#8217;ll allow for more flexible code management. You can grab the latest code from the repository by the following command: svn co https://svn.sourceforge.net/svnroot/liar/trunk/liar/ [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re glad to announce that we&#8217;ve migrated the LiAR source code from the CVS to a <a href="http://subversion.tigris.org/">Subversion (SVN)</a> repository.  SVN is generally available on sourceforge since February, and by making this move, we&#8217;ll allow for more flexible code management.</p>
<p>You can grab the latest code from the repository by the following command:<br />
<code>svn co https://svn.sourceforge.net/svnroot/liar/trunk/liar/</code></p>
<p>The repository is also <a href="http://liar.svn.sourceforge.net/viewcvs.cgi/liar/trunk/liar/">browsable</a>.  More info can be found on the <a href="http://sourceforge.net/svn/?group_id=123027">project page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/04/16/subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RenderTarget with PixelToaster</title>
		<link>http://liar.bramz.net/2006/03/13/rendertarget-with-pixeltoaster/</link>
		<comments>http://liar.bramz.net/2006/03/13/rendertarget-with-pixeltoaster/#comments</comments>
		<pubDate>Tue, 14 Mar 2006 00:41:16 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=20</guid>
		<description><![CDATA[I&#8217;ve just implemented a RenderTarget called Display which shows the image on screen while being rendered. I&#8217;ve used the almighty PixelToaster to accomplish this, which turned out to be pretty easy. Here&#8217;s the recurring red sphere on a blue checkerboard plane being rendered in a window: One lesson learned: you should never update a PixelToaster [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just implemented a RenderTarget called Display which shows the image on screen while being rendered.  I&#8217;ve used the almighty <a href="http://pixeltoaster.com/">PixelToaster</a> to accomplish this, which turned out to be pretty easy.  Here&#8217;s the recurring red sphere on a blue checkerboard plane being rendered in a window:</p>
<p><img src="/images/renders/examples/output/display.png" alt="Scene rendered to Display RenderTarget (using PixelToaster)" /></p>
<p>One lesson learned: you should never update a PixelToaster display in another thread than in the one you&#8217;ve opened it.  Upon the first call of update(), somewhere deep inside the function, there&#8217;s a call to the Win32 ShowWindow function (the window still is hidden when you open it).  However, that call will block when it&#8217;s called from a different thread than the one to create the window &#8230;</p>
<p>Things to do: currently, the window closes the moment the render is finished &#8230; We&#8217;ll need the &#8220;press any key&#8221; feature!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/03/13/rendertarget-with-pixeltoaster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>blender export!</title>
		<link>http://liar.bramz.net/2006/02/18/blender-export/</link>
		<comments>http://liar.bramz.net/2006/02/18/blender-export/#comments</comments>
		<pubDate>Sat, 18 Feb 2006 19:01:03 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=19</guid>
		<description><![CDATA[It&#8217;s been a while since my last update. Two months to be exact. What have I been doing in that time? Not that much &#8230; I&#8217;ve been struggling with lights &#8230; How do lights fit in the grand design of a ray tracer? Are they objects? Are they shaders? Or even something completely different? I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since my last update.  Two months to be exact.  What have I been doing in that time?  Not that much &#8230; I&#8217;ve been struggling with lights &#8230; How do lights fit in the grand design of a ray tracer?  Are they objects?  Are they shaders?  Or even something completely different?  I&#8217;ve settled with the first option: lights are objects.  I don&#8217;t know if that&#8217;s the best decision, but you have to make one to get on, don&#8217;t you?  Anyway, that&#8217;s not the subject of this post.  I&#8217;ve also been working on a script to export scenes in Blender to a LiAR script.</p>
<p>You can&#8217;t continue crafting your scenes in raw Python code forever.  One day, you want to use a real modeling program.  And what program better suits this need than <a href="http://www.blender.org/">Blender</a>?  First of all, it&#8217;s free and open source.  But secondly (and perhaps more interesting for LiAR), it has an embedded Python environment.  So, we can write our export script in pure Python, which is of course great.  </p>
<p>It takes a while to get the hang of their Python API, but once you get the feeling, it&#8217;s fairly easy.  And so here&#8217;s the first result.  I&#8217;ve managed to export the default scene (the one you get when you start Blender) to a LiAR script, and to actually render it.  It&#8217;s not exactly spectacular (it&#8217;s rather dull even), but it works.  A lot of features are still missing, but that&#8217;s not so important.  The important thing is that the export works.  Here it is (model courtesy blender.org =) &#8230;</p>
<p>I can&#8217;t link to the code, because it&#8217;s not in the CVS yet, but when it is commited, you&#8217;ll find it in extras/blender_scripts/liar_export.py</p>
<p><img src="/images/renders/misc/blender_to_liar.png" alt="default scene of Blender rendered by LiAR isn't a raytracer ..." /></p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2006/02/18/blender-export/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHD-Motorsports FZR</title>
		<link>http://liar.bramz.net/2005/12/15/phd-motorsports-fzr/</link>
		<comments>http://liar.bramz.net/2005/12/15/phd-motorsports-fzr/#comments</comments>
		<pubDate>Thu, 15 Dec 2005 10:18:44 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=18</guid>
		<description><![CDATA[A render of the new PHD-Motosports skin for the FZR. Wimz is doing an amazing job on those skins. There&#8217;s a nice detail you can&#8217;t see from this point of view: the driver&#8217;s name with a little Belgian flag. Great! The cars are rendered with depth of field for a more realistic image &#8230; Model [...]]]></description>
			<content:encoded><![CDATA[<p>A render of the new <a href="http://www.phd-motorsports.com/">PHD-Motosports</a> skin for the FZR.  Wimz is doing an amazing job on those skins.  There&#8217;s a nice detail you can&#8217;t see from this point of view: the driver&#8217;s name with a little Belgian flag.  Great!</p>
<p>The cars are rendered with depth of field for a more realistic image &#8230;</p>
<p><img src="/images/renders/phdmotorsports/fzr.jpg" alt="FZR with new skin and DOF.  Model by liveforspeed.com, skin by phd-motorsports.com" /></p>
<p>Model by <a href="http://http://www.liveforspeed.net">Live for Speed</a>, custom skin by <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2005/12/15/phd-motorsports-fzr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>depth of field</title>
		<link>http://liar.bramz.net/2005/12/04/depth-of-field/</link>
		<comments>http://liar.bramz.net/2005/12/04/depth-of-field/#comments</comments>
		<pubDate>Sun, 04 Dec 2005 18:14:48 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=17</guid>
		<description><![CDATA[Some time ago, I mentioned I was implementing depth of field in LiAR. Well, I finally managed to code and test it. The following image illustrates the depth of field effect. The left part is rendered by a pinhole camera, the right part by a camera with a circular lens. You can find the script [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://liar.bramz.net/2005/11/15/triangle-meshes-ok-but-still-slow/">Some time ago</a>, I mentioned I was implementing depth of field in LiAR.  Well, I finally managed to code and test it.  The following image illustrates the depth of field effect.  The left part is rendered by a pinhole camera, the right part by a camera with a circular lens.    You can find the script on the CVS: examples/cameras/depth_of_field.py</p>
<p><img src="/images/renders/examples/cameras/depth_of_field.jpg" alt="illustration of depth of field on a grid of spheres.  render script: examples/cameras/depth_of_field.py" /></p>
<p> Adding depth of field to a ray tracer is rather easy once you&#8217;re familiar to the concepts of <a href="http://en.wikipedia.org/wiki/Distributed_ray_tracing">distributed ray tracing</a> (which isn&#8217;t too hard either). First, you generate a primary ray as usual and you determine it&#8217;s intersection with the focal plane.  This is a (virtual) plane orthogonal to the camera direction and al points on this plane will be in focus.  Then you generate a new origin of the primary ray.  This is done by picking a random point on the camera &#8220;lens&#8221;, which is a disk orthogonal to the camera direction and with the camera position as center.  The best way to do this is by generating stratified <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/84042557057fa93bdab4ef5b800af98d_3.5pt.gif' title='\left(u,v\right)' alt='\left(u,v\right)'  style="vertical-align:-3.5pt;"  /> samples in the range <img class='latexrender' src='/wp-content/plugins/latexrender/pictures/8c5b55ab73c77e41fb9e2c4077307461_3.5pt.gif' title='\left[0,1\right]\times\left[0,1\right]' alt='\left[0,1\right]\times\left[0,1\right]'  style="vertical-align:-3.5pt;"  /> and to transform them to a disk (Peter Shirley has written a <a href="http://www.acm.org/jgt/papers/ShirleyChiu97/">paper</a> on how exactly to do this). Finally, you generate the new ray direction from the point on the lens to the intersection on the focal plane.  This makes sure everything on the focal plane is indeed in focus.  Voila, that&#8217;s it!</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2005/12/04/depth-of-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>renders of LX6</title>
		<link>http://liar.bramz.net/2005/12/03/renders-of-lx6/</link>
		<comments>http://liar.bramz.net/2005/12/03/renders-of-lx6/#comments</comments>
		<pubDate>Sat, 03 Dec 2005 21:33:35 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[bramz' diary]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=16</guid>
		<description><![CDATA[This week, I&#8217;ve been mostly rendering &#8230; cars. It&#8217;s been a while since my last update. I&#8217;ve been rendering cars for PHD-Motorsports. The setup is rather simple. The same triangle mesh is instantiated three times with a different skin. There are three point lights: a pure white key light in the front left corner, a [...]]]></description>
			<content:encoded><![CDATA[<p>This week, I&#8217;ve been mostly rendering &#8230; cars.</p>
<p><img src="/images/renders/phdmotorsports/lx6_front.jpg" alt="Front view of the LX6 cars with team skin.  Model courtesy " /></p>
<p>It&#8217;s been a while since my last update.  I&#8217;ve been rendering cars for <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a>.  The setup is rather simple.  The same triangle mesh is instantiated three times with a different skin.  There are three point lights: a pure white key light in the front left corner, a blueish fill light in the front right corner, and as last a blueish back light.</p>
<p><img src="/images/renders/phdmotorsports/lx6_side_motion.jpg" alt="side view with motion blur" /></p>
<p>Of course, we also had to render some &#8220;action&#8221;, so we added a bit of <a href="http://liar.bramz.net/2005/11/16/motionblur/">motion blur</a> to the side view of the cars.  A checker board is added a floor to have a fixed object as reference.</p>
<p>Model and skin by <a href="http://www.liveforspeed.net/">Live for Speed</a> and <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2005/12/03/renders-of-lx6/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>LiAR sponsors PHD-Motorsports team</title>
		<link>http://liar.bramz.net/2005/11/22/liar-sponsors-phd-motorsports-team/</link>
		<comments>http://liar.bramz.net/2005/11/22/liar-sponsors-phd-motorsports-team/#comments</comments>
		<pubDate>Tue, 22 Nov 2005 18:36:21 +0000</pubDate>
		<dc:creator>bramz</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://liar.sourceforge.net/?p=15</guid>
		<description><![CDATA[LiAR isn&#8217;t a raytracer is pleased to announce that it has become the official sponsor of PHD-Motorsports, the Ghent-based racing team owned by Victor De Muer. The team is currently competing in the VRL Live For Speed WinterTrophy 2005. Last week, LiAR CEO Bram de Greve was contacted by De Muer in search of funds [...]]]></description>
			<content:encoded><![CDATA[<p><i>LiAR isn&#8217;t a raytracer</i> is pleased to announce that it has become the official sponsor of <a href="http://www.phd-motorsports.com/">PHD-Motorsports</a>, the Ghent-based racing team owned by Victor De Muer.  The team is currently competing in the VRL Live For Speed WinterTrophy 2005.</p>
<p>Last week, LiAR CEO Bram de Greve was contacted by De Muer in search of funds for his team.  Both bosses agreed that LiAR will commit to a long-term financial backing of PHD-Motorsports.  In return, the corporate logo will be prominently displayed on the team&#8217;s racing cars starting from the next championship race on December 4, 2005 in Blackwood.</p>
<p>&#8220;It&#8217;s a great opportunity for us&#8221;, de Greve said.  &#8220;We&#8217;ll be able to showcase our technology that naturally fits the fast cars of PHD-Motorsports.  And I also know team member Tom De Muer from his work on LASS, so I have great confidence in their performance.&#8221;</p>
<p>Stay tuned for renders of the team&#8217;s racing cars.  Meanwhile, be sure to check out the team news on their homepage <a href="http://www.phd-motorsports.com/">www.phd-motorsports.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://liar.bramz.net/2005/11/22/liar-sponsors-phd-motorsports-team/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->