Material Instances

From HEWIKI
(Difference between revisions)
Jump to: navigation, search
(Serialization Format)
(What types of assets support Material Instances?)
 
(55 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
== Overview  ==
 
== Overview  ==
  
HeroEngine's Material Instancing System allows dynamic runtime modifications to the visual appearance of a model by changing the material of a specific instance to use a new texture, shader or material properties (bump, spec, etc). Material instancing is a huge win in games allowing the reuse of a model by making simple switches of the texture for variety. For example, an artist might have created the model of a red brick wall; using material instancing the polygons of the model can be reused but the texture can be switched to that of a stone wall.
+
HeroEngine's Material Instancing System allows dynamic runtime modifications to the visual appearance of a model by changing the material of a specific instance to use a new texture, shader or material properties (bump, spec, etc). Material instancing is a huge win in games allowing the reuse of a model by making simple switches of the texture for variety. For example, an artist might have created the model of a red brick wall; using material instancing the polygons of the model can be reused but the texture can be switched to that of a stone wall.  
  
 
Not only does material instancing support dynamic runtime modifications, but it can also be used as a normal part of the area editing process creating a persistent change. The system provides support to changing the features associated with one or more materials associated with an object and updating their properties. There are multiple options on the UI which can be selected for editing and viewed at runtime before saving to the server.  
 
Not only does material instancing support dynamic runtime modifications, but it can also be used as a normal part of the area editing process creating a persistent change. The system provides support to changing the features associated with one or more materials associated with an object and updating their properties. There are multiple options on the UI which can be selected for editing and viewed at runtime before saving to the server.  
Line 9: Line 9:
 
The system also makes it easy to create assets, change their material properties, save them to the asset library and reuse them in any desired area. Without material instancing, if the project required multiple stone walls an artist would have to create individual models for each with their unique texture mapping and use them at the appropriate places. Whereas material instancing saves the efforts of recreating similar materials and allows editing individual properties for the materials. For example, there can be a material named “Material_1” which has a specular map. Selecting the same material, we can update it to undo the specular map such that there will be a new material, say, “Material_2” on the server which will have all the properties similar to that of “Material_1” but won’t have the specular map.  
 
The system also makes it easy to create assets, change their material properties, save them to the asset library and reuse them in any desired area. Without material instancing, if the project required multiple stone walls an artist would have to create individual models for each with their unique texture mapping and use them at the appropriate places. Whereas material instancing saves the efforts of recreating similar materials and allows editing individual properties for the materials. For example, there can be a material named “Material_1” which has a specular map. Selecting the same material, we can update it to undo the specular map such that there will be a new material, say, “Material_2” on the server which will have all the properties similar to that of “Material_1” but won’t have the specular map.  
  
This allows editing the appearance of a model at runtime and making multiple materials which can be used for different objects in an area.
+
This allows editing the appearance of a model at runtime and making multiple materials which can be used for different objects in an area.  
  
 
== Terminology  ==
 
== Terminology  ==
  
; [[Asset]] : is a template from which things in the game world are made. An asset instance is an object with a unique ID number, created from an asset. Areas are mainly populated with asset instances instantiated from the [[Asset Library]]. Assets own meshes.
+
;[[Asset]] 
 +
:a template from which things in the game world are made. An asset instance is an object with a unique ID number, created from an asset. Areas are mainly populated with asset instances instantiated from the [[Asset Library]]. Assets own meshes
  
; [[Model|Mesh]] : is a single set of geometry, and a reference to the material which it uses. There may be multiple meshes in a model -- for example, a barrel of apples may consist of a mesh for the wooden barrel and a mesh for the pile of apples.
+
;[[Instance]] 
 +
:a unique instantiation of an asset with its own set of mutable properties that may be modified through the [[Properties panel]] or script interfaces. Complex properties such as material instances use [[Material Instance Properties|specialized property editors]] and serialize their data using a specialized [[Parameter syntax]]
  
; [[Material]] : is a set of textures with defined roles (such as diffuse, normal/specular and macro) and associated properties. A material instance a unique combination of material properties which can be applied to one or more asset meshes. Material Instance Properties can be customized using the [[Material Instance Properties]] dialogue.
+
;[[Model|Mesh]] 
 +
:a single set of geometry, and a reference to the material which it uses. There may be multiple meshes in a model -- for example, a barrel of apples may consist of a mesh for the wooden barrel and a mesh for the pile of apples.
  
== Serialization Format  ==
+
;[[Material]] 
 +
:a set of textures with defined roles (such as diffuse, normal/specular and macro) and associated properties. A material instance a unique combination of material properties which can be applied to one or more asset meshes. Material Instance Properties can be customized using the [[Material Instance Properties]] dialogue.
  
Changes made through the Material Instance Properties dialogue are represented in a serialized override string. Values which differ from the base material will appear in the string within the _MaterialOverrides property field in the [[Properties Panel]].
+
== What types of assets support Material Instances? ==
  
The serialization format is as follows.
+
Material Instancing is supported on Models (.hgm files) that are a part of the area or instantiated through [[Prop buckets]].  Characters and dynamic character parts do not support Material Instancing because they are part of a much more complicated set of systems which support advanced features like dynamic texture banks, palettes and tinting layers.
  
<code>&lt;serialization format version number&gt;&nbsp;% &lt;instance name&gt; # &lt;hash string for this material instance&gt; [ &lt;diffuse map path&gt;,&lt;diffuse map alpha type&gt;,&lt;normal map path&gt;,&lt;normal map contains specular channel&gt;,&lt;macro map path&gt;,&lt;macro map UV multiplier&gt;,&lt;shader map path&gt;,&lt;shader translucency&gt;,&lt;shader reflectivity&gt;,&lt;texture address mode U&gt;,&lt;texture address mode V&gt;,&lt;polygon attributes&gt;,&lt;animated UVs U1&gt;,&lt;animated UVs V1&gt;,&lt;animated UVs U2&gt;,&lt;animated UVs V2&gt;] </code>
+
== Usage  ==
 
+
[[Image:MaterialInstancesPropertiesDiloagueButton.png|right|200px|MaterialInstancesPropertiesDiloagueButton.png]]  
 
+
=== Use Material Instance Property Editor to Specify a Different Texture ===
Here is an example of a material override string after changing the diffuse map path. Note that some values are empty and others contain default enumerations which are set by the system.
+
 
+
 
+
<code>0%mushroom_demo6#82b311bfb05255ae1e9822a0c49b3aab[/techart/hill/grannyexport/textures/orange_utility.dds,1,,,,1,,0,0,1,1,1,0,0,0,0]</code>
+
 
+
 
+
[[Image:MaterialInstancePropertiesDialogueExample.png|center|MaterialInstancePropertiesDialogueExample.png]]
+
 
+
== An Example ==
+
  
 
#Log into any test area where changes won't be persisted (any play instance).  
 
#Log into any test area where changes won't be persisted (any play instance).  
Line 48: Line 43:
 
Additional information about the dialogue and other customization options can be found on the [[Material Instance Properties]] wiki page.  
 
Additional information about the dialogue and other customization options can be found on the [[Material Instance Properties]] wiki page.  
  
== HSL External Functions ==
+
=== Creating a Prefab Using Material Instances ===
  
There are several external functions available through [[HSL]] script.  
+
[[Image:MaterialInstancesWhiteBoxTutorial.png|right|700px|MaterialInstancesWhiteBoxTutorial.png]]
 +
 
 +
#Open the [[Properties Panel]]
 +
#Using the [[Whitebox Layout Tools]] [[Image:WhiteboxLayoutToolsButton.png]] UI, drop a couple asset primitives into the area.&nbsp;
 +
#Select one of the asset instances and navigate to the _MaterialOverrides value box in the [[Properties Panel]] and press the "..." button on the right side. The Material Instance Properties dialogue will appear.
 +
#Under "Diffuse/Alpha Map", press the button marked "whiteboxing_default_d.dds". This will bring up a selection dialogue for a new diffuse map. Select any .dds file and press "OK".
 +
#The material instance applied to the asset instance will update to include the new diffuse map. These changes are immediate and do not need to be committed. Press "Close" to keep the changes or "Reset to Default" to undo them.
 +
#Make sure the asset instance remains select and click "Create" / "Library" to open the [[Asset Library]].
 +
#Navigate to a suitable library tab and right-click within the icon area. Select "Grab Selected"<br>
 +
#Name the asset something unique. You can optionally take a thumbnail capture of the item by right-clicking on the newly created thumbnail and selecting "Icon" / "Snapshot..."
 +
#Close the window. You will be prompted to the changes to the library. Click "Yes" to commit your work.
 +
#From the same library tab, you can now drop in this new asset in any area with modified material instances already saved on the asset spec.&nbsp;
 +
 
 +
<br>
 +
 
 +
<br>
 +
 
 +
== Advanced Usage  ==
 +
 
 +
=== Script Interface (HSL External Functions)  ===
 +
 
 +
There are several external functions exposed to [[HSL]] that can be used to manipulate the material instance properties for an [[Instance]] (only [[HBNodes|renderable instances]] have properties).  
  
 
<hsl>external function EnumerateMaterialInstanceProperties() as List of String</hsl>  
 
<hsl>external function EnumerateMaterialInstanceProperties() as List of String</hsl>  
  
This function will return the following list of strings which can be use as the "property_name" parameter in the next two functions.
+
This function will return the following list of strings which can be use as the "property_name" parameter in the next two functions. <br>[1] "DiffuseMap" <br>[2] "DiffuseMapAlphaType" <br>[3] "NormalMap" <br>[4] "HasSpecular" <br>[5] "MacroMap" <br>[6] "MacroMapUVMultiplier" <br>[7] "ShaderProperties" <br>[8] "Translucency" <br>[9] "Reflectivity" <br>[10] "TextureAddressMode" <br>[11] "AddressU" <br>[12] "AddressV" <br>[13] "AnimatedU1" <br>[14] "AnimatedV1" <br>[15] "AnimatedU2" <br>[16] "AnimatedV2"  
<br>[1] "DiffuseMap" <br>[2] "DiffuseMapAlphaType" <br>[3] "NormalMap" <br>[4] "HasSpecular" <br>[5] "MacroMap" <br>[6] "MacroMapUVMultiplier" <br>[7] "ShaderProperties" <br>[8] "Translucency" <br>[9] "Reflectivity" <br>[10] "TextureAddressMode" <br>[11] "AddressU" <br>[12] "AddressV" <br>[13] "AnimatedU1" <br>[14] "AnimatedV1" <br>[15] "AnimatedU2" <br>[16] "AnimatedV2"  
+
 
 +
<hsl>external function GetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String ) as String</hsl> Retrieves the value of the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.
 +
 
 +
