Skip to content
On this page

Mapping of DirectX (HLSL) materials

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
    reductionPipelineWithBaking = "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 texture
        DiffuseTexture = sgsdk_CreateShadingTextureNode("DiffuseTexture");
        sgsdk_AddAttributeToNode DirectXShader "DiffuseTexturemapChannel" 3

        -- specular texture
        SpecularTexture = sgsdk_CreateShadingTextureNode("SpecularTexture");
        sgsdk_AddAttributeToNode DirectXShader "SpecularTexturemapChannel" 3

        -- roughness texture
        RoughnessTexture = sgsdk_CreateShadingTextureNode("RoughnessTexture");
        sgsdk_AddAttributeToNode DirectXShader "RoughnessTexturemapChannel" 3

        -- metallic texture
        MetalnessTexture = sgsdk_CreateShadingTextureNode("MetalnessTexture");
        sgsdk_AddAttributeToNode DirectXShader "MetalnessTexturemapChannel" 3

        -- normals texture
        NormalsTexture = sgsdk_CreateShadingTextureNode("NormalTexture");
        sgsdk_AddAttributeToNode DirectXShader "NormalsTexturemapChannel" 3
        sgsdk_SetSRGB NormalsTexture false

        -- connect shading network to Simplygon channel
        sgsdk_ConnectNodeToChannel DiffuseTexture DirectXShader "Diffuse"
        sgsdk_ConnectNodeToChannel SpecularTexture DirectXShader "Specular"
        sgsdk_ConnectNodeToChannel RoughnessTexture DirectXShader "Roughness"
        sgsdk_ConnectNodeToChannel MetalnessTexture DirectXShader "Metalness"
        sgsdk_ConnectNodeToChannel NormalsTexture DirectXShader "Normals"

        -- map back texture on diffuse channel to Diffuse1 in HLSL shader
        sgsdk_ConnectOutputToDirectXMaterial effectFile "Diffuse" "DiffuseTexture"
        sgsdk_ConnectOutputToDirectXMaterial effectFile "Specular" "SpecularTexture"
        sgsdk_ConnectOutputToDirectXMaterial effectFile "Roughness" "RoughnessTexture"
        sgsdk_ConnectOutputToDirectXMaterial effectFile "Metalness" "MetalnessTexture"
        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...")
                            )
                        )
                    )
                )
            )
        )
    )