Skip to content

Commit eba2e63

Browse files
agajdosivilemduha
authored andcommitted
Fix #28 Bake procedural textures and set them into materials before GLTF export
1 parent dc14851 commit eba2e63

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

blender_bg_scripts/gltf_bg_blender.py

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,97 @@ def make_active_UV_first(obj):
8989
make_UV_active(obj, orig_name) #move_UV_to_bottom() plays with active, so we set it here to originally active UV
9090
print(f"----- UVs before order: {[uv for uv in uvs]} ({uvs.active.name} is active)")
9191

92+
93+
# MARK: BAKE PROCEDURAL TEXTURES
94+
def is_procedural_material(mat):
95+
"""Determine if a material is procedural.
96+
Here, procedural is defined as using nodes without any Image Texture nodes.
97+
"""
98+
if not mat.use_nodes:
99+
return False
100+
for node in mat.node_tree.nodes:
101+
if node.type == 'TEX_IMAGE':
102+
return False
103+
return True
104+
105+
106+
def bake_all_procedural_textures(obj):
107+
"""Bake all procedural textures on a mesh object, storing the baked images within the Blender project."""
92108

109+
procedural_materials = [mat for mat in obj.data.materials if mat and is_procedural_material(mat)]
110+
if not procedural_materials:
111+
print(f"----- procedural materials not found on '{obj.name}'. Skipping bake.")
112+
return
113+
114+
# Configure bake settings
115+
bpy.context.scene.render.engine = 'CYCLES'
116+
bpy.context.scene.cycles.bake_type = 'DIFFUSE'
117+
bpy.context.scene.cycles.use_pass_color = True
118+
bpy.context.scene.cycles.bake_margin = 16
119+
120+
# Select the object and make it active
121+
bpy.ops.object.select_all(action='DESELECT')
122+
obj.select_set(True)
123+
bpy.context.view_layer.objects.active = obj
124+
125+
# Ensure the object is in Object Mode
126+
if obj.mode != 'OBJECT':
127+
bpy.ops.object.mode_set(mode='OBJECT')
128+
129+
# Prepare materials for baking
130+
for mat in procedural_materials:
131+
if not mat.use_nodes:
132+
mat.use_nodes = True
133+
nodes = mat.node_tree.nodes
134+
135+
# Create a new Image Texture node
136+
img_node = nodes.new(type='ShaderNodeTexImage')
137+
img_node.location = (-300, 0)
138+
139+
# Create a new image for baking
140+
bake_image = bpy.data.images.new(
141+
name=f"{obj.name}_{mat.name}_Bake",
142+
width=1024,
143+
height=1024
144+
)
145+
img_node.image = bake_image
146+
bake_image.generated_color = (0, 0, 0, 1) # Initialize with black
147+
148+
# Set the image as active for baking
149+
img_node.select = True
150+
mat.node_tree.nodes.active = img_node
151+
152+
# Perform the bake
153+
bpy.ops.object.bake(
154+
type='DIFFUSE',
155+
pass_filter={'COLOR'},
156+
use_selected_to_active=False,
157+
margin=16
158+
)
159+
print(f"----- baked procedural textures {procedural_materials}")
160+
161+
# Assign baked textures to materials
162+
for mat in procedural_materials:
163+
nodes = mat.node_tree.nodes
164+
img_node = next((node for node in nodes if node.type == 'TEX_IMAGE' and node.image.name == f"{obj.name}_{mat.name}_Bake"), None)
165+
if not img_node:
166+
continue
167+
# Find the Principled BSDF node
168+
bsdf = next((node for node in nodes if node.type == 'BSDF_PRINCIPLED'), None)
169+
if bsdf:
170+
# Remove existing connections to Base Color
171+
for link in list(bsdf.inputs['Base Color'].links):
172+
mat.node_tree.links.remove(link)
173+
# Connect the Image Texture node to Base Color
174+
mat.node_tree.links.new(img_node.outputs['Color'], bsdf.inputs['Base Color'])
175+
# Pack the image into the Blender file
176+
if not img_node.image.packed_file:
177+
img_node.image.pack()
178+
print(f"Packed image '{img_node.image.name}' into the Blender project.")
179+
180+
print(f"----- baked textures assigned")
181+
182+
93183
# MARK: GENERATE
94184
# ACCEPT different formats - like WEB (compressed GLTF), GODOT (uncompressed)
95185
def generate_gltf(json_result_path: str, target_format: str):
@@ -106,7 +196,7 @@ def generate_gltf(json_result_path: str, target_format: str):
106196
if obj.type != 'MESH':
107197
continue
108198
disable_subsurf_modifiers(obj)
109-
#remove_inactive_uv_maps(obj)
199+
bake_all_procedural_textures(obj)
110200
make_active_UV_first(obj)
111201

112202
print("=== PRE-PROCESSING FINISHED ===")

0 commit comments

Comments
 (0)