March, 2013

1
Mar 13

Mitsuba 0.4.4 released

Hello all,

I’ve uploaded binaries for the Mitsuba 0.4.4 release. This is mainly a bugfix release to address issues concerning the previous version. There is, however, one new feature:

Improved Python bindings for rendering animations

It’s a fairly common operation to render a turntable animation of an object to understand its shape a little better. So far, doing this in Mitsuba involved many separate invocations of the renderer (one for each frame). Not only is this a bit tedious, but it also wastes a considerable amount of CPU time by loading and preprocessing the same scene over and over again. Python to the rescue!

In Mitsuba 0.4.4, the Python bindings make this kind of thing straightforward: simply load the scene and render out frames in a for loop. The following piece of code does this, together with motion blur. The work can be spread over the local cores or those on networked machines. Some setup code is omitted for brevity (see the Python chapter in the documentation for all details).

# Render a turntable with 360 / 2 = 180 frames
stepSize = 2
for i in range(0,360 / stepSize):
    # Compute the rotation at the beginning and the end of the frame
    rotationCur  = Transform.rotate(Vector(0, 0, 1), i*stepSize);
    rotationNext = Transform.rotate(Vector(0, 0, 1), (i+1)*stepSize);

    # Compute matching camera-to-world transformations
    trafoCur  = Transform.lookAt(rotationCur  * Point(0,-6,10),
        Point(0), rotationCur  * Vector(0, 1, 0))
    trafoNext = Transform.lookAt(rotationNext * Point(0,-6,10),
        Point(0), rotationNext * Vector(0, 1, 0))

    # Create an interpolating animated transformation
    atrafo = AnimatedTransform()
    atrafo.appendTransform(0, trafoCur)
    atrafo.appendTransform(1, trafoNext)
    atrafo.sortAndSimplify()
    sensor.setWorldTransform(atrafo) # Assign to the sensor

    # Submit the frame to the scheduler and wait for it to finish
    scene.setDestinationFile('frame_%03i.png' % i)
    job = RenderJob('job_%i' % i, scene, queue)
    job.start()
    queue.waitLeft(0)
    queue.join()

This is basically a 1:1 mapping of the C++ API. At this point, a good amount of the interfaces have been exposed, making it fun to prototype stuff while subjected to the amazing weightlessness of Python. Here, you can see an example of a video created this way (a turntable of the material test ball with a bumpy metal BSDF):



Other changes

  • Photon mapper: In previous releases, the standard photon mapper could miss certain specular paths compared to the path tracer. They are now correctly accounted for.

  • thindielectric: The thindielectric plugin computed incorrect transmittance values in certain situations; this is now fixed.

  • Robustness: Improved numerical robustness when dealing with specular+diffuse materials, such as “plastic”.

  • twosided: Fixed cases where the twosided plugin did not make a material two-sided as expected.

  • Instancing: The shading computed shading frame was incorrect for non-rigid transformations.

  • Cube shape: This recently added shape is now centered at the origin by default, to be consistent with the way that other shapes in Mitsuba work. This will require an extra translation in scenes which are already using the cube shape.

  • TLS cleanup logic: on some platforms, the mtssrv binary crashed with an exception after finishing a rendering job, due to some issues with cleaning up thread-local storage.

  • Other minor fixes and improvements, which are listed in the HG history