## Material.AddSharedTextureLayer

### Introduced

v4.0

### Description

Adds an existing texture layer to the container. The layer already belongs to at least one other texture layer container (either Shader or Material).
A texture layer is an object which simplifies layering of texture effects on top of shaders and materials. Each layer has a set of properties which describe its characteristics (such as color, mixing mode, weight) to specify how it will affect the shader ports it drives. The order that layers appear under a container indicates the order the layering is applied, similar to the way a "mix N colors" shader node works. Texture layer port objects (see TextureLayer.AddTextureLayerPort) are owned by layers, and are used to specify which shader ports the layer should affect.
A Shader can also be a texture layer container, and has the same set of related methods.

### C# Syntax

    Material.AddSharedTextureLayer( Object in_varLayerToAdd, Boolean in_bAfter, Object in_varRefLayer );

### Scripting Syntax

    Material.AddSharedTextureLayer( Layer, [After], [Reference] );

### Parameters

Parameter | Type | Description
--- | --- | ---
Layer | TextureLayer or String | Texture layer to add to this container.
After | Boolean | True to insert the new texture layer after the reference layer. False to insert it before. If no reference layer, then True will add at the end of the container's list, False will add it at the start. Default Value: True
Reference | TextureLayer or String | Reference texture layer, to indicate where the newly-added layer should be located in the stack. The layer will be inserted adjacent to (before or after) the reference layer. If not specified, then the new layer will be added at the beginning or the end, depending on the value of the following argument.

### Examples

#### 1. JScript Example

    /*

    	This example shows how to create and share texture layers.

    	It also shows how both Shaders and Materials can be texture

    	layer containers, and the same layer can drive ports on

    	each of them (if desired).

    */

    oRoot = ActiveProject.ActiveScene.Root;

    oSph = oRoot.AddGeometry( "Sphere", "MeshSurface" );

    oMat = oSph.AddMaterial( "Phong" );

    oPhong = oMat.Shaders(0);

    // Add a layer to the Phong.

    oShared = oPhong.CreateTextureLayer( "SharedLayer" );

    // Add an unshared layer to the Material.

    oRough = oMat.CreateTextureLayer( "Rough" );

    // Add the first layer to the material, thereby sharing it.

    // We'll put it before the Rough layer.

    oMat.AddSharedTextureLayer( oShared, false, oRough );

    // Now for fun, let's create a Fractal, attach it to the

    // color input of the shared layer, and make it drive

    // both the Phong's diffuse and the Material's displacement.

    oParam = Application.Dictionary.GetObject( oShared + ".color" );

    oFractal = oParam.ConnectFromPreset( "Fractal", siTextureShaderFamily );

    oDiffuse = oShared.AddTextureLayerPort( oPhong.Parameters( "diffuse" ) );

    oDispl = oShared.AddTextureLayerPort( oMat.Parameters( "displacement" ) );

    // Now let's explore what we have created...

    DumpTextureLayerContainer( oMat );

    function DumpTextureLayerContainer( in_cont )

    {

    	Application.LogMessage( "CONTAINER: " + in_cont.Name );

    	for ( var i = 0; i < in_cont.TextureLayers.Count; i++ )

    	{

    		oTextureLayer = in_cont.TextureLayers(i);

    		DumpTextureLayer( oTextureLayer, i+1 );

    	}

    }

    function DumpTextureLayer( in_layer, in_index )

    {

    	Application.LogMessage( "   Layer " + in_index + ": " + in_layer.Name );

    	oColorSrc = in_layer.color.source;

    	var empty;

    	if ( oColorSrc == empty )

    	{

    		Application.LogMessage( "     Color: (" + in_layer.Red.Value +

    						"," + in_layer.Green.Value +

    						"," + in_layer.Blue.Value + ")" );

    	}

    	else

    	{

    		Application.LogMessage( "     Color driven by: " + oColorSrc.Name );

    	}

    	oPorts = in_layer.TextureLayerPorts;

    	count = oPorts.Count;

    	Application.LogMessage( "     Layer drives:" );

    	if ( count == 0 )

    		Application.LogMessage( "       <nothing>" );

    	else

    	{

    		for ( i = 0; i < count; i++ )

    		{

    			Application.LogMessage( "       " + oPorts(i).Target.FullName );

    		}

    	}

    }

    // This example should log something like:

    //INFO : "CONTAINER: Material"

    //INFO : "   Layer 1: SharedLayer"

    //INFO : "     Color driven by: Fractal"

    //INFO : "     Layer drives:"

    //INFO : "       sphere.Material.Phong.diffuse"

    //INFO : "       sphere.Material.Color2scalar.input"

    //INFO : "   Layer 2: Rough"

    //INFO : "     Color: (0.7,0.7,0.7)"

    //INFO : "     Layer drives:"

    //INFO : "       <nothing>"

