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


XRT 2.2.0 released

Posted: 06 Nov 2013 20:34
Tags: downloads

Image Unavailable
scene from Mathias Baas

Of course, the major feature in this release is blobby rendering. The subject has already been discussed at great length in the two previous posts and I will not say more, apart from the fact that blobbies have now a dedicated page into the gallery. But there are some other interesting features worth mentioning.

Primitive variables

In the RenderMan terminology, a "primitive variable" ("primvar" for short) is a mechanism that allows you to attach arbitrary data (variables) to objects (primitives). These values are interpolated or not (depending on their interpolation type) and passed from the object to its shader at render time. By overwriting shader parameters, they modify the way a geometric primitive is shaded. A single shader instance may then be reused for a myriad of objects. I finally implemented support for them in all XRT primitives (except for subdivision surfaces).

Some finishing touches to the RenderMan client

Apart from blobby support and a few bugs fixes, binary output is now implemented.

More examples

Blobby rendering ribs and some Python scripts using the new Python binding for RenderMan API are now available in the examples archive.

Comments: 0, Rating: 0

The blob returns !!

Posted: 04 Nov 2013 17:40
Tags: blobby

Actually, there is much more to blobs than adding mere spheres. XRT implementation supports various operations and field functions.


A max operation is roughly equivalent to a union operation in CSG whereas the min operation is like an intersection. Max is used most of the time to prevent blending between shapes. In the following pictures, a hand is modelled from several blobby ellipsoids, first with no blending at all, then with all shapes blended together, then with blending selectively disabled between fingers. For each of the four fingers, the blobs describing it are added together, along with the adjacent blobs at the edge of the palm. A separate added-together group is made of all the palm blobs. The whole field function is just the max of these five overlapping blending groups.


Another useful operation is sub, which substracts one field from another. As illustrated in the following picture, depending on the strength of the field, we can either put a dent in it (left topmost shape) or dig a hole through it (right topmost shape). The bottom row is the max of two fields to help visualizing them.


There are three other supported operations: mul (multiply fields), neg (negate a field) and div (divide two fields) but I have not yet found any meaningful usage of these. Therefore, I'll skip them.

Field functions

XRT implements field functions as plugins. Let me present you some of them.



A capsule field function is the distance field built from a line segment (ideally suited for sausage or spaghetti like shapes). Note how the shapes smoothly blend when their respective line segments are abutting (whether they share the same orientation or not). Actually, if you subdivide a capsule into a sum of shorter capsules, the resulting field is exactly the same as the single capsule.

Here are more spaghettis (the sum of 480 capsules in a toroidal spiral)




A cube field function defines a cube centered at the origin. Pretty lame, isn't it ? Things get more interesting when the cube is combined with other shapes.



A plane field fuction defines a unit square in the xy-plane, at z=0, centered at the origin.



Comments: 0, Rating: 0

The blob is coming !!

Posted: 19 Sep 2013 19:30
Tags: blobby


… in next XRT version.


Blobby objects belong to the family of implicit surfaces. That is, instead of being specified explicitely with an array of points like a polygon mesh or a subdivision surface, a blobby surface is defined by a field function $f(x,y,z)$ that is equal to a threshold value at every point on the surface.

A well-known implicit surface is the sphere with center at the origin and radius r, which is $x^2+y^2+z^2=r^2$. You can find many more examples of implicit surfaces here. XRT algorithm for rendering generic implicit surfaces has been detailed in a previous post. Most of the implicit surfaces have an infinite domain (the range of values that $f(x,y,z)$ can take) and combining them does not lead to anything interesting (for example, if we add two sphere implicit surfaces with two different centers, the resulting surface is a void because, at every point in space, the combined implicit function value will likely be superior to the threshold value)

We can get much more interesting effects when using bump functions. A bump function is smooth (its derivatives are continuous at all orders) and has compact support (in broad terms, the part of the (x,y,z) space where $f(x,y,z)$ is not 0 is a box).


In the above example, two such fields are added and their centers are made closer and closer until they seem to swallow each other. What happens? Things get much clearer when we draw the iso-potentials (Image credits).

Image Unavailable
Disjoint supports

Image Unavailable
Overlapping supports

