XRT is a raytracing based programmable rendering system for photo-realistic image synthesis built around a plug-in architecture design.


XRT 1.0.3 released

Posted: 28 Aug 2010 13:26
Tags: downloads implicit surface


XRT 1.0.3 exports a new Shape API call that loads a shape plugin at run-time. This way, the renderer can be extended to handle new primitives without changing the core. Actually, all primitives in XRT are implemented this way: the many primitives calls provided by the API are just convenient shortcuts using Shape.

As an example, I have implemented an implicit surface plugin (an implicit surface is the set of points that obeys to the equation $f(x,y,z) =$0 where $f$ can be any arithmetic expression). The thumbnail on the left is a rendering of such a surface1. The next post will fully document this primitive.

This release also fixes the flawed implementation of LookAt introduced in the 1.0.1 release. It was not working correctly with multiple cameras. All the generators that make use of this call have been updated, including the Structure Synth exporter.

The Reference Guide, along with a few layout changes, documents the Shape call and explains how to properly use LooKAt.

The goods are available in the Downloads section.

Comments: 0, Rating: 0

XRT 1.0.2 released

Posted: 22 Jul 2010 14:16
Tags: downloads luxrender ply


XRT 1.0.2 features a new generator plugin for PLY files loading. It is based on the RPly library from Diego Nehab (available here).

To stress the generator, I have hand translated some test scenes from LuxRays1 to Pyg. I have also updated XRT Python binding to enable object instancing within Pyg and redesigned a bit area lights to use geometry sets.

PLY geometry import works flawlessly but, given that XRT has no support for global illumination, the result is sometimes not convincing. Surface shaders could also be improved. Nevertheless, a few preliminary pictures are available here.

As usual, this new release along with the updated documentation is available in the Downloads section.

Comments: 0, Rating: 0

XRT 1.0.1 released

Posted: 07 Jul 2010 21:17
Tags: downloads gallery structure_synth


Structure Synth is a tool for generating 3D structures by specifying a design grammar (something akin to L-systems: a script with rewriting rules). Using simple rule sets, you can create very complex objects which looks like futuristic buildings, organic structures or abstract sculptures. It features a flexible template based export system for integration with third-party renderers. I believe this capability combined with SunFlow stunning renderings contributed a lot to its fame.

Of course, I could not resist writing a similar export template for XRT. It exports Structure Synth camera settings and shades the geometry with an ambient occlusion shader. To ease the process, I have added a Python binding for XRT LookAt API call bumping XRT version to 1.0.1.

This new release along with the exporter, the shader and the updated documentation is available in the Downloads section.

A new section of the gallery dedicated to Structure Synth is now available here.

Comments: 0, Rating: 0

What's next?

Posted: 28 Jun 2010 16:55
Tags: roadmap

Here is what I plan to do for version 2.0.

The most important added features will be:

  • Catmull-Clark subdivision surfaces
  • multi-threaded rendering
  • OpenImageIO library integration
  • deformation blur
  • occlusion cache for faster ambient occlusion
  • color bleeding (and of course irradiance caching)

I also want to add lesser (in terms of development effort but nevertheless useful) features:

  • primitive variables
  • imagers
  • file format support: PLY, OBJ
  • shader message passing
  • shadeops
  • geometry sets
  • shadow bias support
  • nurbs curves
  • Python bindings for XRT extensions to Gelato
  • any other fancy stuff that allows me to render a nice picture

The third major topic will target optimisation:

  • run a profiler to identify architectural and implementation bottlenecks
  • review existing acceleration structures and possibly implement new ones (sbvh, bih, qbvh)

My ultimate goal for this release is to able to render scenes exported from Blender by Eric Back's MOSAIC.

I guess it's probably going to take me 18 to 24 months to complete all these tasks but most of them are really incremental changes. Now that packaging the software and the documentation is a lot quicker, I intend to issue releases much more frequently (when I complete new features).

Comments: 0, Rating: 0

XRT 1.0.0 released!

Posted: 07 Jun 2010 17:28
Tags: downloads

After months of exhaustive testing, the first release of the XRT renderer is finally available for public consumption here. Despite the time spent, there are a few bugs remaining and important features like subdivision surfaces or global illumination are still missing. Therefore, you should not probably rely on it for mission critical duties.

