-
-class MaterialAtlas:
- def __init__(self, materials):
- self.render_mode = materials[0].render_mode
- if self.render_mode=='EXTERNAL':
- raise Exception("Material atlas with external render mode does not make sense")
-
- if self.render_mode=='CUSTOM':
- self.render_methods = materials[0].render_methods
- else:
- self.render_methods = None
- if self.render_methods:
- self.name = "material_atlas_"+os.path.splitext(self.render_methods[0].shader)[0]
- else:
- self.name = "material_atlas"
- self.receive_shadows = materials[0].receive_shadows
- self.cast_shadows = (materials[0].shadow_method!='NONE')
- self.materials = materials
- self.material_names = [m.name for m in self.materials]
- self.uniforms = None
- method_hash = compute_render_method_hash(self)
- for m in self.materials:
- if m.render_mode!=self.render_mode:
- raise Exception("Conflicting render modes in MaterialAtlas constructor")
- if self.render_mode=='CUSTOM' and compute_render_method_hash(m)!=method_hash:
- raise Exception("Conflicting shaders in MaterialAtlas constructor")
- if m.receive_shadows!=self.receive_shadows or m.shadow_method!=materials[0].shadow_method:
- raise Exception("Conflicting shadow settings in MaterialAtlas constructor")
-
- count = len(self.materials)
- size = 1
- while size*size*2<count:
- size *= 2
- if size*size>=count:
- self.size = (size, size)
- else:
- self.size = (size*2, size)
-
- from .util import get_colormap
-
- cm = get_colormap(True)
- self.base_color_data = ""
- for m in map(Material, self.materials):
- if any(p.texture for p in m.properties):
- raise Exception("Texturing is incompatible with material atlas")
- base_color = [int(cm(c)*255) for c in m.base_color.value]
- self.base_color_data += "\\x{:02X}\\x{:02X}\\x{:02X}\\xFF".format(*base_color)
- self.base_color_data += "\\x00\\x00\\x00\\x00"*(self.size[0]*self.size[1]-count)
-
- def get_material_uv(self, material):
- index = self.material_names.index(material.name)
- x = index%self.size[0]
- y = index//self.size[0]
- return ((x+0.5)/self.size[0], (y+0.5)/self.size[1])
-
-def create_material_atlas(context, material):
- if not material.material_atlas:
- raise Exception("Material is not part of a material atlas")
-
- method_hash = compute_render_method_hash(material)
- materials = []
- for m in context.blend_data.materials:
- if m.material_atlas and compute_render_method_hash(m)==method_hash:
- materials.append(m)
-
- return MaterialAtlas(materials)
+ def init_pbr_properties(self, node_tree, from_node):
+ base_color = self.create_property("base_color", (0.8, 0.8, 0.8, 1.0))
+ tint = self.create_property("tint", (1.0, 1.0, 1.0, 1.0))
+ metalness = self.create_property("metalness", 0.0)
+ roughness = self.create_property("roughness", 0.5)
+ normal = self.create_property("normal_map")
+ emission = self.create_property("emission", (0.0, 0.0, 0.0))
+
+ base_color.set_from_input(node_tree, from_node.inputs["Base Color"], from_node.inputs["Alpha"])
+ if base_color.tint:
+ tint.value = base_color.tint
+ metalness.set_from_input(node_tree, from_node.inputs["Metallic"])
+ roughness.set_from_input(node_tree, from_node.inputs["Roughness"])
+ normal.set_from_input(node_tree, from_node.inputs["Normal"])
+ emission.set_from_input(node_tree, from_node.inputs["Emission"])