Skip to content

Instantly share code, notes, and snippets.

@wakarase
Created March 22, 2023 20:26
Show Gist options
  • Save wakarase/31b98ad460bd9a77b277235250276962 to your computer and use it in GitHub Desktop.
Save wakarase/31b98ad460bd9a77b277235250276962 to your computer and use it in GitHub Desktop.
# Blender 質感・マテリアル設定実践テクニック
# 3-04-01.blend ドロドロ汚れの作り方
import bpy
NOT_MODIFIED = False
object = bpy.data.objects['export3dcoat'] # シーンに配置済みのオブジェクト
slot = object.material_slots[0] # そのマテリアルスロット
material = slot.material # に設定されているマテリアル
node_tree = material.node_tree # のノードネットワーク
nodes = node_tree.nodes # にある各ノード
def delete():
"""過去に生成したノードを削除します。"""
for node in nodes:
if node.label.endswith(' del'):
nodes.remove(node)
delete()
def show():
"""既存のノードの情報を表示します。"""
for node in nodes:
s = 'node "{}" at {}'
s = s.format(node.name, list(node.location))
print(s, type(node))
show()
def format_key(key):
"""与えられた文字列を加工して必要なら整数にします。"""
if key.startswith('_'):
return int(key[1:]) # 先頭の下線で整数を表すことにします。
else:
key = key.rstrip('_') # 末尾の下線は無視することにします。
return key.replace('_', ' ') # 中間の下線で空白を表すことにします。
def create(name, location, **args):
"""新しくノードを作ってlocationに配置します。"""
node = nodes.new('ShaderNode' + name)
node.label = node.name + ' del' # 自動生成したノードだというフラグです。
x_offset = -1420
node.location = (location[0] + x_offset, location[1])
for key, value in args.items():
node.inputs[format_key(key)].default_value = value
return node
def link(**args):
"""2つのノードを接続します。"""
(k_left, v_left), (k_right, v_right) = args.items()
k_left, k_right = format_key(k_left), format_key(k_right)
node_tree.links.new(v_right.inputs[k_right], v_left.outputs[k_left])
def create_uneven_texture():
"""色ムラの設定を用意します。"""
texture_coordinate = create('TexCoord', (-1135, -176))
# 第1マスグレイブ。汚れの分布を定義します。
# 次元を増やして、汚れのぼやけ具合を調整できます。
if NOT_MODIFIED:
musgrave_texture = create('TexMusgrave', (-923, -11), Scale=2, Detail=15, Dimension=0, Lacunarity=1.4)
else:
musgrave_texture = create('TexMusgrave', (-923, -11), Scale=3, Detail=15, Dimension=0, Lacunarity=1.4)
link(Object=texture_coordinate, Vector=musgrave_texture)
if NOT_MODIFIED:
# +0.5が基本ですが、+1.5として汚れの範囲を見やすく広げます。
# 値を増やすほど汚れが広がるので、必要に応じて調整します。
add = create('Math', (-738, -13), _1=1.5)
link(Fac=musgrave_texture, Value=add)
else:
map_range = create('MapRange', (-738, 250), From_Min=-3, From_Max=-0)
link(Fac=musgrave_texture, Value=map_range)
add = create('Math', (-738, -13), _1=0.0) # ダミーです。
link(Result=map_range, Value_=add)
# 汚れていない部分の色と汚れの色のカラーミックスを設定します。
# ここでは泥汚れのイメージで、水色(0x548BE2)と茶色(0x4F3B30)とします。
mix = create('Mix', (-360, 176), _6=(0.089, 0.258, 0.761, 1.000), _7=(0.078, 0.044, 0.030, 1.000))
mix.data_type = 'RGBA'
link(Value=add, Factor=mix)
# 第2マスグレイブ。覆い焼きの分布を定義します。
if NOT_MODIFIED:
musgrave_texture = create('TexMusgrave', (-366, -8), Scale=2, Detail=15, Dimension=0, Lacunarity=1.5)
else:
musgrave_texture = create('TexMusgrave', (-366, -8), Scale=3, Detail=15, Dimension=0, Lacunarity=1.5)
link(Object=texture_coordinate, Vector=musgrave_texture)
color_dudge = create('Mix', (-151, 256))
color_dudge.data_type = 'RGBA'
if NOT_MODIFIED:
color_dudge.blend_type = 'DODGE'
else:
color_dudge.blend_type = 'OVERLAY'
link(_2=mix, _6=color_dudge)
link(Fac=musgrave_texture, _7=color_dudge)
principled_bsdf = create('BsdfPrincipled', (29, 279))
link(_2=color_dudge, Base_Color=principled_bsdf)
material_output = nodes['Material Output.002']
link(BSDF=principled_bsdf, Surface=material_output)
return texture_coordinate, add, color_dudge, principled_bsdf
texture_coordinate, add, color_dudge, principled_bsdf = create_uneven_texture()
# 色ムラを調整します。
# 汚れの分布である第1マスグレイブを覆い焼きの係数として用い、汚れだけに色ムラをつけます。
# そもそもの覆い焼きの分布である第2マスグレイブとの共通部分が強く覆い焼きされ、明るくかすれます。
# 「最大へ」(To Max)で、汚れの色ムラの強弱を調節できます。ペンキなどは0がいいです。
if NOT_MODIFIED:
map_range = create('MapRange', (-360, 441), To_Min=0.0, To_Max=0.2)
else:
map_range = create('MapRange', (-360, 441), From_Min=0.8, To_Max=0.15)
link(Value=add, Value_=map_range)
link(Result=map_range, Factor=color_dudge)
# 粗さを調整します。
# 汚れていない部分の粗さを0.5、汚れ部分を0.2とし、ドロドロのツヤを表現します。
# 0.2でなく増加させると、より乾いた汚れを表現できます。
if NOT_MODIFIED:
map_range = create('MapRange', (-150, 48), To_Min=0.5, To_Max=0.2)
else:
map_range = create('MapRange', (-150, 48), To_Min=0.8, To_Max=0.2)
link(Value=add, Value_=map_range)
link(Result=map_range, Roughness=principled_bsdf)
# 汚れの凹凸を表現していきます。
# ノイズのスケールで凹凸模様の細かさを調整します。
if NOT_MODIFIED:
noise_texture = create('TexNoise', (-373, -373), Scale=10)
else:
noise_texture = create('TexNoise', (-373, -373), Scale=11.5, Detail=3.5)
bump = create('Bump', (-142, -257))
link(Object=texture_coordinate, Vector=noise_texture)
link(Fac=noise_texture, Height=bump)
link(Normal=bump, Normal_=principled_bsdf)
# 汚れていない部分のバンプを0、汚れ部分を0.2とします。
# 0.2を変えて汚れの凹凸の度合いを調整できます。0.1ならサラッとした汚れです。
if NOT_MODIFIED:
map_range = create('MapRange', (-526, -200), To_Min=0.0, To_Max=0.2)
else:
map_range = create('MapRange', (-526, -200), From_Min=0.8, To_Max=0.3)
link(Value=add, Value_=map_range)
link(Result=map_range, Strength=bump)
print('Done.')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment