[Serializable]
[Title("Master/Remapper")]
public class RemapMasterNode : AbstractMasterNode
, IGeneratesBodyCode
, IGeneratesFunction
, IMayRequireNormal
, IMayRequireTangent
, IMayRequireBitangent
, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequireWorldPosition
, IMayRequireVertexColor
{
[SerializeField]
private string m_SerialziedRemapGraph = string . Empty ;
return string . Empty ;
}
// Step 1: Generate properties from this node
// remap graphs are not allowed to have subgraphs
// or property nodes, so this is okay :)
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this ) ;
foreach ( var node in activeNodeList . OfType < AbstractMaterialNode > ( ) )
node . GeneratePropertyBlock ( shaderPropertiesVisitor , mode ) ;
// Step 2: Set this node as the remap target
var subShaders = remapAsset . masterRemapGraph . GetSubShadersFor ( this , mode ) ;
// Step 1: Set this node as the remap target
// Pass in the shader properties visitor here as
// high level properties are shared
// this is only used for the header
var subShaders = remapAsset . masterRemapGraph . GetSubShadersFor ( this , mode , shaderPropertiesVisitor ) ;
resultShader = resultShader . Replace ( "${SubShader}" , subShaders . Aggregate ( ( i , j ) = > i + Environment . NewLine + j ) ) ;
if ( subShaders ! = null )
resultShader = resultShader . Replace ( "${SubShader}" , subShaders . Aggregate ( string . Empty , ( i , j ) = > i + Environment . NewLine + j ) ) ;
else
resultShader = resultShader . Replace ( "${SubShader}" , string . Empty ) ;
public override string GetSubShader ( GenerationMode mode )
public override string GetSubShader ( GenerationMode mode , PropertyGenerator shaderPropertiesVisitor )
}
public override void CollectPreviewMaterialProperties ( List < PreviewProperty > properties )
{
base . CollectPreviewMaterialProperties ( properties ) ;
if ( remapAsset = = null )
return ;
remapAsset . masterRemapGraph . CollectPreviewMaterialProperties ( properties ) ;
}
#if UNITY_EDITOR
#else
public MaterialSubGraphAsset subGraphAsset { get ; set ; }
#endif
private MasterRemapGraph masterRemapGraph
{
get
{
if ( remapAsset = = null )
return null ;
return remapAsset . masterRemapGraph ;
}
}
public override PreviewMode previewMode
{
validNames . Add ( slot . id ) ;
}
RemoveSlotsNameNotMatching ( validNames ) ;
}
public void GenerateNodeCode ( ShaderGenerator shaderBody , GenerationMode generationMode )
{
var nodes = ListPool < INode > . Get ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( nodes , this , null , NodeUtils . IncludeSelf . Exclude ) ;
for ( var i = 0 ; i < nodes . Count ; i + + )
{
var node = nodes [ i ] ;
if ( node is IGeneratesBodyCode )
( node as IGeneratesBodyCode ) . GenerateNodeCode ( shaderBody , generationMode ) ;
}
ListPool < INode > . Release ( nodes ) ;
if ( remapAsset = = null )
return ;
var inputNode = remapAsset . masterRemapGraph . inputNode ;
foreach ( var mappedSlot in inputNode . GetOutputSlots < MaterialSlot > ( ) )
{
var edge = owner . GetEdges ( new SlotReference ( guid , mappedSlot . id ) ) . FirstOrDefault ( ) ;
if ( edge ! = null )
{
var outputRef = edge . outputSlot ;
var fromNode = owner . GetNodeFromGuid < AbstractMaterialNode > ( outputRef . nodeGuid ) ;
if ( fromNode = = null )
continue ;
shaderBody . AddShaderChunk ( "float4 " + inputNode . GetVariableNameForSlot ( mappedSlot . id ) + " = " + fromNode . GetVariableNameForSlot ( outputRef . slotId ) + ";" , true ) ;
}
else
{
shaderBody . AddShaderChunk ( "float4 " + inputNode . GetVariableNameForSlot ( mappedSlot . id ) + " = " + inputNode . FindSlot < MaterialSlot > ( mappedSlot . id ) . GetDefaultValue ( GenerationMode . ForReals ) + ";" , true ) ;
}
}
}
public override void GeneratePropertyBlock ( PropertyGenerator visitor , GenerationMode generationMode )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
foreach ( var node in activeNodeList . OfType < IGenerateProperties > ( ) )
node . GeneratePropertyBlock ( visitor , generationMode ) ;
}
public override void GeneratePropertyUsages ( ShaderGenerator visitor , GenerationMode generationMode )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
foreach ( var node in activeNodeList . OfType < IGenerateProperties > ( ) )
node . GeneratePropertyUsages ( visitor , generationMode ) ;
}
public void GenerateNodeFunction ( ShaderGenerator visitor , GenerationMode generationMode )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
foreach ( var node in activeNodeList . OfType < IGeneratesFunction > ( ) )
node . GenerateNodeFunction ( visitor , generationMode ) ;
}
public bool RequiresNormal ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireNormal > ( ) . Any ( x = > x . RequiresNormal ( ) ) ;
}
public bool RequiresTangent ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireTangent > ( ) . Any ( x = > x . RequiresTangent ( ) ) ;
}
public bool RequiresBitangent ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireBitangent > ( ) . Any ( x = > x . RequiresBitangent ( ) ) ;
}
public bool RequiresMeshUV ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireMeshUV > ( ) . Any ( x = > x . RequiresMeshUV ( ) ) ;
}
public bool RequiresScreenPosition ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireScreenPosition > ( ) . Any ( x = > x . RequiresScreenPosition ( ) ) ;
}
public bool RequiresViewDirection ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireViewDirection > ( ) . Any ( x = > x . RequiresViewDirection ( ) ) ;
}
public bool RequiresWorldPosition ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireWorldPosition > ( ) . Any ( x = > x . RequiresWorldPosition ( ) ) ;
}
public bool RequiresVertexColor ( )
{
var activeNodeList = new List < INode > ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( activeNodeList , this , null , NodeUtils . IncludeSelf . Exclude ) ;
return activeNodeList . OfType < IMayRequireVertexColor > ( ) . Any ( x = > x . RequiresVertexColor ( ) ) ;
}
}
}