I am painting the default cube through vertex coloring. I paint the bottom four vertices as (0.25, 0.25, 0.25) and the top four vertices as (0.75, 0.75, 0.75).
When I inspect the result in VERTEX PAINT mode (using hotkey S to get the color), the bottom of the cube is indeed (0.25, 0.25, 0.25) and the top is (0.75, 0.75, 0.75).
However, the middle point of the cube is not (0.5, 0.5, 0.5), it is ~(0.56, 0.56, 0.56). Somehow the gradient is not linear. I don't think its an issue with sRGB vs Linear, because otherwise the bottom and top values would also be wrong, but it's just the values in between. So what is the issue here? I really need a linear gradient.
EDIT. related issue: https://developer.blender.org/T71835 This says it has something to do with how the vertex colors are stored (8-bit sRGB apparently).
Code to reproduce this issue:
"""Script that checks vertex color interpolation error on the default cube.
run command: `blender --python gradient_error.py` (opens blender)
"""
import bpy
# Set up scene
sce = bpy.context.scene
# Select cube
scene = bpy.context.scene
for ob in scene.objects:
ob.select_set(False)
if ob.name == 'Cube':
ob.select_set(True)
obj = bpy.context.view_layer.objects.active
# Get cube data
mesh = obj.data
vert_list = mesh.vertices
# Get the color map
if mesh.vertex_colors:
color_map = mesh.vertex_colors.active
else:
color_map = mesh.vertex_colors.new()
# apply colors
i = 0
for poly in mesh.polygons:
for idx in poly.loop_indices: #vertices
loop = mesh.loops[idx]
v = vert_list[loop.vertex_index]
z_coord = v.co.z
# Paint bottom 4 vertices 0.25, top 4 vertices 0.75.
if z_coord < 0:
color_map.data[i].color = (0.25, 0.25, 0.25, 0)
else:
color_map.data[i].color = (0.75, 0.75, 0.75, 0)
i += 1
# Give it this new material
mat = bpy.data.materials.new('vcolor_material')
# Deactivate shadows
mat.shadow_method = 'NONE'
# Apply material
mesh.materials.append(mat)
# Set Flat lighting and show Vertex Coloring
my_areas = bpy.context.workspace.screens[0].areas
my_shading = 'WIREFRAME'
for area in my_areas:
for space in area.spaces:
if space.type == 'VIEW_3D':
space.shading.light = "FLAT"
space.shading.color_type = "VERTEX"
bpy.ops.object.mode_set(mode='VERTEX_PAINT')
print("\nRan succesfully.\n")