However, the gallery is large enough to testify that you can already do a lot with XRT. If you render something nice with it, drop me a message on the Forum. If you have troubles, find something that does not work as expected (the Overview page should give you a good idea of XRT current feature set) or want to ask a question, the Forum is also the place to go.

Hope you will enjoy it!

Comments: 0, Rating: 0

The RenderMan Companion

Posted: 23 Mar 2010 22:59
Tags: arman gallery rc rfb


Since the beginning of the year, I have entered a fairly intensive bug-fixing phase: pick a set of scenes, compute reference renderings, compare the results with XRT output and hack the code until it gets right. Lather, rince, repeat …

This is rather tedious and will probably last a few more months but I am making good progress. Of course, because there are features that I have not yet implemented, some scenes cannot look right but I have decided to halt any further development until I am confident that the current code base is solid enough.

Less bugs means also more new pictures for the galllery. Their number has steadily increased and is now over 200.

I am just done with the examples of the RenderMan Companion. This is a fairly old book (1989), so old that, at the time of its writing, the RIB file format was not yet defined and all examples were provided as C programs. These are good test cases for XRT RIB client library.

Although RenderMan Companion image content cannot really be considered any longer as cutting edge (its follow-ups, Advanced RenderMan or Renderings for Beginners, are a bit more challenging), you will find some nice pictures here.

Comments: 0, Rating: 0

Constructive Solid Geometry

Posted: 20 Feb 2010 12:35
Tags: csg


The most widely known algorithms for rendering constructive solid geometry (CSG) require finding all intersections of a line with a primitive and then computing the intersections by examining the intervals. This is clearly inefficient because you need to store and compute all the intersections for all the sub-objects of the CSG tree. Not only you don't really need to know all intersections to find the nearest one but the storage/deletion of many hits within a rendering loop is a real performance killer. Another issue is that you must rewrite all your primitive intersection routines to support CSG which increases the code bloat.

Therefore, CSG support within XRT is based on a different algorithm described in a short paper from Andrew Kensler: Ray Tracing CSG Objects Using Single Hit Intersections. This paper is no longer available on the web but you can find a local copy here.

As the author states in his introduction:

"The [algorithm] computes intersections with binary CSG objects using the [nearest] intersection. Though it may need to do several of these per sub-object, the usual number needed is quite low. The only limitation of this algorithm is that the sub-objects must be closed, non-self-intersecting and have consistently oriented normals."1

Algorithm outline

A ray is shot at each sub-object to find the nearest intersection, then the intersection with the sub-object is classified as one of entering, exiting or missing it. Based upon the combination of the two classifications, one of several actions is taken:

  • returning a hit
  • returning a miss
  • changing the starting point of the ray for one of the objects and then shooting this ray, classifying the intersection. In this case, the state machine enters a new loop.

The paper finally describes the state machine and the 3 different state tables (one for each CSG operation Union, Intersection and Difference) needed to raytrace a CSG tree. This a very neat idea expressed clearly and concisely: the paper is 3 pages long, 2/3 of it made of diagrams, state tables and pseudo code ready to be translated into C++. A real programmer's heaven.

But it doesn't work.

The state table for Union is OK but the state tables for Intersection and Difference are not. Even with very simple cases, when you run the routine with pen and paper, it fails. The good news are that it can be fixed with a few minor changes:

  • create two other actions
  • change the result of one combination in the Difference and Intersection tables
  • update the state machine

My changes are given below in bold.

List of actions

ReturnMiss Exit, reporting no intersection
ReturnAIfCloser Return the intersection with A if it is closer
ReturnAIfFarther Return the intersection with A if it is farther
ReturnA Always return the intersection with A
ReturnBIfCloser Return the intersection with B if it is closer
ReturnBIfFarther Return the intersection with B if it is farther
ReturnB Always return the intersection with B
FlipB If returning an intersection with B, flip its normal
AdvanceAAndLoop Continue with the next intersection with A
AdvanceBAndLoop Continue with the next intersection with B
AdvanceAAndLoopIfCloser Continue with the next intersection with A if the current intersection with A is closer
AdvanceBAndLoopIfCloser Continue with the next intersection with B if the current intersection with B is closer

Action tables

Union Enter B Exit B Miss B
Enter A ReturnAIfCloser, ReturnBIfCloser ReturnBIfCloser, AdvanceAAndLoop ReturnA
Exit A ReturnAIfCloser, AdvanceBAndLoop ReturnAIfFarther, ReturnBIfFarther ReturnA
Miss A ReturnB ReturnB ReturnMiss
Difference Enter B Exit B Miss B
Enter A ReturnAIfCloser, AdvanceBAndLoop AdvanceAAndLoopIfCloser, AdvanceBAndLoopIfCloser ReturnA
Exit A ReturnAIfCloser, ReturnBIfCloser, FlipB ReturnBIfCloser, FlipB, AdvanceAAndLoop ReturnA
Miss A ReturnMiss ReturnMiss ReturnMiss
Intersection Enter B Exit B Miss B
Enter A AdvanceAAndLoopIfCloser, AdvanceBAndLoopIfCloser ReturnAIfCloser, AdvanceBAndLoop ReturnMiss
Exit A ReturnBIfCloser, AdvanceAAndLoop ReturnAIfCloser, ReturnBIfCloser ReturnMiss
Miss A ReturnMiss ReturnMiss ReturnMiss

State machine pseudo-code

The algorithm is slightly modified to take into account the new actions. Please note that minA and minB must not be initialized to 0.

minA = minB = min // current nearest intersection
( tA, NA ) = IntersectWithA( O, D, minA )
( tB, NB ) = IntersectWithB( O, D, minB )
stateA = ClassifyEnterExitOrMiss( tA, NA )
stateB = ClassifyEnterExitOrMiss( tB, NB )
  action = table [stateA, stateB]
  if ReturnMiss ∈ action then
    return miss
  else if ReturnA ∈ action 
    or ( ReturnAIfCloser ∈ action and tA <= tB ) 
    or ( ReturnAIfFarther ∈ action and tA > tB ) then
    return tA, NA
  else if ReturnB ∈ action 
    or ( ReturnBIfCloser ∈ action and tB <= tA ) 
    or ( ReturnBIfFarther ∈ action and tB > tA ) then
    if FlipB ∈ action then
      NB = −NB
    end if
    return tB, NB
  else if AdvanceAAndLoop ∈ action 
    or ( AdvanceAAndLoopIfCloser ∈ action and tA <= tB ) then
    minA = tA
    ( tA, NA ) = IntersectWithA( O, D, minA )
    stateA = ClassifyEnterExitOrMiss( tA, NA )
  else if AdvanceBAndLoop ∈ action 
    or ( AdvanceBAndLoopIfCloser ∈ action and tB <= tA ) then
    minB = tB
    ( tB, NB ) = IntersectWithB( O, D, minB )
    stateB = ClassifyEnterExitOrMiss( tB, NB )
  end if
end loop

You will find some examples of this feature in the gallery

Comments: 0, Rating: 0

Ambient occlusion

Posted: 22 Jan 2010 22:40
Tags: ambient occlusion


Ambient occlusion measures how much of the hemisphere above each surface point is occluded by other objects in the scene. It is computed by tracing rays randomly distributed around the hemisphere above each shaded point. In the example picture, the shader colors pixels white if they have a completely unoccluded view of the hemisphere, and black if the view of the hemisphere is completely occluded: the result looks a bit washed out similar to the way an object would appear on an overcast day.
Because it takes into account other objects for lighting computations, it pretends to be a global illumination solution but is not physically based. Anyway, this is a much better solution for computing the ambient term compared to adding the usual constant to the rendering equation. The only drawback is that you need to fire lots of ray per pixel to get rid of the noise (random distribution of rays = noise).
Implementing ambient occlusion is as simple as its definition: if you already have shadow rays in your renderer, it takes a mere 20 lines of code.
Despite its simplicity, it gives surprisingly convincing results. Therefore, it is part of the toolbox of all major CGI studios: Pixar, DreamWorks, Sony Pictures and the likes. You will find more examples of this feature in the gallery (look here)

Comments: 0, Rating: 0

OSL is out

Posted: 16 Jan 2010 18:12
Tags: compiler langage osl shading


