BMS, Movie, Illustrations, Programming

頂点カラーは頂点に対してではなく、それぞれの面に対して個別に設定されている【Blender】

より正確に言うと、ループに対して頂点カラーが設定されている。このため、1つのマテリアルだけを用いて、それぞれの面を異なる色で塗り分けることができる。

ループとは

  • 面に対して、その面の角のことをループと呼ぶらしい
  • 面と、その面を構成する頂点の組に対してループが1つ存在する
  • 三角形にはループが 3つ存在し、Cube (立方体) にはループが 24個存在する
  • (法線を手前として) 反時計回りに面を囲むような順番で並べられている
  • 1つのループにつき、対応する面が1つ、頂点が1つ、その面の次のループへと向かう辺が1つある
  • Blender Python: The most confusing part of BMesh

頂点カラーとは

  • 頂点に色を塗ることが出来る 3DCG の概念
    • テクスチャとは異なる
  • 厳密には、頂点カラーは頂点ではなくループに対して設定されている
  • つまり、頂点に隣接する平面それぞれに対して、異なる色を割り当てることができる
    • Edge Split をする必要がない
    • ただし、Python プログラムを使わずにそれが出来るのかどうかは不明
  • Using Python and custom data to (vertex) color your Blender model

面を頂点カラーで塗り分ける例

頂点カラーを使用して、1つのマテリアルだけを用いて、それぞれの面を異なる色で塗り分けた例

塗り分ける前のメッシュ:

シェーダーノード:

Python プログラム:

import bpy

def update_vertex_color(obj):
    colors = [
        [1.0, 0.0, 0.0],
        [1.0, 1.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.0, 1.0, 1.0],
        [0.0, 0.0, 1.0],
        [1.0, 0.0, 1.0],
    ]

    mesh = obj.data
    
    if not mesh.vertex_colors:
        mesh.vertex_colors.new()
    vertex_color = mesh.vertex_colors[0]
    
    i = 0
    for j, poly in enumerate(mesh.polygons):
        r = colors[j % 6][0]
        g = colors[j % 6][1]
        b = colors[j % 6][2]

        for k, idx in enumerate(poly.loop_indices):
            vertex_color.data[i].color = (r, g, b, 1.0)
            # または vertex_color.data[idx].color = (r, g, b, 1.0)
            i += 1

update_vertex_color(bpy.data.objects['Cube'])

ループが反時計回りになっていることの可視化

もちろんそれぞれの頂点に異なる色を割り当てることも可能。赤 → 黄色 → 黄緑 → シアン → 青という順に、ループが反時計回りに一周していることが分かる。

Python プログラム:

import bpy

def update_vertex_color_2(obj):
    colors = [
        [1.0, 0.0, 0.0],
        [1.0, 1.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.0, 1.0, 1.0],
        [0.0, 0.0, 1.0],
        [1.0, 0.0, 1.0],
    ]

    mesh = obj.data
    
    if not mesh.vertex_colors:
        mesh.vertex_colors.new()
    vertex_color = mesh.vertex_colors[0]
    
    i = 0
    for j, poly in enumerate(mesh.polygons):
        for k, idx in enumerate(poly.loop_indices):
            r = colors[k % 6][0]
            g = colors[k % 6][1]
            b = colors[k % 6][2]
            vertex_color.data[i].color = (r, g, b, 1.0)
            # または vertex_color.data[idx].color = (r, g, b, 1.0)
            i += 1

update_vertex_color_2(bpy.data.objects['Cube'])

応用例

例えば、Python スクリプトと頂点カラーを使用して、某AEプラグインのように面を描画するマテリアルが作れるかもしれない