When supports overlap, potentials sum, hence the resulting shape.

A blobby object is a combination of elementary bump functions (which define primitive fields like spheres, segments, boxes … ) through a hierarchy of operations on them (add, sub, div, mul, neg, min, max) resulting in all kinds of rounded objects.

Intersection algorithm

As usual, I have looked at what my glorious predecessors have done but I have not found much. Regarding open source implementations, the most comprehensive is Aqsis's one: blobbies are tesselated into polygon meshes using J. Bloomenthal's implicit surface polygonizer [1]. Because I am a bit prejudiced against tesselation (mostly because there is always a trade-off between accuracy and memory space), I prefer direct algorithms. Unfortunately, the litterature on that subject is quite scarce. Worse, every algorithm seems have restrictions either on the shapes or on the supported operations (usually blending), like for instance [3] (that certainly does not imply I think this is a bad work).

Therefore, a fresh look at the problem was needed. Here is my small contribution.

Because a blobby is an implicit surface, the interval-based bisection algorithm used to raytrace implicit surfaces [2] applies.

However, because interval arithmetic is expensive and because a blobby is built from hundreds or thousands field primitives combined in a tree of operations, the repeated evaluation of the whole field function over an interval is awfully expensive. Fortunately, two key optimisations come to the rescue.

First, for most primitive field functions, it is possible to analytically compute the resulting interval on a given segment in 3D space. This way, the result is much tighter than the direct use of interval arithmetic.

The major optimization stems from the fact that primitive field functions have a compact support. This means that any given ray is likely to hit only a very limited subset of all blobby primitives. Before starting bisection, the ray is tested against the blobby bounding box. This gives a confidence interval where the ray can potentially hit the blobby. All primitives (and then all nodes in the tree) are evaluated against this interval. All leaves and nodes which are always 0 on the interval can be safely discarded which leads to a drastic simplification of the tree. Because of the inclusion property of arithmetic interval, we are guaranteed to compute accurate values on any subdivision of the confidence interval using this tree. This trimmed down (and much faster to evaluate) tree is then used in the bisection. The expensive tree needs to be evaluated only once per ray.

That's all for now. I'll give more details on the available field functions in the next post.

1. J. Bloomenthal, "An Implicit Surface Polygonizer", Graphics Gems IV, 1994
2. A. Knoll, Y. Hijazi, C. D. Hansen, I. Wald, and H. Hagen. "Interactive ray tracing of arbitrary implicit functions". In Proceedings of the 2007 Eurographics/IEEE Symposium on Interactive Ray Tracing, 2007.
3. O. Gourmel, A. Pajot, M. Paulin, L. Barthe, and P. Poulin, "Fitted BVH for Fast Raytracing of Metaballs". Computer Graphics Forum, (Proc. Eurographics '10), 29 (2), pp. 281-288, May 2010

Comments: 0, Rating: 0

XRT 2.1.0 released

Posted: 11 Jul 2013 12:58
Tags: downloads

Accessing RenderMan from Python
Image Unavailable
script written by Yuichirou Yokomakura

In a previous post, I complained about Pixar not updating the RenderMan interface specification1. Since then, my wishes have been more than fullfilled because the complete documentation for Pixar products (including past versions) is now online. Just check http://renderman.pixar.com/view/resources. Registration in the forums is required but is free.

Skimming through it, I can measure how far behind is XRT in terms of features. This new release (available in the Downloads section) is an attempt to somewhat fill the gap.

What's new

At first, my intent was to simply add a Python binding for the RenderMan interface provided by XRT. Using the ribclients project from Nicholas Yue, I thought it could be a quick development. Alas, I stumbled rapidly on limits and bugs of my current implementation. So, it turned out to be a complete rewrite of everything related to RenderMan in XRT.

RIB generator

I have switched from a bison/flex based implementation to a hand tuned lexer/parser. No only this is more flexible and allows for better error checking but loading files is now 30% faster.

RIB client

The previous implementation features only an interface to XRT. The new one supports also saving to output to ascii files or strings. Binary output is in the works.

Python binding

Pixar's Python binding for RenderMan ("PRMan for Python") documentation is rather sketchy. Nevertheless, that was enough to understand that I needed to perform extensive modifications to the original "ribclients" code. I have mostly based my tests on a handful of example files gathered on the Internet. My main sources have been Jon Macey's courseware and Yuichirou Yokomakura blog2.

In most cases, writing a Python binding is just a matter of translating arguments from Python to the target API. There are even tools that automate this kind of tasks, SWIG being probably the most widely known. PRMan for Python follows this pattern except for Procedurals which request procedural callbacks written in Python. My tests are OK but I have not tried enough examples to be completely confident on my implementation.

Misc bits and fixes

  • There is now a progress bar in the console so that you know if your render is doing well (or not …).
  • CSG operations and transformation stack management are much more robust.
  • There is a improved sampler for even better image quality (as explained here).
  • RenderMan inline archives and hierarchical subdivision meshes (rendered as simple subdivision meshes) are now supported.

Comments: 0, Rating: 0

A new sampler

Posted: 10 Jul 2013 22:27
Tags: sampling

The Pixar folks are not only good at making movies, they have also a team of top-notch engineers who write R&D papers available at the Pixar online library . One of their latest publications is called "Correlated Multi-Jittered Sampling". The happy few who read this blog know that one of my pet subjects is sampling. Therefore, this paper could not pass unnoticed.

Let me remind you of a few concepts about samplers before digging into it1.

A stratified sampler divides the unit square (the area of a pixel, for instance) into equal area cells and position a single sample within each cell. If the sample is at the center of cell, you get an uniform sampler, the simplest but the worst (in terms of aliasing) sampler. If the position is jittered within the cell, you get a stratified jittered sampler. Jittering allows you to trade aliasing for noise but the noise increases when samples get too near from each other in neighbouring cells or adjacent pixels. This is called clumpiness. A well designed sampler will try to preserve stratification and to decrease clumpiness.

There are other types of samplers. Amongst then, low-discrepancy samplers built from quasi-Monte Carlo sequences are the best at decreasing clumpiness but they tend to suffer from correlation artifacts because they are highly deterministic. They also require a degree in mathematics from you. As explained in this post, XRT use these sampling techniques for area lights, soft shadows, glossiness or translucency.

Pixar's paper advocates a variant of stratified sampling that reaches the level of quality of low-discrepancy samplers through smart jittering techniques. Although the article gives ample arguments to proof the validity of correlated multi-jittered sampling, perhaps the best one is the fact that Pixar is confident enough to use it in the latest RenderMan Pro Server. The author has also been kind enough to provide a sample implementation2. I could not refrain myself to give it a try …

Here is a comparison between XRT current sampler (on the left) and the new one (on the right).

Depth of field (magnified 5 times)

Image Unavailable

Image Unavailable

Thin lines (magnified 2 times)

Image Unavailable

Image Unavailable

Motion blur (magnified 5 times)

Image Unavailable

Image Unavailable

This looks really convincing with depth of field effects and thin lines but is only marginally better for motion blur and large edges. To be honest, visually speaking, I see no differences but, when comparing the two pictures as JPEG files, the picture computed with the new sampler compresses slightly better which means there is less noise.

Therefore, correlated multi-jittered sampling will be the new default sampling method in the next version of XRT.

Comments: 0, Rating: 0

XRT 2.0.1 released

Posted: 13 Jun 2013 22:07
Tags: downloads embree

This release integrates a custom version of the Embree 1.1 BVH building and traversal engine, heavily modified to support all kinds of primitives and not only triangles. Compared to version 1.0, Embree 1.1 requires much less memory to build a BVH tree and therefore is able to process larger scenes at the expense of increased building times. Of course, XRT benefits from this improvement.

Here is an example of scene that XRT could not process before.

Curly hair
Image Unavailable
3.5 millions hair segments !!

You will find the new "hairy" pictures in the expanded Hair Models gallery.

Another benefit of the BVH accelerator overhaul is a small speed boost. In my first attempt to integrate Embree, I reported somewhat surprising results: the algorithms supposed to build the most efficient traversal trees had the poorest traversal speeds. I had no clues about this behaviour and I still haven't. Although I have copy/pasted the same kind of modifications in 1.1 that I did in 1.0, this time, I seem to get it right: you can expect a 10% speed increase from SAH-based algorithms.

Comments: 0, Rating: 0

Production Volume Rendering: a follow-up

Posted: 10 Mar 2013 15:03
Tags: pvr


Just a quick note to let you know that a slew of modications that I made to compile and render PVR on Windows have been accepted by Marcus Wrenninge and are now available to everyone at the PVR GitHub repository. The vast majority of the code changes have been made to please the VC++ 2010 compiler and to export DLL symbols. I have also fixed a number of Python scripts that were not in sync with PVR Python binding.

I have also contributed a VC++ 2010 solution for PVR. It probably would have been better to add WIN32 support to the existing SCons project or to provide files for CMake but I am not an expert for these tools. If someone wishes to step in, I'll be happy to provide help for testing. In the meantime, this will save mucho typing for Windows users. However, there is still quite a lot of work to perform to have a working platform. If this is your first time, expect to spend a whole day downloading, compiling and organizing the whole shebang.

First, you need to compile Field3D, OpenImageIO dependencies (which also have a large number of dependencies). You also need to install boost-1.44 (other versions will probably do; the solution is just set for this very version).

Next, the solution expects to find libs and includes in a well behaved environment, ie your dependencies file structure should look like this

Third party tools -->
| Field3D -->
| | lib
| | include
| OpenImageIO -->
| | lib
| | include
| others -->
| | lib
| | include

which is probably the ugliest graphics ever published on this blog but you get the *cough* picture *cough*. “Third party tools” root directory can be any name of your liking but, before starting the solution itself, you need to set a THIRD_PARTY_TOOLS_HOME environment variable with this name for the solution to find PVR dependencies. A .bat file is supplied to perform these duties. Others dependencies are hdf5 and ilmbase-1.0.1 (from the OpenEXR distribution) that are subdependencies from Field3D and OpenImageIO.

Finally, you will need to copy libpvr/export to libpvr/pvr and libpvr/external/GPD-pvr/export to libpvr/external/GPD-pvr/GPD-pvr.

You are now ready to compile PVR. Happy rendering !

Comments: 0, Rating: 0

3.0 plans

Posted: 18 Jan 2013 22:15
Tags: roadmap

Here is what I plan for version 3.0. Please bear in mind that roadmaps are not set in stone and may evolve if need be.

Open Shading Language integration

Open Shading Language (OSL) is quite trendy at the moment (see this post from Larry Gritz). Let me explain my perception of the pros and cons of OSL.

Given that XRT already supports a shading language, why move to something else? The answer is that the current implementation has a number of limitations:

  • to compute derivatives, a shader is executed at three different locations: P+dPdx, then P+dPdy and finally P (this is how BMRT implemented derivatives). Through some clever tricks implemented within the SL library, the computed values are retained and derivatives are computed at the P location. There are two drawbacks: even if only one derivative is needed, the entire shader is run thrice (except for light loops which are evaluated once). If a derivative depends on an other derivative, the computed value is 0 because second orders derivatives would require more shader executions.
  • the compiler is not able to take advantage of shader parameters that are constant for a whole primitive and prune execution accordingly. For instance, in the following construct, which occurs more than often, the condition keeps on being evaluated.
if (texturename != "")
  • ray differentials are not propagated which makes it impossible to filter textures or to refine subdivision surfaces.

OSL brings answers to all these issues through automatic differentiation, derivative tracking and just-in-time compilation (based on LLVM tools). These are quite powerful incentives for integrating this terrific piece of software. However, there are also some design decisions or unimplemented features that make me uneasy:

  • lights are modeled as emissive surfaces which means only area lights are available.
  • closures (a rough equivalent to RSL lights loops) are built in the renderer although a future version of OSL may support their implementation in the OSL itself1.

As a result, the renderers that integrate OSL must provide implementations for point lights, directional lights and closures. This clearly loses flexibility compared to a full-fledged shading language.

I guess that the main reason for this is that there are deadlines in the real world and that you sometimes have to deliver intermediate releases before the final product to allow people to work. Nevertheless, it does not compromise a major design goal from OSL which is to relieve shader writers as much as possible from the intrincacies of rendering2.

I have not been able to find much information on the latest evolutions of RSL but, from what I gathered here, Pixar folks have chosen to preserve flexibility but require more from the shader writers. Hence, the need for a more complex interface with the renderer. For instance, PRMan 17.0 is now also a path tracer. I have a quite limited knowledge of path tracing but I understand that "importance sampling" (in plain words, put your samples where your light is) is key to performance and image quality. Therefore, an "efficient" shader has to provide information on how it must be "importance sampled".

I do not feel like going backwards in terms of features. So, I could either try to extend OSL for my needs - but can it be called OSL anymore? - or keep on supporting RSL while reusing the OSL infrastructure - how about a public spec, Pixar? In any case, I'll try first to match the existing XRT capabilities (while learning more on LLVM) before moving on to advanced stuff such like global illumination.

True displacements with shaders

Actually, this is a completely uncharted territory for me. There are known solutions for scanline renderers but, when it comes to raytracing, computer graphics litterature does not help much. Despite being a important feature in a renderer (guess why commercial renderers are so tight lipped on that matter), there is only a handful of papers that deals with the subject

1. PHARR, M., AND HANRAHAN, P. 1996: Geometry caching for ray-tracing displacement maps. In Eurographics Rendering Workshop 1996, pp. 31–40 (paper link).
2. SMITS B., SHIRLEY P., STARK M. 2000: Direct ray tracing of displacement mapped triangles. In Proc. Eurographics Workshop on Rendering Techniques 2000, pp. 307–318 (paper link).
3. CHRISTENSEN, P. H., LAUR, D. M., FONG, J., WOOTEN, W. L., AND BATALI, D. 2003. Ray differentials and multiresolution geometry caching for distribution ray tracing in complex scenes. In Eurographics 2003 (paper link).
4. STOLL G., MARK W., DJEU P., WANG R., ELHASSAN I. 2006: Razor: An architecture for dynamic multiresolution ray tracing. Technical report 06-21, Department of Computer Science, University of Texas at Austin, 2006 (paper link).
5. HANIKA, J., KELLER, A., AND LENSCH, H. 2010. Two-level ray tracing with reordering for highly complex scenes. In Proceedings of Graphics Interface 2010, pp 145–152 (paper link). Also known as the "Rayes" algorithm.

The lack of any decent implementation in open-source renderers is probably a good measure of its difficulty:

  • LuxRender implements a very limited subset of displacement shaders: textures are used to displace subdivision surfaces along the normal. Although a very respectable effort, it's far from I want to achieve.
  • I believe there is a similar feature in Blender Cycles but, according to its lead developper, Brecht Van Lommel, it's far from satisfactory.
  • Psychopath is an on-going effort to implement the "Rayes" algorithm.

I feel too very attracted by the "Rayes" algorithm, maybe because the paper seems the easiest to understand. The OpenSubdiv project from Pixar will likely be an asset for XRT.

Path tracing

Although I sometimes wonder how people are willing to accept many hours render times for a single (noisy) picture, I want to give it a try just for the sake of curiosity. The concepts are quite difficult to master but the good point is that it is a very hot topic for computer graphics. There are so many papers that the jury is still out to define what is an effective solution. Look for instance at the myriad of algorithms implemented in the Mitsuba renderer.

To help the newbies, there are lots of tiny projects that implements global illumination algorithms:

  • smallpt, a path tracer
  • smallpvt, a volumetric path tracer
  • smallppm, an implementation of "Progressive photon mapping"
  • gpusppm, an implementation of "Stochastic progressive photon mapping"
  • smallVCM, an implementation of the "Vertex connection and merging" algorithm (a combination of progressive photon mapping and bidirectional path tracing)
  • githole repositories, another collection of global illumination algorithms

None of them is really designed for performance. Their only aim is to provide a pedagogical starting point.

Volume rendering

My intent is to introduce concepts from the "Production Volume Rendering" book into XRT.

Deformation blur

You have been raytracing too much when you dream of path-traced displaced deformed motion-blurred polygons …

More RenderMan compliance

  • blobby support
  • RIB 3.3 support
  • Python binding for the RI interface

Comments: 0, Rating: 0