Quoting Sony Pictures Imageworks Open Source Software site: «Open Shading Language (OSL) is a small but rich language for programmable shading in advanced renderers and other applications. OSL is similar to C, as well as other shading languages; however, it is specifically designed for advanced rendering algorithms with features such as radiance closures, BRDFs, and deferred ray tracing as first-class concepts.

The OSL project includes a complete language specification, a compiler from OSL to an intermediate assembly-like bytecode, an interpreter that executes OSL shaders on collections of points in a SIMD manner, and extensive standard shader function library.»

Although the project is not yet production-ready, browsing the source code is very instructive: aside from the fact that the project is a very good demonstration of how to design a langage compiler and byte code interpreter, it features things that I never seen before: automatic differentiation of expressions, symbolic computing. These features allow a raytracer to compute derivatives in a very efficient manner (no need to evaluate three times a shader like BMRT did in its time, once is enough) or to perform fast relighting (running a shader does not return a color but a symbolic expression that can be stored and evaluated later against a different set of light sources). There are many other aspects of OSL that are well thought out and will favor the implementation of global illumination renderers.

For all these reasons, OSL looks like a very worthwhile component to add to the XRT renderer. However, the langage specification is not yet complete and there is currently no way to define the equivalent of RenderMan shading langage "illuminance loops" (except by wiring them into the renderer). This is a long term goal for the project but is not due soon. The roadmap will probably be detailed in the forthcoming months.

One thing I am contemplating is that, given that RSL and OSL already share a lot (keywords, types, function library), it should be possible to transform the OSL compiler into a RSL one without too much hassle. This would allow me to reuse most of OSL.

Comments: 0, Rating: 0

Motion blur (the end?)

Posted: 19 Dec 2009 17:19
Tags: blur motion transformation


After a long struggle with my laziness, I finally found the energy to complete (sort of) motion blur. I have left deformation blur and attributes blur (see here for an explanation of these terms) aside for the moment and focused on transformation blur.

It turned out that my first implementation was at the same time partly buggy and awfully slow. To take motion into account, I was enlarging any affected primitive bounding box before inserting them into my acceleration structure. It was therefore no big surprise that it was really inefficient. A(nother) complete overhaul was needed. Pfff …

Back to the drawing board, I figured out that, usually, motion is applied to a group of static primitives for which an efficient acceleration structure can be computed. Therefore, I have redesigned the scene parser to output a hierarchy of acceleration structures (aggregate) instead of a single one. Motion blur is applied only at the aggregate level. Underneath, everything has tight and efficient bounding boxes. As a result, I got a 60x speedup compared to my first naive implementation and it also cured magically my bugs!

I have added a page in the gallery to demonstrate these new features.

Comments: 0, Rating: 0

Motion blur again

Posted: 15 Sep 2009 21:26
Tags: blur motion transformation

I am finally done with a first implementation of transformation motion blur (for some examples, go here). As expected, extensive changes to transformation and intersection routines were needed. However, this is not the end of it. Let me explain why in a few words.

Motion blurred transformations are created by giving a sequence of transformations at different times and can be concatenated and nested hierarchically. The number of time samples may be different for each transformation. When a ray is fired, it is given a random time. When a primitive is tested for intersection by a ray, this time is used to retreive the corresponding motion segment and to interpolate the current transformation between the two ends of the segment.

Right now, I am using linear interpolation between transformations. This works well for scales, translations and small rotations but is obviously wrong for large rotations. It's just an faster path to get a feel on motion blur. I know there is a much better solution: quaternions and spherical interpolation. This will be the next step.

Comments: 0, Rating: 0

Gelato gallery updated

Posted: 13 Sep 2009 16:08
Tags: gallery gelato

I have added new examples and updated some others because they really benefited from the last features I have implemented: improved sampling and blurred shadows. I have also completely changed the gallery layout to display full resolution pictures. It's less straightforward than to use Wikidot builtin gallery but one cannot see anything worthwhile on a confetti. Have a look here.

Comments: 0, Rating: 0

Improved sampling

Posted: 08 Sep 2009 22:26
Tags: pbrt sampler stratified

