見出し画像

[Blender] 原神っぽい見た目にするスクリプト

なにをやっているんだい?

なんだかゲーム内のような見た目に近づけるスクリプトです。
やっていることとしては、MMD用に設定されているマテリアルを、Blenderのものに置き換えつつ、影がアニメ調になるようにしています。研究の余地は、まだまだあります。手作業でもできますが量が多いので自動化してみました。

※ コードは最下部にベタ貼りしてます。
※ MMDマテリアルで「スフィア」の部分は変換がうまくいかないので、真っ黒になってしまった部分はスフィアをオフにするとよいです。これについては、後日改めて詳細追記します。
環境:Blender 3.0.0

設定方法

「Script」タブを開いたら、「+新規」でファイルを作成します
コードをファイルに保存して「開く」でもOK!

下のエディタ部分に下部のスクリプトを貼り付けます

左上のウィンドウで、設定したいモデルが選択されていることを確認したら

「▶」実行ボタンをくりっく

なにやら変わっているはず
※ ライトは「サン」や「エリア」など強めのものを推奨。

BEFORE
AFTER

コード

# Blender import
import bpy
import math
import bmesh


#import os
#os.system('chcp 65001')


# Slect Active Object
ACIVE_OBJECT = bpy.context.active_object
material_slots = ACIVE_OBJECT.material_slots
print("Material Slots:"len(material_slots))
#print(dir(material_slots))


for slot in material_slots:
    slot_name = slot.name
    node_tree = slot.material.node_tree
    nodes = node_tree.nodes
    links = node_tree.links
    print("----- [{}]({}) -----".format(slot_name, len(nodes)))
   
    def_loc = (00)
    tex_uv = None
    base_tex = None
    output = None
    mmd_shader = None
    mmd_toon_tex = None
    mmd_sphere_tex = None
    for n in nodes:
        if n.name == "mmd_tex_uv":
            def_loc = n.location
            tex_uv = n
#            print(def_loc)
        if n.name == "mmd_base_tex":
            base_tex = n
        if n.bl_label == "Material Output":
            output = n
        if n.name == "mmd_shader":
            mmd_shader = n
        if n.name == "mmd_toon_tex":
            mmd_toon_tex = n
        if n.name == "mmd_sphere_tex":
            mmd_sphere_tex = n
        blabel = n.bl_label
        nlabel = n.label
#        print("Nodes Name:", n.name)
#        print("Blender Label:", blabel)
#        print(" Normal Label:", nlabel)
#        print("Location:", n.location)


    for l in links:
        links.remove(l)
       
    if not mmd_shader is None:
        nodes.remove(mmd_shader)
    if not mmd_toon_tex is None:
        nodes.remove(mmd_toon_tex)
    if not mmd_sphere_tex is None:
        nodes.remove(mmd_sphere_tex)
   
    blend_type = 'MULTIPLY'
    if slot_name[-1] == "+":
        blend_type = 'MIX'
        continue
   
    diffuse = nodes.new(type='ShaderNodeBsdfDiffuse')
    diffuse.location = (def_loc[0], def_loc[1] + 200)
   
    shader2rgb = nodes.new(type='ShaderNodeShaderToRGB')
    shader2rgb.location = (def_loc[0] + 200, def_loc[1] + 200)
    links.new(diffuse.outputs[0], shader2rgb.inputs[0])
   
    val2rgb = nodes.new(type='ShaderNodeValToRGB')
    val2rgb.location = (def_loc[0] + 400, def_loc[1] + 200)
    val2rgb.color_ramp.interpolation = 'CONSTANT'
    val2rgb.color_ramp.elements[1].color = (1111)
    val2rgb.color_ramp.elements[1].position = 0.5
    links.new(shader2rgb.outputs[0], val2rgb.inputs[0])
   
    invert = nodes.new(type='ShaderNodeInvert')
    invert.location = (def_loc[0] +700, def_loc[1] + 200)
    links.new(val2rgb.outputs[0], invert.inputs[1])
   
    multiply = nodes.new(type='ShaderNodeMixRGB')
    multiply.location = (def_loc[0] + 900, def_loc[1])
   
    multiply.blend_type = blend_type
    multiply.use_clamp = True
    links.new(invert.outputs[0], multiply.inputs[0])
   
    hsv = nodes.new(type='ShaderNodeHueSaturation')
    hsv.location = (def_loc[0] + 700, def_loc[1] - 200)
    hsv.inputs[1].default_value = 1.3
   
    brightness = nodes.new(type='ShaderNodeBrightContrast')
    brightness.location = (def_loc[0] + 500, def_loc[1] - 300)
    brightness.inputs[1].default_value = -0.2
    links.new(brightness.outputs[0], hsv.inputs[4])
    links.new(hsv.outputs[0], multiply.inputs[2])
   
    links.new(tex_uv.outputs[0], base_tex.inputs[0])
    links.new(base_tex.outputs[0], multiply.inputs[1])
    links.new(base_tex.outputs[0], brightness.inputs[0])
    links.new(multiply.outputs[0], output.inputs[0])
   
    base_tex.location = (def_loc[0] + 200, def_loc[1] - 100)
    output.location = (def_loc[0] + 1200, def_loc[1])

のちのち、GitHubなどに移動します。。

#import os
#os.system('chcp 65001')

この部分は、うまく動作しなかった場合にコメントアウト部分を外してお試しください。
日本語の文字化け対策など、文字コードの設定になります。

その他、コメントアウト部分(#で始まる行)は基本的にログの役割なので、必要に応じて外してください。

この記事が気に入ったらサポートをしてみませんか?