What is InterpolateScalarsBeforeMapping in VTK?
In VTK, there is a mapper flag called InterpolateScalarsBeforeMapping. The flag affects the way scalar data is visualized with colors. The effect can be small, or quite large, depending on the data and color map that are used. So let’s look at some examples to see how it works.
If you do a Google image search for OpenGL triangle you’ll find a familiar image:
An image like this can be found in almost every OpenGL tutorial, somewhere around the 2nd or 3rd lesson. First you are taught how to draw a triangle, then you are taught how to add vertex colors. The image is an example of OpenGL color interpolation, and it looks kind of like a Pink Floyd laser show…
In scientific visualization, we can use colors to represent data. For example, this rendering of Mount St. Helens uses color to indicate terrain elevation:
The following image shows the mesh from a different perspective, and you can see that it is composed of triangles.
The colors at the vertices are chosen based on the elevation. Every vertex in the mesh has a scalar value which represents the elevation of the earth is at that location. We can map scalar values to colors using a lookup table.
The lookup table says that vertices with the lowest elevation are blue, and vertices with the highest elevation are red. Vertices with elevation close to the middle will be white.
With VTK, you can define a color lookup table using the class vtkLookupTable, and you can render the mesh using a vtkMapper. Together, these two classes provide a comprehensive API for controlling how the mesh colors are rendered. In the API of vtkMapper, there is a flag called InterpolateScalarsBeforeMapping which can be toggled on or off. The default is off, but is it better to turn it on? The documentation says:
“By default, vertex color is used to map colors to a surface. Colors are interpolated after being mapped. This option avoids color interpolation by using a one dimensional texture map for the colors.”
The ParaView documentation says:
“If on, scalars will be interpolated within polygons and color mapping will happen on a per-pixel basis. If off, color mapping occurs at polygon points and colors are interpolated, which is generally less accurate.”
So how does this flag affect a typical visualization? Let’s start with a simple example. Using ParaView, I created a Cylinder source and applied the Elevation filter, then visualized it with the Radiation color map:
The cylinder mesh is composed of vertices at the top and bottom caps, and color is interpolated along the vertical edges. Or is it? If you interpolate from black to white, you should get gray in the middle. But we don’t see gray, we see the red/orange/yellow progression that is defined by the color map. That’s because ParaView has set the InterpolateScalarsBeforeMapping flag to on. In ParaView, it is enabled by default. And it’s a good thing, because here is what the visualization looks like if we disable InterpolateScalarsBeforeMapping:
InterpolateScalarsBeforeMapping off.
Oops, not so colorful anymore. The color is interpolated between the vertices, and the result doesn’t look anything like the color map. That’s because when InterpolateScalarsBeforeMapping is off, the colors are interpolated by OpenGL using the vertex RGB values, and this can lead to the appearance of colors in your visualization which do not appear at all in the original color map.
The same interpolation effect occurs for wireframe visualization too:
Left, InterpolateScalarsBeforeMapping on. Right, InterpolateScalarsBeforeMapping off.
For the next example, I used ParaView to generate a more interesting mesh. I created a Wavelet source, then applied the Clip filter:
Left, InterpolateScalarsBeforeMapping on. Right, InterpolateScalarsBeforeMapping off.
In this visualization, the difference is hardly noticeable. But there is a slight difference, and it’s apparent if you use ParaView to switch rapidly between the renderings. In ParaView, the interpolation option can be toggled in the Display panel.
Now, let’s see what happens if we reduce the number of colors in the lookup table. In the following image, the lookup table contains just eight discrete colors, as shown in the vertical color bar:
Left, InterpolateScalarsBeforeMapping on. Right, InterpolateScalarsBeforeMapping off.
On the left, we can clearly see the contours of the scalar field, but on the right, the contours are obscured due to the color interpolation. In both modes, the colors at the vertices are the same, the difference is how color is assigned between the vertices. Clearly, color interpolation is not the best strategy for this type of visualization.
As the vtkMapper documentation states: color interpolation is avoided when you set InterpolateScalarsBeforeMapping to on. When it is on, VTK will generate a 1-dimensional texture that encodes the color lookup table. Vertex colors are replaced with vertex texture coordinates. Instead of interpolating colors, OpenGL will interpolate the texture coordinates, and assign pixel colors via texture lookup.
For more information about VTK, try the VTK and ParaView books, or browse tutorials and examples online.
Scalar interpolation is also supported in Kiwi, a framework for cross platform mobile device development using VTK, with OpenGL ES 2.0 rendering supported through VES. For more information, please ask on the VES public mailing list.
Thanks for reading!
A note on point cloud rendering: if you are using VTK for point cloud rendering with single vertex cells, then you should leave InterpolateScalarsBeforeMapping off. Scalar interpolation isn’t needed when rendering point clouds, and you will experience poor rendering performance otherwise.
For point cloud visualization, set InterpolateScalarsBeforeMapping off.
image credits:
http://onlyinpgh.com/2011/04/carnegie-laser-show/
Thanks Pat for an excellent set of demonstrations!
Some of the volume mappers in VTK also have a similar flag. Keep in mind that whether or not you map your scalar value to a color then interpolate colors, or interpolate scalar values then map to color depends on which makes sense for your data. If it is general true that between scalar value A and scalar value B you always have a ramp of scalar values from A to B then interpolating the scalar value first then mapping that to a color is the right thing to do. But, if that isn’t the case then you might wind up with a misleading image. A classic medical example can be found in rendering CT data. The values that typically correspond to skin and soft tissue lie between the values for air and for bone. However, the teeth (bone values) can be adjacent to air. If you interpolate scalars and then map to color, you’ll wind up with what looks like a layer of skin over the teeth.
Just what I need, however I have a pipeline of vtkImageImport -> vtkImageReslice -> vtkImageMapToColors -> vtkImageActor and none of these inherit from vtkMapper. Let’s say I only have white and black colors being produced in vtkImageMapToColors, then when I turn on interpolation in vtkImageActor, then I get shades of grey for the interpolated pixels, but I want to keep them white or grey. How do I go about that?