I'm very new to blender so apologies if this question doesn't make that much sense. Anyways I'm working with tumors and I'm trying to find a way to color them like a topographical map (the end result would look similar), with the blue being the smoother/flatter areas, and red being areas farther from the main surface. Does anyone have any ideas?
One approach to this might be to use Dynamic Paint and Vertex Colors to create a proximity map between your surface, and a smoothed version of it. I imagine this will be for visualization and illustrative purposes, there's nothing calibrated about it. The method assumes quite high vertex density.
- Derive a base surface, from which, heights will influence color
In this example, I used AltS to scale the original mesh down along its surface normals, and a Smooth Modifier. (The smoothed object you can see in the illustration is a copy; the one actually used is inside the original mesh. If you make your copy an instance using Alt D, the you'll be able to adjust it conveniently, while viewing its effect.)
- Under the physics tab of the properties panel > Dynamic Paint, make the original mesh a Canvas, with settings as shown:
(.. you have to click the '+' next to the 'Paintmap Layer', to create a Vertex Color layer in the object)
- Under the physics tab of the properties panel > Dynamic Paint, make the smoothed mesh a Brush, with settings as shown:
(You will have to tweak the 'Paint Distance' parameter, in particular, to get a good range of tones.)
- Give the original mesh a material whose color is influenced by the tones in the Vertex Color layer, here left with its default name of 'dp_paintmap' (As you can see I haven't set the range of tones up perfectly, here)
and this is the sort of result:
Other options include combining this map with Sharpness as suggested by Duarte, or inverted normal Ambient Occlusion, to emphasise higher frequency (sharper) surface details, or thinner protrusions.
If you want to visualize something like surface roughness based on the mesh geometry I think there's no native way to do that in Blender.
Baking a displacement map of a high detail object to a smoothed version and exporting it, you could try image processing to calculate a representation of the local roughness. The resulting image can then be used as a texture in Blender.
As an example I used this “marshmallow” with regions of vertices randomized with different intensity.
The result ended up to look like this:
As a first step I created a rough UV map of the object followed by scaling it down and moving the UV islands a little bit apart as the baking will add some pixels of border around each island.
I duplicated the object and applied some iterations of smoothing – without reducing the poly count as I would like to reuse the UV map. The smoothed object is shown offset to the right in the screenshot, but would remain at the original position.
In Blender Render mode – which makes it easier to bake displacement maps – I create a new image with 2048×2048px, select the high detail object, shift click on the low detail version, go into edit mode and bake the displacement map in the render tab of the properties panel. Make sure to have “selected to active” checked and add a bit of margin.
I saved the image as grayscale and wrote a script for Python with
matplotlib as well as
import numpy as np import matplotlib.pyplot as plt from skimage.morphology import disk from scipy.ndimage import convolve im = plt.imread('displacement_map.png') im[im==0] = np.nan k = disk(10) # kernel shape is circle of radius 10px # should not be larger than margin of displacement_map im = np.absolute(im - np.nanmean(im)) roughness = convolve(im, k, mode='nearest') plt.imsave(fname='roughness_texture.png', arr=roughness)
roughness_texture.png that should be produced by the script can be added as a texture for the material of the object. By default, the colormap will be the purple to green
viridis, but it can be changed to one of
matplotlib's other color maps by requesting it in the
imsave function. Alternatively, you can use a grayscale color map and use Blender's color ramp node to change the colors within Blender afterwards.
plt.imsave(fname='roughness_texture.png', arr=roughness, cmap=plt.cm.gray)