Created
March 28, 2023 08:01
-
-
Save wakarase/34c23eb7c4b5fdd0f8c97fc30469f462 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Blender 質感・マテリアル設定実践テクニック | |
# 3-05-02.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に配置します。""" | |
if name in ['Reroute']: | |
node = nodes.new('Node' + name) | |
else: | |
node = nodes.new('ShaderNode' + name) | |
node.label = node.name + ' del' # 自動生成したノードだというフラグです。 | |
x_offset = -2000 | |
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_color(): | |
"""色ムラの設定を用意します。これだけでもマテリアルとして完結します。""" | |
texture_coordinate = create('TexCoord', (-1648, -90)) | |
# 第1マスグレイブ。汚れの分布を定義します。 | |
# 次元を増やして、汚れのぼやけ具合を調整できます。 | |
musgrave_texture = create('TexMusgrave', (-1316, 289), Scale=2, Detail=15, Dimension=0.2, Lacunarity=1.4) | |
link(Object=texture_coordinate, Vector=musgrave_texture) | |
# +0.5が基本で、値を増やすほど汚れが広がります。 | |
# さほど広くない錆びの範囲として+0.7にします。 | |
if NOT_MODIFIED: | |
add = create('Math', (-1024, 182), _1=0.7) | |
else: | |
add = create('Math', (-1024, 182), _1=0.0) | |
link(Fac=musgrave_texture, Value=add) | |
reroute = create('Reroute', (-650, 110)) | |
link(Value=add, Input=reroute) | |
# 汚れていない部分や汚れている部分に対応する色を定義します。 | |
# 金属の腐食の複雑な色変化を表現するため、カラーミックスではなくカラーランプを使います。 | |
color_ramp = create('ValToRGB', (-573, 441)) | |
elements = color_ramp.color_ramp.elements | |
element = elements[0] | |
element.color = 0.560, 0.570, 0.580, 1.000 # 0xC5C7C8 錆びていない鉄。 | |
element = elements[1] | |
element.color = 0.058, 0.013, 0.008, 1.000 # 0x441E16 錆びの進んだ暗い部分。 | |
element = elements.new(position=0.5) | |
element.color = 0.413, 0.195, 0.061, 1.000 # 0xAC7A46 錆びはじめ部分。 | |
link(Output=reroute, Fac=color_ramp) | |
# 第2マスグレイブ。覆い焼きの分布を定義します。 | |
musgrave_texture = create('TexMusgrave', (-782, -82), Scale=2, Detail=15, Dimension=0, Lacunarity=1.5) | |
link(Object=texture_coordinate, Vector=musgrave_texture) | |
color_dudge = create('Mix', (-195, 440)) | |
color_dudge.data_type = 'RGBA' | |
color_dudge.blend_type = 'DODGE' | |
link(Color=color_ramp, _6=color_dudge) | |
link(Fac=musgrave_texture, _7=color_dudge) | |
principled_bsdf = create('BsdfPrincipled', (7, 315)) | |
link(_2=color_dudge, Base_Color=principled_bsdf) | |
# Material Outputノードがすでに配置されている前提で、それにつなげます。 | |
material_outputs = [] | |
for node in nodes: | |
if isinstance(node, bpy.types.ShaderNodeOutputMaterial): | |
material_outputs.append(node) | |
if len(material_outputs) != 1: | |
raise Exception('Number of Material Output nodes not 1.') | |
link(BSDF=principled_bsdf, Surface=material_outputs[0]) | |
return texture_coordinate, add, reroute, color_dudge, principled_bsdf | |
def create_uneven_texture(): | |
"""色ムラの分布に対し、粗さや凹凸などを追加します。「ドロドロ汚れの設定」などを担当します。""" | |
# まず色ムラを作ります。 | |
texture_coordinate, add, reroute, color_dudge, principled_bsdf = create_uneven_color() | |
# 汚れの分布である第1マスグレイブを覆い焼きの係数として用い、汚れだけに色ムラをつけることができます。 | |
# しかし、錆びた金属を表すには錆びてない部分もくすませたいので、同じ0.2にします。 | |
map_range = create('MapRange', (-534, 717), To_Min=0.2, To_Max=0.2) | |
link(Output=reroute, Value=map_range) | |
link(Result=map_range, Factor=color_dudge) | |
# 粗さを調整します。 | |
# 汚れていない部分の粗さを0.30、汚れ部分を1.00とし、錆び部分はツヤをなくします。 | |
if NOT_MODIFIED: | |
map_range = create('MapRange', (-189, -5), To_Min=0.30, To_Max=1.00) | |
else: | |
map_range = create('MapRange', (-189, -5), To_Min=0.05, To_Max=1.00) | |
link(Output=reroute, Value_=map_range) | |
link(Result=map_range, Roughness=principled_bsdf) | |
# 汚れの凹凸を表現していきます。 | |
# ノイズのスケールで凹凸模様の細かさを調整します。錆びなので細かくします。 | |
noise_texture = create('TexNoise', (-708, -370), Scale=50) | |
bump = create('Bump', (-186, -271)) | |
link(Object=texture_coordinate, Vector=noise_texture) | |
link(Fac=noise_texture, Height=bump) | |
link(Normal=bump, Normal_=principled_bsdf) | |
# 汚れていない部分のバンプを0.0、汚れ部分を0.5とします。 | |
# 0.5を変えて錆び部分の凹凸の度合いを調整できます。 | |
if NOT_MODIFIED: | |
map_range = create('MapRange', (-435, -131), To_Min=0.0, To_Max=0.5) | |
else: | |
map_range = create('MapRange', (-435, -131), To_Min=0.0, To_Max=0.2) | |
link(Output=reroute, Value_=map_range) | |
link(Result=map_range, Strength=bump) | |
return add, reroute, principled_bsdf | |
add, reroute, principled_bsdf = create_uneven_texture() | |
# 金属の質感を設定します。汚れのない部分がメタリック1です。 | |
map_range = create('MapRange', (-190, 256), To_Min=1.0, To_Max=-0.1) | |
link(Output=reroute, Value=map_range) | |
link(Result=map_range, Metallic=principled_bsdf) | |
# アンビエントオクルージョンで凹んだ部分の錆びを表現していきます。 | |
ambient_occlusion = create('AmbientOcclusion', (-1381, 53)) | |
# 陰影を濃くします。レンダリングエンジンがEeveeならガンマ10、Cyclesならガンマ3にします。 | |
if bpy.context.scene.render.engine == 'BLENDER_EEVEE': | |
gamma = 10 | |
else: | |
if NOT_MODIFIED: | |
gamma = 3.0 | |
else: | |
gamma = 1.5 | |
gamma = create('Gamma', (-1198, -6), Gamma=gamma) | |
# 凹んだ部分を汚したいので白黒反転させます。 | |
invert = create('Invert', (-1023, 15)) | |
screen = create('Mix', (-842, 171), Factor=1) | |
screen.data_type = 'RGBA' | |
screen.blend_type = 'SCREEN' | |
link(Color=ambient_occlusion, Color_=gamma) | |
link(Color=gamma, Color_=invert) | |
link(Color=invert, _7=screen) | |
link(Value=add, _6=screen) | |
link(_2=screen, Input=reroute) | |
print('Done.') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment