Mapping of DirectX (HLSL) materials
Max 2026 and earlier only
Autodesk removed the DirectX material model from Max 2027. The DirectX material APIs and scripts on this page require Max 2026 or earlier and are unavailable in Max 2027 or later.
The following sections contains examples on how to setup, export and import Simplygon materials through MaxScript and Python. It is recommended to read Shading network concepts before proceeding.
Simplygon PBR (DirectX)
This script loops through all Simplygon PBR materials (HLSL connected to DirectX) and sets up shading networks accordingly. Then it sends the selected assets to Simplygon for processing. When the processing is done the LODs are returned to Max where the script takes over and maps the LOD materials back to a HLSL shader.
MaxScript
clear
sgsdk_Reset()
sgsdk_UseShadingNetwork true
sgsdk_SetTextureOutputDirectory "D:\\CubeExample\\OutputTextures\\"
-- path to cubemap
cubeMapPath = "D:\\CubeExample\\cube_map.dds"
-- reduction pipeline with material baking
reductionPipelineWithMaterialBaking = "D:\\Pipelines\\reductionPipelineWithBaking.json"
-- effect file for writeback
effectFile = "D:\\CubeExample\\SimplygonMaxPBRShader.fx"
-- list that will be populated with DirectX Shaders
SimplygonShaderMaterials = #()
-- loop all scene materials
for mat in scenematerials do
(
print ("Material name: " + mat.name)
-- get all material properties
props = getPropNames mat
for i = 1 to props.count do
(
prop = getProperty mat props[i]
print ("\t\t\t." + props[i] + ": " + prop as string + "")
-- if contains "technique"
if (props[i] as string) == "technique" do
(
techniqueName = mat.getCurrentTechniqueName()
print ("\t\t\t." + props[i] + "Name: " + techniqueName as string + "")
-- see if it is the shader we want by looking at technique name
if techniqueName == "dx11|PBR_11" do
(
-- shader found, store in list
appendIfUnique SimplygonShaderMaterials mat
)
)
)
print ("\n")
-- loop through all sub-materials
subMatCount = getNumSubMtls mat
print ("\tNum sub-materials: " + subMatCount as string)
for i = 1 to subMatCount do
(
subMat = getSubMtl mat i
print ("\t\tSub-material name: " + subMat.name)
-- get all sub-material properties
props = getPropNames subMat
for i = 1 to props.count do
(
prop = getProperty subMat props[i]
print ("\t\t\t." + props[i] + ": " + prop as string + "")
-- if contains "technique"
if (props[i] as string) == "technique" do
(
techniqueName = subMat.getCurrentTechniqueName()
print ("\t\t\t." + props[i] + "Name: " + techniqueName as string + "")
-- see if it is the shader we want by looking at technique name
if techniqueName == "dx11|PBR_11" do
(
-- shader found, store in list
appendIfUnique SimplygonShaderMaterials subMat
)
)
)
print ("\n")
)
)
-- debug print of shader list
for mat in SimplygonShaderMaterials do
(
print ("Found Simplygon DirectX Shader: " + mat.name)
)
-- setup shading network for each material/shader
for mat in SimplygonShaderMaterials do
(
MaterialName = mat.name
print ("Setting up shading network for: " + MaterialName)
-- material
DirectXShader = sgsdk_CreateMaterialMetadata MaterialName
-- pre-setup
sgsdk_MaterialColor MaterialName "Ambient" 0 0 0 1
sgsdk_MaterialColor MaterialName "Diffuse" 1 1 1 1
sgsdk_MaterialColor MaterialName "Specular" 1 1 1 1
-- diffuse channel
if mat.DiffuseTexture != undefined then
(
DiffuseTexture = sgsdk_CreateShadingTextureNode("DiffuseTexture");
sgsdk_AddAttributeToNode DirectXShader "DiffuseTexturemapChannel" 3
sgsdk_ConnectNodeToChannel DiffuseTexture DirectXShader "Diffuse"
sgsdk_ConnectOutputToDirectXMaterial effectFile "Diffuse" "DiffuseTexture"
)
-- specular channel
if mat.SpecularTexture != undefined then
(
SpecularTexture = sgsdk_CreateShadingTextureNode("SpecularTexture");
sgsdk_AddAttributeToNode DirectXShader "SpecularTexturemapChannel" 3
sgsdk_ConnectNodeToChannel SpecularTexture DirectXShader "Specular"
sgsdk_ConnectOutputToDirectXMaterial effectFile "Specular" "SpecularTexture"
)
-- roughness channel
if mat.RoughnessTexture != undefined then
(
RoughnessTexture = sgsdk_CreateShadingTextureNode("RoughnessTexture");
sgsdk_AddAttributeToNode DirectXShader "RoughnessTexturemapChannel" 3
sgsdk_ConnectNodeToChannel RoughnessTexture DirectXShader "Roughness"
sgsdk_ConnectOutputToDirectXMaterial effectFile "Roughness" "RoughnessTexture"
)
-- metallic channel
if mat.MetalnessTexture != undefined then
(
MetalnessTexture = sgsdk_CreateShadingTextureNode("MetalnessTexture");
sgsdk_AddAttributeToNode DirectXShader "MetalnessTexturemapChannel" 3
sgsdk_ConnectNodeToChannel MetalnessTexture DirectXShader "Metalness"
sgsdk_ConnectOutputToDirectXMaterial effectFile "Metalness" "MetalnessTexture"
)
-- normals channel
if mat.NormalTexture != undefined then
(
NormalsTexture = sgsdk_CreateShadingTextureNode("NormalTexture");
sgsdk_AddAttributeToNode DirectXShader "NormalsTexturemapChannel" 3
sgsdk_SetSRGB NormalsTexture false
sgsdk_ConnectNodeToChannel NormalsTexture DirectXShader "Normals"
sgsdk_ConnectOutputToDirectXMaterial effectFile "Normals" "NormalTexture"
)
)
-- start Simplygon (can be done in batch mode, no gui)
sgsdk_RunPipelineOnSelection reductionPipelineWithMaterialBaking
-- get list with processed meshes
processedMeshes = sgsdk_GetProcessedMeshes() -- not necessarily in order!!!
-- use mapping information to map cube map to the shaders cube map slot
print ("Simplygon material mapping information:")
-- for all processed meshes
for mesh in processedMeshes do
(
-- get material by querying Simplygon plug-in
material = sgsdk_GetMaterialForMesh mesh
print ("\tMesh: " + mesh)
-- get reuse material (if any)
reuseMaterial = sgsdk_GetMeshReusesMaterial mesh
if reuseMaterial != "" then
(
print ("\t\tReusing material: " + reuseMaterial)
)
else
(
print ("\t\tMaterial: " + material)
)
-- fetch all channels for the material
channels = sgsdk_GetChannelsForMaterial material
for channel in channels do
(
print ("\t\t\tChannel: " + channel)
-- fetch texture path for each channel
texture = sgsdk_GetTexturePathForChannel material channel
print ("\t\t\t\tTexture: " + texture)
mappingChannel = sgsdk_GetMappingChannelForChannel material channel
print ("\t\t\t\tMappingChannel: " + mappingChannel as string)
)
-- look for a matching material in the scene
print ("\n\t\tLooking for matching material in scene...")
for mat in scenematerials do
(
-- if material was found
if material == mat.name do
(
-- get the material properties
props = getPropNames mat
for i = 1 to props.count do
(
prop = getProperty mat props[i]
--print ("\t\t\t." + props[i] + ": " + prop as string + "")
-- if it contains a "technique"
if (props[i] as string) == "technique" do
(
techniqueName = mat.getCurrentTechniqueName()
--print ("\t\t\t." + props[i] + "Name: " + techniqueName as string + "")
-- see if it is our shader by looking at the string
if techniqueName == "dx11|PBR_11" do
(
print ("\t\tSimplygon shader found!")
print ("\t\t\tLinking cube map...")
-- if no cube map is set, set it
if mat.CubemapTexture == undefined then
(
mat.CubemapTexture = openBitMap cubeMapPath
print ("\t\t\tDone!")
)
else
(
print ("\t\t\tAlready set, ignoring...")
)
)
)
)
)
)
)