<hsl>external function SetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String, new_value as String )</hsl> Applies the value to the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.
 +
 
 +
<hsl>external function ListNodeMaterials(model as NodeRef of Class HBNode) as List of String</hsl> Returns a list of serialized override strings which represents the collection of material overrides applied to a given asset instance. This is the same string which will be located in the Properties Panel under the _MaterialOverries field for any selected asset instance.
 +
 
 +
==== Using the Script Interface to Switch to a Different Texture  ====
 +
 
 +
This is a simple tutorial on how to use the script interface for modifying the material instance properties of an asset.
 +
 
 +
This tutorial assumes that you have completed the tutorial [[Your First HSL Script]] as well as read the page [[DOM Editor]]. If you have not, please do so before continuing.
 +
 
 +
'''1.''' Use the [[DOM Editor]] to create a new client class. Give the class a unique name so it does not conflict with anything which already exists in the DOM. From this step onward, replace the text "YourClassName" with the name you choose for your class.
 +
 
 +
'''2.''' Open the script for your newly created class and paste the following HSL code into it. Remember to change "YourClassName" with the name of the class you created in step 1.
 +
 
 +
<hsl>
 +
//This function creates the propbucket and adds the asset spec to that propbucket.
 +
//Adding the spec to the prop bucket is an asynchronous procedure which requires a separate callback method.
 +
