92 lines
4.9 KiB
Python
92 lines
4.9 KiB
Python
"""Small opaque PBR materials, generated without external assets."""
|
|
import unreal
|
|
|
|
from pathlib import Path
|
|
|
|
from .paths import GENERATED, slug
|
|
|
|
|
|
def color(name, rgb=(0.15, 0.5, 0.8), roughness=0.55, metallic=0.0):
|
|
path = f"{GENERATED}/Materials/M_{slug(name)}"
|
|
material = unreal.load_asset(path)
|
|
if material is None:
|
|
material = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
|
|
"M_" + name, GENERATED + "/Materials", unreal.Material, unreal.MaterialFactoryNew())
|
|
if not isinstance(material, unreal.Material):
|
|
raise TypeError(f"{path} nie jest materialem.")
|
|
lib = unreal.MaterialEditingLibrary
|
|
lib.delete_all_material_expressions(material)
|
|
base = lib.create_material_expression(material, unreal.MaterialExpressionConstant3Vector, -300, 0)
|
|
base.set_editor_property("constant", unreal.LinearColor(*rgb, 1.0))
|
|
lib.connect_material_property(base, "", unreal.MaterialProperty.MP_BASE_COLOR)
|
|
for offset, value, prop in [(160, roughness, unreal.MaterialProperty.MP_ROUGHNESS),
|
|
(280, metallic, unreal.MaterialProperty.MP_METALLIC)]:
|
|
node = lib.create_material_expression(material, unreal.MaterialExpressionConstant, -300, offset)
|
|
node.set_editor_property("r", float(value))
|
|
lib.connect_material_property(node, "", prop)
|
|
lib.recompile_material(material)
|
|
unreal.EditorAssetLibrary.save_loaded_asset(material)
|
|
return material
|
|
|
|
|
|
def assign(actor, material, slot=0):
|
|
component = actor.get_component_by_class(unreal.StaticMeshComponent)
|
|
if component is None:
|
|
raise TypeError("Material mozna przypisac do aktora ze StaticMeshComponent.")
|
|
component.set_material(slot, material)
|
|
|
|
|
|
def texture_set(name, *, base_color, normal=None, roughness=None, metallic=None, emissive=None):
|
|
"""Create one atlas material from adjacent PBR textures (PNG/JPEG)."""
|
|
slug(name)
|
|
tools = unreal.AssetToolsHelpers.get_asset_tools()
|
|
path = f"{GENERATED}/Materials/M_{name}"
|
|
material = unreal.load_asset(path)
|
|
if material is None:
|
|
material = tools.create_asset("M_" + name, GENERATED + "/Materials",
|
|
unreal.Material, unreal.MaterialFactoryNew())
|
|
lib = unreal.MaterialEditingLibrary
|
|
lib.delete_all_material_expressions(material)
|
|
entries = [("BaseColor", base_color, unreal.MaterialProperty.MP_BASE_COLOR, "RGB", "color"),
|
|
("Normal", normal, unreal.MaterialProperty.MP_NORMAL, "RGB", "normal"),
|
|
("Roughness", roughness, unreal.MaterialProperty.MP_ROUGHNESS, "R", "linear"),
|
|
("Metallic", metallic, unreal.MaterialProperty.MP_METALLIC, "R", "linear"),
|
|
("Emissive", emissive, unreal.MaterialProperty.MP_EMISSIVE_COLOR, "RGB", "color")]
|
|
for index, (label, filename, prop, channel, role) in enumerate(entries):
|
|
if filename is None:
|
|
if label in {"Roughness", "Metallic"}:
|
|
node = lib.create_material_expression(material, unreal.MaterialExpressionConstant, -300, index * 180)
|
|
node.set_editor_property("r", 0.6 if label == "Roughness" else 0.0)
|
|
lib.connect_material_property(node, "", prop)
|
|
continue
|
|
source = Path(filename).resolve()
|
|
if not source.is_file():
|
|
raise FileNotFoundError(source)
|
|
task = unreal.AssetImportTask()
|
|
task.filename = str(source)
|
|
task.destination_path = f"{GENERATED}/Materials/Textures/{name}"
|
|
task.destination_name = "T_" + label
|
|
task.automated = True
|
|
task.replace_existing = True
|
|
task.save = True
|
|
task.set_editor_property("async_", False)
|
|
tools.import_asset_tasks([task])
|
|
textures = [obj for obj in task.get_objects() if isinstance(obj, unreal.Texture2D)]
|
|
if len(textures) != 1:
|
|
raise RuntimeError("Nie mozna zaimportowac tekstury " + str(source))
|
|
texture = textures[0]
|
|
texture.set_editor_property("srgb", role == "color")
|
|
texture.set_editor_property("compression_settings", unreal.TextureCompressionSettings.TC_NORMALMAP
|
|
if role == "normal" else unreal.TextureCompressionSettings.TC_MASKS
|
|
if role == "linear" else unreal.TextureCompressionSettings.TC_DEFAULT)
|
|
unreal.EditorAssetLibrary.save_loaded_asset(texture)
|
|
node = lib.create_material_expression(material, unreal.MaterialExpressionTextureSample, -300, index * 180)
|
|
node.set_editor_property("texture", texture)
|
|
node.set_editor_property("sampler_type", unreal.MaterialSamplerType.SAMPLERTYPE_NORMAL
|
|
if role == "normal" else unreal.MaterialSamplerType.SAMPLERTYPE_MASKS
|
|
if role == "linear" else unreal.MaterialSamplerType.SAMPLERTYPE_COLOR)
|
|
lib.connect_material_property(node, channel, prop)
|
|
lib.recompile_material(material)
|
|
unreal.EditorAssetLibrary.save_loaded_asset(material)
|
|
return material
|