Friday, January 17, 2014

Dynamic coloring using Cycles/OSL

Description

 We want to make it possible to assign colors to objects based on their position in space.
Imagine we measured or calculated a 3D temperature distribution within a certain space. In order to assess the temperature at the surface of objects within that space, it would be nice to map the temperature information into those objects as local colors.

As an example we created a small movie. we know the temperature distribution within the wire frame box. Now we move a plane and a ball through this space and have its colors reflect the local value of the temperature. Of course, this can be used for any data field!



Download

The blender file together with the needed data files and osl scripts can be obtained on one zip file (including a blender addon parseheader which can display the wire frame box based on the used header file)

Former method

The previously described method of assigning colors to vertices can be used in combination with cycles as well (the "use vertex color" option must be used). This offers the possibility to assign the colors in a single shot, which remain constant over time. So in order to get dynamic coloring behaviour, we need to apply the color sampling step over and over again, using a python script.

New improved Cycles method

Within the cycles renderer, we can make use of OSL scripts, which allow the reading of image files to get external data in. These srcipts are called every time a picture is rendered, so the dynamics is taken care of by the renderer itself.

The normal use of this image reading feature is to import an image which can be used as a texture. Native OSL supports the field3d file format, enabling reading of 3D data sets. However, the osl implementation used in blender does not support this file format, so we are left with reading 2D images.
A set of 2D images can also be thought of a 3D data block, so this is the approach we took:
  1. Based on a 3D data field we produced a set of black-and-white images in png format.
  2. Next to these images a header file is created which described some characteristics of the data field
    • How many voxels in all three directions
    • What is the position of the data field in space
    • What is the size of the data field
    • The location of the image files
  3. The OSL script reads the header file upon compilation and uses as input
    • The current point 
    • The default value to use when the current point is located outside the data field
  4. The OSL script maps the coordinate of the current point to a data value, reading the appropriate data (image) files and reports a value between zero and one
  5. The output can be used as input for a colormap