Loading Materials
Python script for batch loading Redshift materials in Houdini
About
This Python script automates the creation of Redshift materials in Houdini by scanning a folder of textures or subfolders of materials. It matches texture files to material parameters and builds Redshift material networks automatically.
Usage
To run this script, open Houdini and go to Windows > Python Shell. Then enter:
exec(open("%DIR_SCRIPTS%/material_setup.py").read())
Replace %DIR_SCRIPTS%
with the folder path where you saved the script.
Script
import os
import hou
from tkinter import Tk, filedialog
def ask_texture_folder():
"""Open a dialog to select a folder containing textures or subfolders of materials."""
root = Tk()
root.withdraw() # Hide the main tkinter window
folder_selected = filedialog.askdirectory(title='Select Texture Folder')
root.destroy()
return folder_selected
def create_redshift_material(mat_name, tex_folder, matnet="/mat"):
matnet_node = hou.node(matnet)
if not matnet_node:
raise RuntimeError(f"{matnet} node not found")
# Create Redshift Material Builder subnet
rs_builder = matnet_node.createNode("redshift_vopnet", mat_name + "_rsbuilder")
# Create Redshift Material node inside builder
rs_material = rs_builder.createNode("redshift::Material", "redshift_material")
rs_material.moveToGoodPosition()
# Map material parameters to Poliigon texture filename keywords
maps = {
"diffuse_color": ["col", "basecolor", "albedo"],
"refl_roughness": ["gloss", "roughness", "rough"],
"refl_metalness": ["metal", "metallic"],
"bump_input": ["nrm", "normal"],
"displacement_input": ["disp", "displacement", "height"],
"refl_reflect_weight": ["refl", "reflection"],
"diffuse_weight": ["ao", "occlusion"],
"emission_color": ["emit", "emissive"],
}
def find_tex_file(keywords):
for fname in os.listdir(tex_folder):
lname = fname.lower()
for kw in keywords:
if kw in lname and lname.endswith((".png", ".jpg", ".jpeg", ".tif", ".exr")):
return os.path.join(tex_folder, fname)
return None
for param, keywords in maps.items():
filepath = find_tex_file(keywords)
if filepath:
tex_node_name = param + "_tex"
tex_node = rs_builder.createNode("redshift::TextureSampler", tex_node_name)
tex_node.parm("tex0").set(filepath)
tex_node.moveToGoodPosition()
input_index = rs_material.inputIndex(param)
if input_index >= 0:
rs_material.setInput(input_index, tex_node)
else:
print(f"Warning: Material parameter '{param}' not found")
rs_builder.layoutChildren()
rs_builder.moveToGoodPosition()
print(f"Created Redshift material '{rs_builder.name()}' with textures from {tex_folder}")
return rs_builder
def create_redshift_materials_for_folder(folder, matnet="/mat"):
"""
Creates Redshift materials for either:
- All subfolders inside `folder` (each subfolder is a material), or
- The folder itself if it has no subfolders (single material).
"""
subfolders = [entry for entry in os.scandir(folder) if entry.is_dir()]
if subfolders:
# Multiple subfolders: create a material for each subfolder
for entry in subfolders:
matname = entry.name
create_redshift_material(matname, entry.path, matnet)
else:
# No subfolders: treat the folder itself as a single material
matname = os.path.basename(folder)
create_redshift_material(matname, folder, matnet)
if __name__ == '__main__':
parent_folder = ask_texture_folder()
if not parent_folder:
print("No folder selected. Exiting.")
else:
create_redshift_materials_for_folder(parent_folder)