If you are serious about raytracing, give yourself a favor and buy Physically Based Rendering from Matt Pharr & Malcolm Humphreys. It's huge, it's thick, it weighs a ton and will not fit in your pocket but this is definitely the reference book on the subject. Because I felt bad sampling was possibly responsible for my noisy motion blur images (see my previous post), I have opened it once again and reread chapter 7 which deals with sampling and reconstruction (by the way, this chapter is available for downloading here). This led me to conclude it was time to ditch the current "uniform" sampler and to add a brand new sampler plugin: the "stratified jittered" sampler. It was quite straightforward to adapt PBRT implementation to XRT.

The result is worth the try.

Camera motion blur
Image Unavailable
rendered with uniform sampling

Camera motion blur
Image Unavailable
rendered with stratified sampling

This is still not as good as the 3Delight reference image but a lot closer to it. The PBRT book describes other samplers:"low discrepancy" and "best candidate" which should give even better results.

Comments: 0, Rating: 0

Motion blur: first steps

Posted: 01 Sep 2009 22:20
Tags: 3delight blur motion

I am currently adding motion blur support to XRT.

Actually, motion blur designates four different features:

  • camera motion blur, where blur occurs when the camera moves
  • transformation motion blur, where blur occurs when the transformation attached to a scene object changes
  • deformation blur, where the actual object geometry changes
  • attributes blur, where the surface properties of objects changes over time

Camera motion blur is the easiest to implement because it affects only the camera world transformation and therefore does not require extensive changes. Here is a first rendering. The camera turns from right to left while aiming a green matte sphere. I am not completely happy with the result because it is way too noisy. The same scene rendered with 3Delight is a lot smoother.

Camera motion blur
Image Unavailable
rendered with XRT

Camera motion blur
Image Unavailable
rendered with 3Delight

A possible explanation for this noise is that XRT sampling strategy is a bit crude: a regular grid is used with no jitter. I'll try smarter schemes in the future.

Comments: 0, Rating: 0

More Wikidot lore

Posted: 30 Jul 2009 12:32
Tags: website

  • added autonumbering to posts not to worry any more about page names
  • renamed existing posts to fit with autonumbering
  • updated blog template and main page to improve tags display
  • changed the CSS theme of the blog to a fixed width to get a more consistent page layout across different screen sizes
  • slightly updated the layout of some of my previous posts (bigger pictures with a nice border)

Comments: 0, Rating: 0

New RenderMan repository gallery

Posted: 22 Jul 2009 14:06
Tags: gallery rmr shader

I have started a new gallery with examples from the RenderMan repository. This is a very good demonstration of the power of programmable shading. Most of these examples feature very simplistic geometrical content (just one sphere or one square): the real image content comes from the shaders.

Comments: 0, Rating: 0

Hairy monster

Posted: 10 Jul 2009 08:12
Tags: fur gallery gelato

There is a new creature in the Gelato gallery that demonstrates XRT fur rendering capabilities. Frightening, isn't it ?


The rendering times are frightening too (more than 10 hours on my PC). Because the fur is made of tiny little curves, sampling has been set to 6x6 subsamples. Otherwise, aliasing starts to appear as tiny holes in the individual hairs. The other issue that explains long rendering times is the fact that, in a given volume, there are lots of primitives. The BVH acceleration structure that I am using is obviously having a hard time choosing a sufficiently small set of candidates for intersection testing. This is a problem that I have already noticed while benchmarking with other simpler scenes but for which I haven't yet found a solution (improved implementation or better algorithm ?).

Comments: 0, Rating: 0

New Rendering for Beginners shader gallery

Posted: 06 Jul 2009 20:46
Tags: gallery rfb shader

I have built a shader gallery with examples from the Rendering for Beginners book

Comments: 0, Rating: 0

Improving the gallery (part 3)

Posted: 02 Jul 2009 21:36
Tags: arman gallery


The Advanced RenderMan gallery is now up to date.

Comments: 0, Rating: 0

New AIR gallery

Posted: 01 Jul 2009 20:34
Tags: air gallery nurbs

I have fixed a nasty bug on rational NURBS surface evaluation which paves the way for more cool pictures.

I have started a new gallery based on AIR examples. Have a look here!

Comments: 0, Rating: 0