Alright so this annoyed me for a while as I saw loads of how to make procedural materials in blender stuff like that and I could never bring the into roblox. Well I finally figured it out and I’m going to show you and as a bonus I managed to make it a lot easier.
If your looking at this then I hope you already have blender installed and know how to texture and the different tabs if not there are loads of tutorials on youtube
I am going to show you how to do it the automated way
Starting
So i have this sphere and it uses a procedurally generate magma which I followed a tutorial to make It uses normal maps and everything.
I made a script to do this for me
python code:
import bpy
Path = "path here"
Name = "ImageName"
Type = 0
HoldingObj = bpy.context.active_object
TestObj = HoldingObj
Material = HoldingObj.data.materials[HoldingObj.active_material_index].copy()
Types = ["DIFFUSE","EMIT","NORMAL","ROUGHNESS"] #color, emmision / metal, normal, roughness
plane = bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
obj = bpy.context.active_object
if Type <4:
obj.data.materials.append(Material)
image_name = obj.name + Types[Type] + '_BakedTexture'
Resolution = [2048,2048] #1k = 1024, 2k = 2048 etc
img = bpy.data.images.new(image_name,Resolution[0],Resolution[1])
bpy.ops.object.editmode_toggle()
bpy.ops.uv.unwrap(method='ANGLE_BASED',margin=0)
bpy.ops.object.editmode_toggle()
bpy.context.scene.cycles.bake_type = Types[Type]
if Type != 0:
img.colorspace_settings.name = "Non-Color"
else:
bpy.context.scene.render.bake.use_pass_direct = False
bpy.context.scene.render.bake.use_pass_indirect = False
bpy.context.scene.render.bake.use_pass_color = True
#Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake.
print(img.colorspace_settings.name)
mat = obj.data.materials[0]
mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
nodes = mat.node_tree.nodes
texture_node =nodes.new('ShaderNodeTexImage')
texture_node.name = 'Bake_node'
texture_node.select = True
nodes.active = texture_node
texture_node.image = img #Assign the image to the node
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type=Types[Type], save_mode='EXTERNAL',width=Resolution[0],height=Resolution[1])
img.save_render(filepath=Path+"/"+Name+".png")
#In the last step, we are going to delete the nodes we created earlier
mat = obj.data.materials[0]
for n in mat.node_tree.nodes:
if n.name == 'Bake_node':
mat.node_tree.nodes.remove(n)
bpy.ops.object.delete()
TestObj.select_set(True)
else:
for Type in range(4):
Name = Types[Type]
obj = bpy.context.active_object
obj.data.materials.append(Material)
image_name = obj.name + Types[Type] + '_BakedTexture'
Resolution = [2048,2048] #1k = 1024, 2k = 2048 etc
img = bpy.data.images.new(image_name,Resolution[0],Resolution[1])
bpy.ops.object.editmode_toggle()
bpy.ops.uv.unwrap(method='ANGLE_BASED',margin=0)
bpy.ops.object.editmode_toggle()
bpy.context.scene.cycles.bake_type = Types[Type]
if Type != 0:
img.colorspace_settings.name = "Non-Color"
else:
bpy.context.scene.render.bake.use_pass_direct = False
bpy.context.scene.render.bake.use_pass_indirect = False
bpy.context.scene.render.bake.use_pass_color = True
#Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake.
print(img.colorspace_settings.name)
mat = obj.data.materials[0]
mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
nodes = mat.node_tree.nodes
texture_node =nodes.new('ShaderNodeTexImage')
texture_node.name = 'Bake_node'
texture_node.select = True
nodes.active = texture_node
texture_node.image = img #Assign the image to the node
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type=Types[Type], save_mode='EXTERNAL',width=Resolution[0],height=Resolution[1])
img.save_render(filepath=Path+"/"+Name+".png")
#In the last step, we are going to delete the nodes we created earlier
mat = obj.data.materials[0]
for n in mat.node_tree.nodes:
if n.name == 'Bake_node':
mat.node_tree.nodes.remove(n)
bpy.ops.object.material_slot_remove()
bpy.ops.object.delete()
TestObj.select_set(True)
So there are a few requirements first of all select the mesh which has the material.
Make sure the Material you want is at the very top
Change the path name to be a location e.g "C:"
If the type is 0 it does colour
If the type is 1 it does emission which can be used as metallic
If the type is 2 it does the normal
If the type is 3 it does the roughness
If the type if 4 it does all of them
Results
I ran the script at type 4 it gave out these files:
In roblox it looks like this:
There is some tiling which can be solved by a quick edit in gimp and editing the tile size.
I hope this helps you and feel free to ask any questions