//The nateNoderef noderef is an instance of this class which will respond to the callback AssetSpecReady()
 +
function CreateAssetPropBucket()
 +
  CreatePropBucket( "MATERIALINSTANCESTEST" )
 +
  cubeFQN as String = "\engine\cleangame\resources\whiteboxes\cube.hgm"
 +
  yourClassNameNodeRef as NodeRef of Class YourClassName = CreateNodeFromClass("YourClassName")
 +
  spec as NodeRef of Class HBSpec = AddAssetSpecToPropBucketCB( "MATERIALINSTANCESTEST", cubeFQN, yourClassNameNodeRef )
 +
.
 +
 
 +
//Asynchronous callback resulting from calling the external function AddAssetSpecToPropBucketCB()
 +
method AssetSpecReady(spec as NodeRef of Class HBSpec, loadFailed as Boolean)
 +
  if loadFailed
 +
    return
 +
  .
 +
 
 +
  //Instance the HBNodes from the prop bucket
 +
  cubeA as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
 +
  cubeB as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
 +
  defaultcube as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
 +
 
 +
  //Set the HBNode positions to the left and right of the player character
 +
  //A default cube will be placed in front of the character for reference. It will not be modified.
 +
  playerPosition as Vector3   
 +
  GetNodePosition(SYSTEM.INFO.PLAYERCHARACTER, playerPosition)
 +
 
 +
  cubeAPosition as Vector3 = playerPosition + (0.3,0,0)
 +
  cubeBPosition as Vector3 = playerPosition - (0.3,0,0)
 +
  defaultcubePosition as Vector3 = playerPosition + (0,0,-0.3)
 +
     
 +
  SetNodePosition( cubeA, cubeAPosition)
 +
  SetNodePosition( cubeB, cubeBPosition)
 +
  SetNodePosition( defaultcube, defaultcubePosition)
 +
 
 +
  //make the HBNodes renderable
 +
  ActivateInstance( cubeA, "")
 +
  ActivateInstance( cubeB, "")
 +
  ActivateInstance( defaultcube, "")
 +
 
 +
  //print all the material properties available
 +
  materialParameterNames as List of String = EnumerateMaterialInstanceProperties()
 +
  loop i from 1 to materialParameterNames.length
 +
    println("Property[" + i + "] = $Q" + materialParameterNames[i] + "$Q")
 +
  .
 +
 
 +
  //list the materials names which currently exist on the HBNode
 +
  materialsOnNode as List of String = ListNodeMaterials(defaultcube)
 +
  println(materialsOnNode.length + " material(s) found on HBNode")
 +
  loop i from 1 to materialsOnNode.length
 +
    println("[" + i + "] " + materialsOnNode[i])
 +
  .
 +
 
 +
  //GetMaterialInstanceValue() gets a specific material instance property
 +
  //At this point, the diffuse maps should be set to their default values
 +
  diffusePathA as String = GetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1])
 +
  diffusePathB as String = GetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1])
 +
 
 +
  //print the default diffuse map paths
 +
  println("cubeA(" + cubeA + ") default diffuse map path = " + diffusePathA)
 +
  println("cubeB(" + cubeB + ") default diffuse map path = " + diffusePathB)
 +
     
 +
  //SetMaterialInstanceValue() sets a specific material instance property
 +
  //These two operations set the diffuse maps of the left and right cubes to different textures from their defaults
 +
  SetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1], "\Engine\CleanGame\Resources\Common\Textures\wagon1.dds")
 +
  SetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1], "\Engine\CleanGame\Resources\Common\Textures\checkered01.dds")
 +
 
 +
  //Get the new diffuse map paths from the HBNodes
 +
  diffusePathA = GetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1])
 +
  diffusePathB = GetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1])
 +
 
 +
  //print the new diffuse map paths
 +
  println("cubeA(" + cubeA + ") new diffuse map path = " + diffusePathA)
 +
  println("cubeB(" + cubeB + ") new diffuse map path = " + diffusePathB)
 +
 
 +
 
 +
.
 +
</hsl> [[Image:MaterialInstancePropertiesExternalFunctionsTutorial.png|right|MaterialInstancePropertiesExternalFunctionsTutorial.png]]
 +
 
 +
'''3.''' Open the console window and type the following command, again replacing "YourClassName" with the name of the class which you created. Then press enter.
 +
 
 +
<code>call YourClassNameClassMethods CreateAssetPropBucket</code>
 +
 
 +
'''4.''' Three cubes should appear before the player character in the viewport. The center cube will retain its default material set as no overrides were applied to it. The two on either side of the character display different diffuse maps, specified by the new paths set by SetMaterialInstanceValue()
 +
 
 +
'''5.''' Additional information should also be output to the console which includes the default and new paths for the diffuse maps as well as the materials found on the HBNode and the material parameter names used in setting or retrieving material instance parameter values.
 +
 
 +
=== Serialization Format  ===
  
<hsl>external function GetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String ) as String</hsl>
+
Material Instances for an asset instance are represented in a serialization format in the [[Properties Panel]], in the _MaterialOverrides field. More can be found on the format in the [http://wiki.heroengine.com/wiki/Parameter_syntax#Material_Instance_Parameter Material Instance Parameter section] of the [[Parameter Syntax]] page.
Retrieves the value of the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.
+
  
<hsl>external function SetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String, new_value as String )</hsl>
+
== See Also  ==
Applies the value to the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.
+
  
