Help with applying gradient vertex colors to mesh !?

Hi to all,
i am trying to write a script for applying gradient vertex colors to the active mesh.
What i actually want to achieve is to apply gradient white/black colors to a mesh, in more details the top vertices to have pure white color and the bottom vertices to have pure black color. All the vertices in the middle should have a gray scale value based on the normalized height of the mesh bounds for example.

I absolutely don’t understand the Blender API and python and i’m having difficulties to achieve this. I found an add-on from internet which i am trying to alter now in a way that will suite my needs but i am confused. So could you point me on how i have to get the mesh bound, create the interpolated color and apply it to the vertices. Here i have the altered code but it can only apply a constant color to a vertex:

import bpy
import random

bl_info = {
    'author': 'v',
    'category': '3D View',
    'description': 'Set model vertex color using a black/white gradient - used in game engine to bend trees',
    'name': 'Apply gradient mesh vertex colors'
}

def set_verts_colors():
    
    white = (1, 1, 1)
    black = (0, 0, 0)
    
    # must switch to Object Mode briefly to get the new set of selected elements
    # and then change the vertex_color layer
    bpy.ops.object.mode_set(mode='OBJECT')
    obj = bpy.context.active_object

    mesh = obj.data
    color_layer = mesh.vertex_colors.active  
    selected = set(v.index for v in obj.data.vertices if v.select)

    verts = mesh.vertices       
    i = 0
    for poly in mesh.polygons:
        for loop_index in poly.loop_indices:
            vidx = mesh.loops[loop_index].vertex_index                        
            if vidx in selected:
                # How to apply gradient color
                # pure white color on the highest vertices
                # black color on the bottom vertices
                # and of cource interpolated grayscale values for all verts in the middle
                color_layer.data[i].color = (1, 1, 1)
            i += 1
            
    # set to vertex paint mode to see the result
    # bpy.ops.object.mode_set(mode='VERTEX_PAINT')
    bpy.ops.object.mode_set(mode='EDIT')


class BSEVtexSetter(bpy.types.Operator):
    bl_idname = "object.vertex_color_setter"
    bl_label = "Apply gradient Vertex Color to mesh"
    
    def draw(self, context):        
        layout = self.layout
		
    def execute(self, context):
        set_verts_colors()
        return {'FINISHED'}
 
    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)
 
 
def register():
	bpy.utils.register_class(BSEVtexSetter)

def unregister():
    bpy.utils.unregister_class(BSEVtexSetter)
    del bpy.types.Scene.BSE_new_color

if __name__ == "__main__":
    register()

This should produce a white to black (top to bottom) gradient based on a normalized z location of a vertex. Hopefully should get you started :stuck_out_tongue:

import bpy
from mathutils import Vector
obj = bpy.context.object
me = obj.data

# get min and max z from bounding box and their differential
bbox = [Vector(point) for point in obj.bound_box]
max_z = max(v.z for v in bbox)
min_z = min(v.z for v in bbox)
diff = max_z - min_z

mesh_loops = me.loops
color_loops = me.vertex_colors.active.data

# vcol data is stored in a loop layer. to find the corresponding vertex,
# we'll use the regular mesh loops to find the vertex index and then access
# obj.data.vertices to get the z location.
for m_loop, c_loop in zip(mesh_loops, color_loops):

    idx = m_loop.vertex_index  # each loop has one vert index
    z = me.vertices[idx].co.z # store the z location from the index
    color = (z - min_z) / diff # calculate a normalized range (0.0 to 1.0)

    c_loop.color = [color] * 3 + [1]  # apply to the color loop as [color, color, color, 1]
1 Like

Yeah, thanks a lot, i understand the logic and i got it working !
Will try myself to add a couple of colors and alpha values and use them now for interpolation :slight_smile:

Thanks a lot for the help !