// Amplify Shader Editor - Visual Shader Editing Tool // Copyright (c) Amplify Creations, Lda using System; using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEngine; namespace AmplifyShaderEditor { [Serializable] public class TemplateSubShader { [SerializeField] private int m_idx = -1; [SerializeField] private List m_passes = new List(); [SerializeField] private TemplateModulesData m_modules; [SerializeField] private string m_uniquePrefix; [SerializeField] private TemplatePropertyContainer m_templateProperties = new TemplatePropertyContainer(); [SerializeField] private List m_availableShaderGlobals = new List(); [SerializeField] private TemplateInfoContainer m_LODContainer = new TemplateInfoContainer(); [SerializeField] private int m_passAmount = 0; [SerializeField] private int m_mainPass = -1; [SerializeField] private bool m_foundMainPassTag = false; [SerializeField] TemplateOptionsContainer m_customOptionsContainer = new TemplateOptionsContainer(); public TemplateSubShader(TemplateMultiPass template, int subShaderIx, TemplateIdManager idManager, string uniquePrefix, TemplateSubShaderInfo subShaderInfo, ref Dictionary duplicatesHelper ) { m_idx = subShaderIx; m_uniquePrefix = uniquePrefix; FetchLOD( subShaderInfo.StartIdx, subShaderInfo.Modules ); if( m_LODContainer.Index > -1 ) { idManager.RegisterId( m_LODContainer.Index, uniquePrefix + "Module" + m_LODContainer.Id, m_LODContainer.Id ); } m_customOptionsContainer = TemplateOptionsToolsHelper.GenerateOptionsContainer( true, subShaderInfo.Data ); if( m_customOptionsContainer.Enabled ) { idManager.RegisterId( m_customOptionsContainer.Index, uniquePrefix + m_customOptionsContainer.Body, m_customOptionsContainer.Body, true ); } m_modules = new TemplateModulesData( m_customOptionsContainer, idManager, m_templateProperties, uniquePrefix + "Module", subShaderInfo.StartIdx, subShaderInfo.Modules, true ); if( m_modules.SRPType == TemplateSRPType.HD ) { m_modules.SRPIsPBR = subShaderInfo.Data.Contains( TemplateHelperFunctions.HDPBRTag ); } Dictionary ownDuplicatesDict = new Dictionary( duplicatesHelper ); TemplateHelperFunctions.CreateShaderGlobalsList( subShaderInfo.Modules, ref m_availableShaderGlobals, ref ownDuplicatesDict ); if( m_modules.SRPType == TemplateSRPType.BuiltIn ) { TemplateHelperFunctions.CheckUnityBuiltinGlobalMacros( subShaderInfo.Modules, ref m_availableShaderGlobals, ref ownDuplicatesDict ); } m_passAmount = subShaderInfo.Passes.Count; //if( !m_modules.PassTag.IsValid ) //{ // m_modules.PassTag.StartIdx = subShaderData.Passes[ 0 ].GlobalStartIdx; // m_templateProperties.AddId( subShaderData.Data, m_modules.PassTag.Id, subShaderData.Passes[ 0 ].LocalStartIdx, m_modules.PassTag.SearchIndentation ); // m_modules.PassTag.StartIdx -= m_templateProperties.PropertyDict[ m_modules.PassTag.Id ].Indentation.Length; // m_templateProperties.PropertyDict[ m_modules.PassTag.Id ].UseIndentationAtStart = true; // idManager.RegisterId( m_modules.PassTag.StartIdx, m_modules.UniquePrefix + m_modules.PassTag.Id, string.Empty ); //} int firstVisible = -1; int currAddedPassIdx = 0; for( int passIdx = 0; passIdx < m_passAmount; passIdx++ ) { TemplatePass newPass = new TemplatePass( template, this,subShaderIx, passIdx, idManager, uniquePrefix + "Pass" + passIdx, subShaderInfo.Passes[ passIdx ].GlobalStartIdx, subShaderInfo.Passes[ passIdx ], ref ownDuplicatesDict ); if( newPass.AddToList ) { if( newPass.IsMainPass && m_mainPass < 0 ) { m_mainPass = currAddedPassIdx; m_foundMainPassTag = true; } else if(!newPass.IsInvisible && firstVisible < 0 ) { firstVisible = currAddedPassIdx; } m_passes.Add( newPass ); currAddedPassIdx++; } else { newPass.Destroy(); newPass = null; } } if( m_mainPass < 0 ) { // If no main pass was set then choose the first visible one m_mainPass = ( firstVisible < 0 ) ? 0 : firstVisible; m_passes[ m_mainPass ].IsMainPass = true; } ownDuplicatesDict.Clear(); ownDuplicatesDict = null; } public void Destroy() { m_LODContainer = null; m_customOptionsContainer = null; m_templateProperties.Destroy(); m_templateProperties = null; m_passes.Clear(); m_passes = null; m_modules.Destroy(); m_modules = null; m_availableShaderGlobals.Clear(); m_availableShaderGlobals = null; } void FetchLOD( int offsetIdx, string body ) { Match match = Regex.Match( body, TemplateHelperFunctions.SubShaderLODPattern ); if( match != null && match.Groups.Count > 1 ) { m_LODContainer.Id = match.Groups[ 0 ].Value; m_LODContainer.Data = match.Groups[ 1 ].Value; m_LODContainer.Index = offsetIdx + match.Index; } } public List Passes { get { return m_passes; } } public TemplateModulesData Modules { get { return m_modules; } } public string UniquePrefix { get { return m_uniquePrefix; } } public TemplatePropertyContainer TemplateProperties { get { return m_templateProperties; } } public List AvailableShaderGlobals { get { return m_availableShaderGlobals; } } public TemplateInfoContainer LODContainer { get { return m_LODContainer; } } public int PassAmount { get { return m_passAmount; } } public bool FoundMainPass { get { return m_foundMainPassTag; } } public int MainPass { get { return m_mainPass; } } public int Idx { get { return m_idx; } } public TemplateOptionsContainer CustomOptionsContainer { get { return m_customOptionsContainer; } } } }