<hsl>external function ListNodeMaterials(model as NodeRef of Class HBNode) as List of String</hsl>
+
*[[Material Instance Properties]]
Returns a list of serialized override strings which represents the collection of material overrides applied to a given asset instance. This is the same string which will be located in the Properties Panel under the _MaterialOverries field for any selected asset instance.
+
*[[Model]]
 +
*[[Texture Format]]
 +
*[[Parameter syntax]]

Latest revision as of 14:03, 15 November 2012

Contents

Overview

HeroEngine's Material Instancing System allows dynamic runtime modifications to the visual appearance of a model by changing the material of a specific instance to use a new texture, shader or material properties (bump, spec, etc). Material instancing is a huge win in games allowing the reuse of a model by making simple switches of the texture for variety. For example, an artist might have created the model of a red brick wall; using material instancing the polygons of the model can be reused but the texture can be switched to that of a stone wall.

Not only does material instancing support dynamic runtime modifications, but it can also be used as a normal part of the area editing process creating a persistent change. The system provides support to changing the features associated with one or more materials associated with an object and updating their properties. There are multiple options on the UI which can be selected for editing and viewed at runtime before saving to the server.

The system also makes it easy to create assets, change their material properties, save them to the asset library and reuse them in any desired area. Without material instancing, if the project required multiple stone walls an artist would have to create individual models for each with their unique texture mapping and use them at the appropriate places. Whereas material instancing saves the efforts of recreating similar materials and allows editing individual properties for the materials. For example, there can be a material named “Material_1” which has a specular map. Selecting the same material, we can update it to undo the specular map such that there will be a new material, say, “Material_2” on the server which will have all the properties similar to that of “Material_1” but won’t have the specular map.

This allows editing the appearance of a model at runtime and making multiple materials which can be used for different objects in an area.

Terminology

Asset 
a template from which things in the game world are made. An asset instance is an object with a unique ID number, created from an asset. Areas are mainly populated with asset instances instantiated from the Asset Library. Assets own meshes
Instance 
a unique instantiation of an asset with its own set of mutable properties that may be modified through the Properties panel or script interfaces. Complex properties such as material instances use specialized property editors and serialize their data using a specialized Parameter syntax
Mesh 
a single set of geometry, and a reference to the material which it uses. There may be multiple meshes in a model -- for example, a barrel of apples may consist of a mesh for the wooden barrel and a mesh for the pile of apples.
Material 
a set of textures with defined roles (such as diffuse, normal/specular and macro) and associated properties. A material instance a unique combination of material properties which can be applied to one or more asset meshes. Material Instance Properties can be customized using the Material Instance Properties dialogue.

What types of assets support Material Instances?

Material Instancing is supported on Models (.hgm files) that are a part of the area or instantiated through Prop buckets. Characters and dynamic character parts do not support Material Instancing because they are part of a much more complicated set of systems which support advanced features like dynamic texture banks, palettes and tinting layers.

Usage

MaterialInstancesPropertiesDiloagueButton.png

Use Material Instance Property Editor to Specify a Different Texture

  1. Log into any test area where changes won't be persisted (any play instance).
  2. Using the Asset Library, place two utility cubes in the area.
  3. Open the properties panel if it's not already visible.
  4. Select one of the cubes and navigate to the _MaterialOverrides property in the Properties Panel.
  5. Click on the empty space where the value for "_MaterialOverrides" would otherwise be. A "..." button will appear to the right. Click on that.
  6. The Material Instance Properties dialogue will appear. Click on the button with the diffuse map file name under "Diffuse/Alpha Map" and select any .dds file you like from the repository. The change you make will be immediately reflected in your viewport and to any other clients in your area instance.
  7. Press the close button and perform steps 4 - 6 on the other cube you placed in the area. Only, for the second cube, choose a different .dds file from the first. You'll notice that the two asset instances now have separate appearances due to their different material overrides.

Additional information about the dialogue and other customization options can be found on the Material Instance Properties wiki page.

Creating a Prefab Using Material Instances

MaterialInstancesWhiteBoxTutorial.png
  1. Open the Properties Panel
  2. Using the Whitebox Layout Tools WhiteboxLayoutToolsButton.png UI, drop a couple asset primitives into the area. 
  3. Select one of the asset instances and navigate to the _MaterialOverrides value box in the Properties Panel and press the "..." button on the right side. The Material Instance Properties dialogue will appear.
  4. Under "Diffuse/Alpha Map", press the button marked "whiteboxing_default_d.dds". This will bring up a selection dialogue for a new diffuse map. Select any .dds file and press "OK".
  5. The material instance applied to the asset instance will update to include the new diffuse map. These changes are immediate and do not need to be committed. Press "Close" to keep the changes or "Reset to Default" to undo them.
  6. Make sure the asset instance remains select and click "Create" / "Library" to open the Asset Library.
  7. Navigate to a suitable library tab and right-click within the icon area. Select "Grab Selected"
  8. Name the asset something unique. You can optionally take a thumbnail capture of the item by right-clicking on the newly created thumbnail and selecting "Icon" / "Snapshot..."
  9. Close the window. You will be prompted to the changes to the library. Click "Yes" to commit your work.
  10. From the same library tab, you can now drop in this new asset in any area with modified material instances already saved on the asset spec. 



Advanced Usage

Script Interface (HSL External Functions)

There are several external functions exposed to HSL that can be used to manipulate the material instance properties for an Instance (only renderable instances have properties).

external function EnumerateMaterialInstanceProperties() as List of String

This function will return the following list of strings which can be use as the "property_name" parameter in the next two functions.
[1] "DiffuseMap"
[2] "DiffuseMapAlphaType"
[3] "NormalMap"
[4] "HasSpecular"
[5] "MacroMap"
[6] "MacroMapUVMultiplier"
[7] "ShaderProperties"
[8] "Translucency"
[9] "Reflectivity"
[10] "TextureAddressMode"
[11] "AddressU"
[12] "AddressV"
[13] "AnimatedU1"
[14] "AnimatedV1"
[15] "AnimatedU2"
[16] "AnimatedV2"

external function GetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String ) as String
Retrieves the value of the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.

external function SetMaterialInstanceValue( model as NodeRef of Class HBNode, material_name as String, property_name as String, new_value as String )
Applies the value to the property corresponding to the given material instance name and the asset instance (model) to which it has been applied.

external function ListNodeMaterials(model as NodeRef of Class HBNode) as List of String
Returns a list of serialized override strings which represents the collection of material overrides applied to a given asset instance. This is the same string which will be located in the Properties Panel under the _MaterialOverries field for any selected asset instance.

Using the Script Interface to Switch to a Different Texture

This is a simple tutorial on how to use the script interface for modifying the material instance properties of an asset.

This tutorial assumes that you have completed the tutorial Your First HSL Script as well as read the page DOM Editor. If you have not, please do so before continuing.

1. Use the DOM Editor to create a new client class. Give the class a unique name so it does not conflict with anything which already exists in the DOM. From this step onward, replace the text "YourClassName" with the name you choose for your class.

2. Open the script for your newly created class and paste the following HSL code into it. Remember to change "YourClassName" with the name of the class you created in step 1.

//This function creates the propbucket and adds the asset spec to that propbucket.
//Adding the spec to the prop bucket is an asynchronous procedure which requires a separate callback method.
//The nateNoderef noderef is an instance of this class which will respond to the callback AssetSpecReady()
function CreateAssetPropBucket()
  CreatePropBucket( "MATERIALINSTANCESTEST" )
  cubeFQN as String = "\engine\cleangame\resources\whiteboxes\cube.hgm"
  yourClassNameNodeRef as NodeRef of Class YourClassName = CreateNodeFromClass("YourClassName")
  spec as NodeRef of Class HBSpec = AddAssetSpecToPropBucketCB( "MATERIALINSTANCESTEST", cubeFQN, yourClassNameNodeRef ) 
.
 
//Asynchronous callback resulting from calling the external function AddAssetSpecToPropBucketCB()
method AssetSpecReady(spec as NodeRef of Class HBSpec, loadFailed as Boolean)
  if loadFailed
    return
  .
 
  //Instance the HBNodes from the prop bucket
  cubeA as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
  cubeB as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
  defaultcube as NodeRef of Class HBNode = CreateInstanceFromPropBucket( "MATERIALINSTANCESTEST", spec )
 
  //Set the HBNode positions to the left and right of the player character
  //A default cube will be placed in front of the character for reference. It will not be modified.
  playerPosition as Vector3    
  GetNodePosition(SYSTEM.INFO.PLAYERCHARACTER, playerPosition)
 
  cubeAPosition as Vector3 = playerPosition + (0.3,0,0)
  cubeBPosition as Vector3 = playerPosition - (0.3,0,0)
  defaultcubePosition as Vector3 = playerPosition + (0,0,-0.3)
 
  SetNodePosition( cubeA, cubeAPosition)
  SetNodePosition( cubeB, cubeBPosition)
  SetNodePosition( defaultcube, defaultcubePosition)
 
  //make the HBNodes renderable
  ActivateInstance( cubeA, "")
  ActivateInstance( cubeB, "")
  ActivateInstance( defaultcube, "")
 
  //print all the material properties available
  materialParameterNames as List of String = EnumerateMaterialInstanceProperties()
  loop i from 1 to materialParameterNames.length
    println("Property[" + i + "] = $Q" + materialParameterNames[i] + "$Q")
  .
 
  //list the materials names which currently exist on the HBNode
  materialsOnNode as List of String = ListNodeMaterials(defaultcube)
  println(materialsOnNode.length + " material(s) found on HBNode")
  loop i from 1 to materialsOnNode.length
    println("[" + i + "] " + materialsOnNode[i])
  .
 
  //GetMaterialInstanceValue() gets a specific material instance property
  //At this point, the diffuse maps should be set to their default values
  diffusePathA as String = GetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1])
  diffusePathB as String = GetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1]) 
 
  //print the default diffuse map paths
  println("cubeA(" + cubeA + ") default diffuse map path = " + diffusePathA)
  println("cubeB(" + cubeB + ") default diffuse map path = " + diffusePathB)
 
  //SetMaterialInstanceValue() sets a specific material instance property
  //These two operations set the diffuse maps of the left and right cubes to different textures from their defaults
  SetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1], "\Engine\CleanGame\Resources\Common\Textures\wagon1.dds")
  SetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1], "\Engine\CleanGame\Resources\Common\Textures\checkered01.dds")
 
  //Get the new diffuse map paths from the HBNodes
  diffusePathA = GetMaterialInstanceValue(cubeA, materialsOnNode[1], materialParameterNames[1])
  diffusePathB = GetMaterialInstanceValue(cubeB, materialsOnNode[1], materialParameterNames[1]) 
 
  //print the new diffuse map paths
  println("cubeA(" + cubeA + ") new diffuse map path = " + diffusePathA)
  println("cubeB(" + cubeB + ") new diffuse map path = " + diffusePathB)
 
 
.
MaterialInstancePropertiesExternalFunctionsTutorial.png

3. Open the console window and type the following command, again replacing "YourClassName" with the name of the class which you created. Then press enter.

call YourClassNameClassMethods CreateAssetPropBucket

4. Three cubes should appear before the player character in the viewport. The center cube will retain its default material set as no overrides were applied to it. The two on either side of the character display different diffuse maps, specified by the new paths set by SetMaterialInstanceValue()

5. Additional information should also be output to the console which includes the default and new paths for the diffuse maps as well as the materials found on the HBNode and the material parameter names used in setting or retrieving material instance parameter values.

Serialization Format

Material Instances for an asset instance are represented in a serialization format in the Properties Panel, in the _MaterialOverrides field. More can be found on the format in the Material Instance Parameter section of the Parameter Syntax page.

See Also

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox