I use this code to paint:

import bpy

def random_color(obj):
    import random
    r = random.random
    mesh = obj.data 
    scn = bpy.context.scene
    #check if our mesh already has Vertex Colors, and if not add some... (first we need to make sure it's the active object)
    scn.objects.active = obj
    obj.select = True
    if mesh.vertex_colors:
        vcol_layer = mesh.vertex_colors.active
        vcol_layer = mesh.vertex_colors.new()
    for poly in mesh.polygons:
        for loop_index in poly.loop_indices:
            loop_vert_index = mesh.loops[loop_index].vertex_index
            random_color = [r(), r(), r()]
            vcol_layer.data[loop_index].color = random_color

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        bpy.context.scene.objects.active = obj

in the 3D viewer, I only observe the lase part of the plane is painted. enter image description here

Another problem is,when I render it, the plane is all black because I don't add a light source. But should I add light in vertex paint mode?


2 Answers 2


As far as I understand, this line


only causes the user interface to switch to Vertex Paint mode, which displays the vertex colors in the viewport when the object is active and allows you to paint the vertices on your own. This step is not required if you color the vertices in a script and it does not change the way the final image is being rendered. If these colors should also appear in the final render then you have to set up your material to take vertex colors into account. The answer to this question describes how to do that if you're using the Cycles render engine. You should end up with a material like this:

Cycles material which uses vertex color

Unless you're using an Emission shader instead of the Diffuse BSDF you still have to use other light sources in the scene.

And while the script seems to define the random_color function, the function doesn't actually get called. As you ended up with some parts of your model being painted, I assume this is only a missed line when you copied your script. In case it isn't, the last loop should probably be:

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        bpy.context.scene.objects.active = obj

It's likely that the viewport will still display only one mesh colored as Blender will only display vertex colors for the active object. All other objects will be displayed according to the Viewport Shading setting. This should explain why only one part of your model is colored while the rest of it remains grey. Once you've set up your material you can switch to Material shading to see the other parts of the plane colored as well.

Material shading option


Here is a bmesh take on this, using the code from this answer.

import bpy
import bmesh
from random import random
context = bpy.context
scene = context.scene
mesh = context.object.data
bm = bmesh.new()

meshes = [o.data for o in scene.objects if o.type == 'MESH']
for mesh in meshes:

    color_layer = bm.loops.layers.color.get("Col")
    if color_layer is None:
        color_layer = bm.loops.layers.color.new("Col")
    # make a random color table for each vert
    # vert_color = random_color_table[vert.index]
    random_color_table = [[random() for c in "rgb"]
                          for i in range(len(bm.verts))]
    for face in bm.faces:
        for loop in face.loops:
            print("Vert:", loop.vert.index)
            loop[color_layer] = random_color_table[loop.vert.index]

As pointed out by @binweg use How Can Vertex Paint Be Rendered to render.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .