LoginSignup
5
2

More than 3 years have passed since last update.

Blender2.80のスクリプトだけで例のゲームっぽい舞台を生み出す

Last updated at Posted at 2020-07-17

 Blender2.8のスクリプトの練習として、例のゲームっぽい舞台を作っていきます。
image.png
(イメージ映像)

image.png
(これは実在のハイ・トレッスル・トレイル橋(アイオワ州)

完成映像

 このようなものができる予定です。

image.png

ソースコード

import bpy
import numpy as np

#現状をリセット
for mat in bpy.data.materials:
    bpy.data.materials.remove(mat)
for cam in bpy.data.cameras:
    bpy.data.cameras.remove(cam)
for obj in bpy.data.objects:
    bpy.data.objects.remove(obj)
for obj in bpy.context.scene.objects:
    bpy.data.objects.remove(obj)

 何はなくともモジュールのインポートと現状のリセット。

足場

 とりあえず足場を作ります。まずはキューブ。

#足場を作る
bpy.ops.mesh.primitive_cube_add(location=(0,0,-50))
bpy.context.object.scale = (2,2,50)

image.png

 マテリアルを作って適用させます。

#黒マテリアルを設定
bpy.data.materials.new(name = 'black')
mat = bpy.data.materials['black']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes['Principled BSDF']
mat_node.inputs['Base Color'].default_value = (0,0,0,1)
mat_node.inputs['Metallic'].default_value = 1
mat_node.inputs['Specular'].default_value = 1

#黒マテリアルを足場に適用
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat

image.png

足場(枠)

 枠を作ります。WIREFRAMEモディファイアを利用します。

#枠を作る
bpy.ops.mesh.primitive_cube_add(location=(0,0,-50))
bpy.data.objects['Cube.001'].scale=(2,2,50)
bpy.ops.object.transform_apply(scale=True)
bpy.ops.object.modifier_add(type='WIREFRAME')
bpy.context.object.modifiers['Wireframe'].thickness = 0.05

image.png

 青く光るマテリアルを作って、枠に適用します。

#発光マテリアル(青)を設定
bpy.data.materials.new(name = 'blue')
mat = bpy.data.materials['blue']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes.new('ShaderNodeEmission')
mat_node.inputs['Color'].default_value = (0,0,1,1)
mat_node.inputs['Strength'].default_value = 500
matout = node_tree.nodes['Material Output']
node_tree.links.new(mat_node.outputs[0], matout.inputs[0])

#発光マテリアル(青)を枠に適用
mat = bpy.data.materials['blue']
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat

image.png

 use_nodesTrueにした場合、デフォルトではPrincipled BSDFが適用されますが、それ以外のシェーダを使う場合はnode_tree.nodes.newで新しくノードを作成し、それと出力ノードをリンクさせてあげなければいけません。そのあたりの処理が、

mat_node = node_tree.nodes.new('ShaderNodeEmission')

 と

node_tree.links.new(mat_node.outputs[0], matout.inputs[0])

 になります。

ねじれ枠

 はるかかなたに伸びるねじれ枠を作っていきます。平面をひねりながら生成していき、またWIREFRAMEを利用します。

#ねじれ枠を作る
for i in range(50):
    bpy.ops.mesh.primitive_plane_add(size=15,location=(0,i*5+10,0),rotation=(np.pi/2,i/5,0))
    bpy.ops.object.modifier_add(type='WIREFRAME')
    bpy.context.object.modifiers['Wireframe'].thickness = 0.8
    mat = bpy.data.materials['black']
    bpy.ops.object.material_slot_add()
    bpy.context.object.active_material=mat

image.png

黒マテリアルはすでに作成しているので、mat = bpy.data.materials['black']で呼び出すだけで再利用できます。

レールを作る

 赤と青のレールを敷いてあげましょう。先に発光マテリアルの赤バージョンを作成します。

#発光マテリアル(赤)を設定
bpy.data.materials.new(name = 'red')
mat = bpy.data.materials['red']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes.new('ShaderNodeEmission')
mat_node.inputs['Color'].default_value = (1,0,0,1)
mat_node.inputs['Strength'].default_value = 100
matout = node_tree.nodes['Material Output']
node_tree.links.new(mat_node.outputs[0], matout.inputs[0])

 そして改めてレール作成。

#レールを作る
poslist = [
    [ 4,0,-2],
    [ 4,0, 2],
    [-4,0,-2],
    [-4,0, 2]
    ]

for pos in poslist:
    bpy.ops.mesh.primitive_cube_add(size=1,location=pos)
    bpy.context.object.scale = [0.2,800,0.2]
    if bpy.context.object.location[2] > 1:
        mat = bpy.data.materials['red']
        bpy.ops.object.material_slot_add()
        bpy.context.object.active_material=mat
    else:
        mat = bpy.data.materials['blue']
        bpy.ops.object.material_slot_add()
        bpy.context.object.active_material=mat

image.png

カメラ

 最後にカメラをつけます。

#カメラを設定
bpy.ops.object.camera_add(location=(2,-10,2))
bpy.data.objects['Camera'].rotation_euler = (np.pi*1/2, 0, 0)
bpy.data.cameras[0].lens = 20

 あとは背景を黒くしてレンダリングすれば、

image.png

 このような感じになります。

全ソースコード

 今までのを1つのソースにまとめます。

import bpy
import numpy as np

#現状をリセット
for mat in bpy.data.materials:
    bpy.data.materials.remove(mat)
for cam in bpy.data.cameras:
    bpy.data.cameras.remove(cam)
for obj in bpy.data.objects:
    bpy.data.objects.remove(obj)
for obj in bpy.context.scene.objects:
    bpy.data.objects.remove(obj)

#足場を作る
bpy.ops.mesh.primitive_cube_add(location=(0,0,-50))
bpy.context.object.scale = (2,2,50)

#黒マテリアルを設定
bpy.data.materials.new(name = 'black')
mat = bpy.data.materials['black']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes['Principled BSDF']
mat_node.inputs['Base Color'].default_value = (0,0,0,1)
mat_node.inputs['Metallic'].default_value = 1
mat_node.inputs['Specular'].default_value = 1

#黒マテリアルを足場に適用
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat

#枠を作る
bpy.ops.mesh.primitive_cube_add(location=(0,0,-50))
bpy.data.objects['Cube.001'].scale=(2,2,50)
bpy.ops.object.transform_apply(scale=True)
bpy.ops.object.modifier_add(type='WIREFRAME')
bpy.context.object.modifiers['Wireframe'].thickness = 0.050

#発光マテリアル(青)を設定
bpy.data.materials.new(name = 'blue')
mat = bpy.data.materials['blue']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes.new('ShaderNodeEmission')
mat_node.inputs['Color'].default_value = (0,0,1,1)
mat_node.inputs['Strength'].default_value = 500
matout = node_tree.nodes['Material Output']
node_tree.links.new(mat_node.outputs[0], matout.inputs[0])

#発光マテリアル(青)を枠に適用
mat = bpy.data.materials['blue']
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat

#ねじれ枠を作る
for i in range(50):
    bpy.ops.mesh.primitive_plane_add(size=15,location=(0,i*5+10,0),rotation=(np.pi/2,i/5,0))
    bpy.ops.object.modifier_add(type='WIREFRAME')
    bpy.context.object.modifiers['Wireframe'].thickness = 0.8
    mat = bpy.data.materials['black']
    bpy.ops.object.material_slot_add()
    bpy.context.object.active_material=mat

#発光マテリアル(赤)を設定
bpy.data.materials.new(name = 'red')
mat = bpy.data.materials['red']
mat.use_nodes = True
node_tree = mat.node_tree
mat_node = node_tree.nodes.new('ShaderNodeEmission')
mat_node.inputs['Color'].default_value = (1,0,0,1)
mat_node.inputs['Strength'].default_value = 100
matout = node_tree.nodes['Material Output']
node_tree.links.new(mat_node.outputs[0], matout.inputs[0])

#レールを作る
poslist = [
    [ 4,0,-2],
    [ 4,0, 2],
    [-4,0,-2],
    [-4,0, 2]
    ]

for pos in poslist:
    bpy.ops.mesh.primitive_cube_add(size=1,location=pos)
    bpy.context.object.scale = [0.2,800,0.2]
    if bpy.context.object.location[2] > 1:
        mat = bpy.data.materials['red']
        bpy.ops.object.material_slot_add()
        bpy.context.object.active_material=mat
    else:
        mat = bpy.data.materials['blue']
        bpy.ops.object.material_slot_add()
        bpy.context.object.active_material=mat

#カメラを設定
bpy.ops.object.camera_add(location=(2,-10,2))
bpy.data.objects['Camera'].rotation_euler = (np.pi*1/2, 0, 0)
bpy.data.cameras[0].lens = 20
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2