#### 2. VBScript Example

    '

    ' This example shows how to create and share texture layers.

    ' It also shows how both Shaders and Materials can be texture

    ' layer containers, and the same layer can drive ports on each

    ' of them (if desired).

    '

    set oRoot = ActiveProject.ActiveScene.Root

    set oSph = oRoot.AddGeometry( "Sphere", "MeshSurface" )

    set oMat = oSph.AddMaterial( "Phong" )

    set oPhong = oMat.Shaders(0)

    ' Add a layer to the Phong.

    set oShared = oPhong.CreateTextureLayer( "SharedLayer" )

    ' Add an unshared layer to the Material.

    set oRough = oMat.CreateTextureLayer( "Rough" )

    ' Add the first layer to the material, thereby sharing it.

    ' We'll put it before the Rough layer.

    oMat.AddSharedTextureLayer oShared, False, oRough

    ' Now for fun, let's create a Fractal, attach it to the

    ' color input of the shared layer, and make it drive

    ' both the Phong's diffuse and the Material's displacement.

    set oParam = Dictionary.GetObject( oShared & ".color" )

    set oFractal = oParam.ConnectFromPreset( "Fractal", siTextureShaderFamily )

    set oDiffuse = oShared.AddTextureLayerPort( oPhong.Parameters( "diffuse" ) )

    set oDispl = oShared.AddTextureLayerPort( oMat.Parameters( "displacement" ) )

    ' Now let's explore what we have created...

    DumpTextureLayerContainer oMat

    sub DumpTextureLayerContainer( in_cont )

    	Application.LogMessage "CONTAINER: " & in_cont.Name

    	i = 1

    	for each oTextureLayer in in_cont.TextureLayers

    		DumpTextureLayer oTextureLayer, i

    		i = i + 1

    	next

    end sub

    sub DumpTextureLayer( in_layer, in_index )

    	Application.LogMessage "   Layer " & in_index & ": " & in_layer.Name

    	set oColorSrc = in_layer.color.source

    	if TypeName( oColorSrc ) = "Nothing" then

    		Application.LogMessage "     Color: (" & in_layer.Red.Value & _

    						"," & in_layer.Green.Value & _

    						"," & in_layer.Blue.Value & ")"

    	else

    		Application.LogMessage "     Color driven by: " & oColorSrc.Name

    	end if

    	set oPorts = in_layer.TextureLayerPorts

    	count = oPorts.Count

    	if count = 0 then

    		Application.LogMessage "     <layer driving no ports>"

    	else

    		Application.LogMessage "     Layer drives:"

    		for i = 0 to count - 1

    			Application.LogMessage "       " & oPorts(i).Target.FullName

    		next

    	end if

    end sub

    ' This example should log something like:

    'INFO : "CONTAINER: Material"

    'INFO : "   Layer 1: SharedLayer"

    'INFO : "     Color driven by: Fractal"

    'INFO : "     Layer drives:"

    'INFO : "       sphere.Material.Phong.diffuse"

    'INFO : "       sphere.Material.Color2scalar.input"

    'INFO : "   Layer 2: Rough"

    'INFO : "     Color: (0.7,0.7,0.7)"

    'INFO : "     <layer driving no ports>"

### See Also

AddTextureLayer Material.CreateTextureLayer Shader.CreateTextureLayer Shader.AddSharedTextureLayer