Merge_Textures 2.0

Merge Textures now accepts multiple different Suffixes and texture types. It also accepts multiple Texturesets at once.
This commit is contained in:
Killergnom
2024-10-18 15:50:58 +02:00
parent 04208ebe6e
commit e63b208f06
19 changed files with 39058 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
import os
import sys
from PIL import Image
import time
# Define suffix lists for BaseColor, Normal, RMA/ORM
BASECOLOR_SUFFIXES = ['_alb', '_albedo', '_bc', '_basecolor', '_b']
NORMAL_SUFFIXES = ['_nrm', '_normal', '_n']
RMA_SUFFIXES = ['_rma']
ORM_SUFFIXES = ['_orm']
EMISSIVE_SUFFIXES = ['_emissive']
OPACITY_SUFFIXES = ['_opacity']
def detect_texture_type(filename):
""" Detects the type of texture based on its suffix """
if any(suffix in filename.lower() for suffix in BASECOLOR_SUFFIXES):
return 'BaseColor'
elif any(suffix in filename.lower() for suffix in NORMAL_SUFFIXES):
return 'Normal'
elif any(suffix in filename.lower() for suffix in RMA_SUFFIXES):
return 'RMA'
elif any(suffix in filename.lower() for suffix in ORM_SUFFIXES):
return 'ORM'
elif any(suffix in filename.lower() for suffix in EMISSIVE_SUFFIXES):
return 'Emissive'
elif any(suffix in filename.lower() for suffix in OPACITY_SUFFIXES):
return 'Opacity'
return None
def get_material_name(filename):
""" Strips the 'T_' or 'TX_' prefix and returns the material name """
base_name = os.path.basename(filename)
if base_name.startswith('T_'):
return base_name[2:].split('_')[0] # Assumes 'T_Material_Suffix'
elif base_name.startswith('TX_'):
return base_name[3:].split('_')[0] # Assumes 'TX_Material_Suffix'
return base_name.split('_')[0]
def process_textures(input_files):
""" Main function to process all textures in a folder and convert to BCR/NMO """
textures = {}
# Group files by material name
for filepath in input_files:
filename = os.path.basename(filepath)
material_name = get_material_name(filename)
texture_type = detect_texture_type(filename)
if material_name not in textures:
textures[material_name] = {}
textures[material_name][texture_type] = filepath
# Create a merged folder in the same directory as the input
base_path = os.path.dirname(input_files[0])
output_folder = os.path.join(base_path, 'merged')
os.makedirs(output_folder, exist_ok=True)
# Process each material group
for material, files in textures.items():
basecolor_file = files.get('BaseColor')
normal_file = files.get('Normal')
rma_file = files.get('RMA')
orm_file = files.get('ORM')
emissive_file = files.get('Emissive')
opacity_file = files.get('Opacity')
if basecolor_file and normal_file and (rma_file or orm_file):
# Convert to BCR/NMO format
convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, output_folder)
print(f"{material}: Successfully converted.")
else:
print(f"Skipping {material}: missing necessary files")
print("+++All materials successfully converted+++")
time.sleep(3)
def convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, output_folder):
""" Converts given textures to BCR and NMO formats """
basecolor_img = Image.open(basecolor_file).convert('RGBA')
normal_img = Image.open(normal_file).convert('RGBA')
if rma_file:
rma_img = Image.open(rma_file).convert('RGBA')
# BCR conversion
bcr_img = Image.merge('RGBA', (basecolor_img.split()[0], basecolor_img.split()[1], basecolor_img.split()[2], rma_img.split()[0])) # Use Roughness (Alpha from RMA/ORM)
bcr_img.save(os.path.join(output_folder, f"{material}_BCR.png"))
# NMO conversion
nmo_img = Image.merge('RGBA', (normal_img.split()[0], normal_img.split()[1], rma_img.split()[1], rma_img.split()[2])) # Use Metallic, AO from RMA/ORM
nmo_img.save(os.path.join(output_folder, f"{material}_NMO.png"))
elif orm_file:
rma_img = Image.open(orm_file).convert('RGBA')
# BCR conversion
bcr_img = Image.merge('RGBA', (basecolor_img.split()[0], basecolor_img.split()[1], basecolor_img.split()[2], rma_img.split()[1])) # Use Roughness (Alpha from RMA/ORM)
bcr_img.save(os.path.join(output_folder, f"{material}_BCR.png"))
# NMO conversion
nmo_img = Image.merge('RGBA', (normal_img.split()[0], normal_img.split()[1], rma_img.split()[2], rma_img.split()[0])) # Use Metallic, AO from RMA/ORM
nmo_img.save(os.path.join(output_folder, f"{material}_NMO.png"))
# Optionally handle emissive and opacity maps
if emissive_file:
emissive_img = Image.open(emissive_file).convert('RGB')
emissive_img.save(os.path.join(output_folder, f"{material}_EM.png"))
if opacity_file:
opacity_img = Image.open(opacity_file).convert('L')
opacity_img.save(os.path.join(output_folder, f"{material}_OP.png"))
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: drag and drop texture files onto the script")
else:
# Get the file paths from sys.argv (ignoring the first argument which is the script name)
input_files = sys.argv[1:]
process_textures(input_files)