-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrender.py
144 lines (115 loc) · 4.82 KB
/
render.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# This script should be run from the Blender Python console
import bpy
import os
import random
import subprocess
import pathlib
import logging
# Get current working directory
dir = bpy.path.abspath("//").replace("\\", "/")
# Constants
INPUT_DIR = f"{dir}out/cropped"
OUTPUT_DIR = f"{dir}out/rendered"
VARIATIONS = 2
# Run the "isolate.py" script via subprocess if the input directory doesn't exist or is empty
if not os.path.exists(INPUT_DIR) or len(os.listdir(INPUT_DIR)) == 0:
logging.info("No textures found, running isolate.py")
subprocess.run(["python", f"{dir}isolate.py"])
# If the output directory doesn't exist, create it
if not os.path.exists(OUTPUT_DIR):
pathlib.Path(OUTPUT_DIR).mkdir(parents=True, exist_ok=True)
# Get the coin object
coin = bpy.data.objects["Coin"]
# Get all materials
coin_face_mat = bpy.data.materials["Coin_face"]
coin_side_mat = bpy.data.materials["Coin_side"]
plane_concrete_mat = bpy.data.materials["Concrete"]
world_mat = bpy.data.worlds["World"]
# Get the texture nodes of the materials
for node in coin_face_mat.node_tree.nodes:
match node.name:
case "face_img_texture":
face_tex_node = node
case "face_bump_texture":
face_bump_node = node
case "rustiness":
rustiness_node = node
case "roughness":
roughness_node = node
for node in coin_side_mat.node_tree.nodes:
if node.name == "side_img_texture":
side_tex_node = node
elif node.name == "side_bump_texture":
side_bump_node = node
for node in plane_concrete_mat.node_tree.nodes:
if node.name == "texture_mapping":
mapping_node = node
for node in world_mat.node_tree.nodes:
match node.name:
case "r_weight":
r_weight_node = node
case "g_weight":
g_weight_node = node
case "b_weight":
b_weight_node = node
# List and group files in the input directory
files = os.listdir(INPUT_DIR)
textures = [file for file in files if file.endswith(".texture.png")]
dmaps = [file for file in files if file.endswith(".dmap.png")]
# Iterate through the textures in the input directory
for texture, dmap in zip(textures, dmaps):
# Load the texture
texture_image = bpy.data.images.load(os.path.join(INPUT_DIR, texture))
dmap_image = bpy.data.images.load(os.path.join(INPUT_DIR, dmap))
# Set the texture nodes image to the loaded texture
face_tex_node.image = texture_image
face_bump_node.image = dmap_image
side_tex_node.image = texture_image
side_bump_node.image = dmap_image
# Get the name of the texture
name = os.path.splitext(os.path.splitext(texture)[0])[0]
# Set the output file name
bpy.context.scene.render.filepath = os.path.join(OUTPUT_DIR, name)
# Generate random positions for the camera and light and randomize the light's color and intensity
for i in range(VARIATIONS):
# Set the camera's position around the coin
bpy.data.objects["Camera"].location = (
random.uniform(-2, 2), random.uniform(-2.5, -3), random.uniform(-2, 2))
# Set the coin's rotation around the y-axis
coin.rotation_euler = (coin.rotation_euler[0], random.uniform(0, 6.28), coin.rotation_euler[2])
# Set the light's color
(
r_weight_node.outputs[0].default_value,
g_weight_node.outputs[0].default_value,
b_weight_node.outputs[0].default_value
) = (
random.uniform(0.6, 1),
random.uniform(0.6, 1),
random.uniform(0.6, 1)
)
# Randomize the plane's texture position (edit the mapping node's location)
mapping_node.inputs[1].default_value = (
random.uniform(-5, 5), random.uniform(-5, 5), 0)
# Randomize the coin's age (0 = new, 1 = old) using a normal distribution
age = min(abs(random.normalvariate(0, 0.2)), 1)
# Randomize the rustiness of the coin using the age
rustiness_node.outputs[0].default_value = min(0.6 + age * 0.7, 0.9)
# Randomize the roughness of the coin using the age
roughness_node.outputs[0].default_value = min(0.4 + age * 0.5, 0.8)
continue
# Render the image
bpy.context.scene.render.filepath = os.path.join(
OUTPUT_DIR, f"{name}_{i}")
bpy.ops.render.render(write_still=True)
# Set render engine to Workbench
bpy.context.scene.render.engine = "BLENDER_WORKBENCH"
# Hide background plane
bpy.data.objects["Plane"].hide_render = True
# Render the image
bpy.context.scene.render.filepath = os.path.join(
OUTPUT_DIR, f"{name}_{i}_mask")
bpy.ops.render.render(write_still=True)
# Set render engine to Cycles
bpy.context.scene.render.engine = "CYCLES"
# Show background plane
bpy.data.objects["Plane"].hide_render = False