# how to use external values as input for color ramp shader node?

All,

I've recently started dabbling in Blender to do some scientific visualization, like ParaView but 1000x prettier :)

At the moment I'm trying to tackle adding a color ramp to a 3D surface. As of now, I've been able to figure out how to use the surface's vertex geometry as the input for coloring. My current node setup looks something like this:

This separates the z-values from the geometry and uses them as input for the color map (after normalizing them in the map range node).

I want to do this exact same process, but instead of using the z-values, I want to use arbitrary values.

If I have a surface with n points, I will have an array with n values. These may represent temperature, salinity, velocity etc.

How could I go about doing this? Both GUI and python based solutions welcome! Would like to learn it first by GUI but will eventually be coded.

• Hi! Seems like your question titles are pretty much the same for all of your latest questions. Please make them specific, thanks. Consider that this is not a regular forum, please read: blender.stackexchange.com/help/how-to-ask Apr 18, 2020 at 7:22
• there are several questions that are related but are distinct questions, I ask them individually otherwise I get penalized for putting too much in one... trying to do one thing with multiple steps...any idea how to do this? Apr 18, 2020 at 16:56
• Your edit doesn't really help. Again, please take the time, read the link of my first comment and make your question useful for all of us by trying to find a specific title. Apr 18, 2020 at 17:03
• I feel like I'm somewhat responsible for this. It did seem to me that @DerekEden had two related, yet nevertheless distinct questions in a previous post. If reaching two goals requires two (potentially) distinct approaches, should there not be a separate question associated with each? Apr 18, 2020 at 18:23
• Related blender.stackexchange.com/questions/161664/… Can also use UV layer u, v data. Apr 19, 2020 at 10:06

You can loop over every vertex after initializing different arrays for each of your vertex color layers. You can parse the init data from a file (eg .csv) with python but this is not covered in this answer.

import bpy
import bmesh

obj = bpy.context.selected_objects[0]  # Get the currently selected object

vertex_colors = obj.data.vertex_colors
while vertex_colors:
vertex_colors.remove(vertex_colors[0])  # Remove all vertex color layers form the mesh data

bm = bmesh.new()  # Create new bmesh object
bm.from_mesh(obj.data)  # Init the bmesh with the current mesh

verts_count = len(bm.verts)  # Get the number of vertices in the mesh
# Not obligatory, I just use this to populate the vertex color layers)

# This dictionary will map each vertex color layer name to the data for each vertex
data_layers = {
'Temperature':  # vertex color layer name 1
[
(1, 0, 0, 1),  # Color of vertex index 0
(0, 1, 0, 1),  # Color of vertex index 1
(0, 0, 1, 1),  # Color of vertex index 2
(1, 1, 1, 1),  # Color of vertex index 3...
],
'Velocity':  # vertex color layer name 2
[(i / verts_count, i / verts_count, i / verts_count, 1) for i in range(verts_count)],
'Salinity':  # vertex color layer name 3
[(i / verts_count, 1 - (i / verts_count), 0.5, 1) for i in range(verts_count)],
}

color_layers = {}
for layer_name in data_layers:
# Create the vertex color layers and store them in a dictionary for easy access by name
color_layers[layer_name] = bm.loops.layers.color.new(layer_name)

for layer_name, layer in color_layers.items():
# Loop over each vertex color layer
for v in bm.verts:
# Loop over every vertex
# Loop over every loop of this vertex (the corners of the faces in which this vertex exists)
try:
loop[layer] = data_layers[layer_name][v.index]
# Get the value from the init dictionary
except IndexError:
loop[layer] = (1, 0, 1, 1)
# Set a placeholder (magenta) value if the mapping array is not long enough

bm.to_mesh(obj.data)  # Give the data back to the actual mesh


Then to acces the vertex colors in your material, use the vertex color node :

Note that the "Temperature" layer was initialized with only 4 values, so only a few vertices in the right eye got colored and the rest of the vertices got mapped to a magenta color.

Also note that you can store 4 values in each of the 4 channels of your color. Example with the 'Velocity' vertex color layer used before :

• looks insane...going to attempt this after dinner, will get back to you..thanks for input Apr 19, 2020 at 0:14
• seriously thank you, this worked like a charm. Apr 19, 2020 at 1:23
• @DerekEden I'm glad it helped you ! I have added a tip to add more information in each color's channel if you are intersted Apr 19, 2020 at 8:43
• @Gorgious This is a very nice answer. Do you know off-hand if the same can be done without using bmesh? I don't see any list like link_loops within an object's data property. Apr 20, 2020 at 22:52
• @JeremyHilgar Mesh has a loops attribute and then you can check the current loop's vertex_index attribute for mapping. But I'd rather use bmesh, any reason why you can't use this ? If it's an edit-mode problem, you can create a from-edit-meshbmesh Apr 21, 2020 at 7:23