ShaderGraphVfxAsset.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.Graphing;
  5. using UnityEngine;
  6. namespace UnityEditor.ShaderGraph.Internal
  7. {
  8. [Serializable]
  9. public struct TextureInfo
  10. {
  11. public string name;
  12. public Texture texture;
  13. }
  14. public sealed class ShaderGraphVfxAsset : ScriptableObject, ISerializationCallbackReceiver
  15. {
  16. public const int BaseColorSlotId = 1;
  17. public const int MetallicSlotId = 2;
  18. public const int SmoothnessSlotId = 3;
  19. public const int NormalSlotId = 8;
  20. public const int AlphaSlotId = 4;
  21. public const int EmissiveSlotId = 5;
  22. public const int ColorSlotId = 6;
  23. public const int AlphaThresholdSlotId = 7;
  24. [SerializeField]
  25. public bool lit;
  26. [SerializeField]
  27. internal GraphCompilationResult compilationResult;
  28. [SerializeField]
  29. internal ShaderGraphRequirements[] portRequirements;
  30. [SerializeField]
  31. string m_EvaluationFunctionName;
  32. [SerializeField]
  33. string m_InputStructName;
  34. [SerializeField]
  35. string m_OutputStructName;
  36. [SerializeField]
  37. ConcretePrecision m_ConcretePrecision = ConcretePrecision.Float;
  38. [NonSerialized]
  39. List<AbstractShaderProperty> m_Properties;
  40. [SerializeField]
  41. List<SerializationHelper.JSONSerializedElement> m_SerializedProperties = new List<SerializationHelper.JSONSerializedElement>();
  42. [SerializeField]
  43. internal IntArray[] outputPropertyIndices;
  44. internal ConcretePrecision concretePrecision
  45. {
  46. get => m_ConcretePrecision;
  47. set => m_ConcretePrecision = value;
  48. }
  49. [SerializeField]
  50. OutputMetadata[] m_Outputs;
  51. [SerializeField]
  52. TextureInfo[] m_TextureInfos;
  53. public IEnumerable<TextureInfo> textureInfos { get => m_TextureInfos; }
  54. internal void SetTextureInfos(IList<PropertyCollector.TextureInfo> textures )
  55. {
  56. m_TextureInfos = textures.Select(t => new TextureInfo() { name = t.name, texture = EditorUtility.InstanceIDToObject(t.textureId) as Texture }).ToArray();
  57. }
  58. internal void SetOutputs(OutputMetadata[] outputs)
  59. {
  60. m_Outputs = outputs;
  61. }
  62. public OutputMetadata GetOutput(int id)
  63. {
  64. return m_Outputs.FirstOrDefault(t => t.id == id);
  65. }
  66. public bool HasOutput(int id)
  67. {
  68. return m_Outputs.Any(t => t.id == id);
  69. }
  70. public string evaluationFunctionName
  71. {
  72. get { return m_EvaluationFunctionName; }
  73. internal set { m_EvaluationFunctionName = value; }
  74. }
  75. public string inputStructName
  76. {
  77. get { return m_InputStructName; }
  78. internal set { m_InputStructName = value; }
  79. }
  80. public string outputStructName
  81. {
  82. get { return m_OutputStructName; }
  83. internal set { m_OutputStructName = value; }
  84. }
  85. public IEnumerable<AbstractShaderProperty> properties
  86. {
  87. get
  88. {
  89. EnsureProperties();
  90. return m_Properties;
  91. }
  92. }
  93. internal void SetProperties(List<AbstractShaderProperty> propertiesList)
  94. {
  95. m_Properties = propertiesList;
  96. m_SerializedProperties = SerializationHelper.Serialize<AbstractShaderProperty>(m_Properties);
  97. }
  98. void EnsureProperties()
  99. {
  100. if (m_Properties == null)
  101. {
  102. m_Properties = SerializationHelper.Deserialize<AbstractShaderProperty>(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping());
  103. foreach (var property in m_Properties)
  104. {
  105. property.ValidateConcretePrecision(m_ConcretePrecision);
  106. }
  107. }
  108. }
  109. void ISerializationCallbackReceiver.OnAfterDeserialize()
  110. {
  111. //After import the object will be deserialized into the previous instance, leading to an descynchronization between m_SerializedProperties and m_Properties
  112. m_Properties = null;
  113. }
  114. void ISerializationCallbackReceiver.OnBeforeSerialize() { }
  115. public GraphCode GetCode(OutputMetadata[] outputs)
  116. {
  117. var graphCode = new GraphCode();
  118. graphCode.requirements = ShaderGraphRequirements.none;
  119. var outputIndices = new int[outputs.Length];
  120. for (var i = 0; i < outputs.Length; i++)
  121. {
  122. if (!outputs[i].isValid)
  123. {
  124. throw new ArgumentException($"Invalid {nameof(OutputMetadata)} at index {i}.", nameof(outputs));
  125. }
  126. outputIndices[i] = outputs[i].index;
  127. graphCode.requirements = graphCode.requirements.Union(portRequirements[outputs[i].index]);
  128. }
  129. graphCode.code = compilationResult.GenerateCode(outputIndices);
  130. var propertyIndexSet = new HashSet<int>();
  131. foreach (var outputIndex in outputIndices)
  132. {
  133. foreach (var propertyIndex in outputPropertyIndices[outputIndex].array)
  134. {
  135. propertyIndexSet.Add(propertyIndex);
  136. }
  137. }
  138. EnsureProperties();
  139. var propertyIndices = propertyIndexSet.ToArray();
  140. Array.Sort(propertyIndices);
  141. var filteredProperties = propertyIndices.Select(i => m_Properties[i]).ToArray();
  142. graphCode.properties = filteredProperties;
  143. return graphCode;
  144. }
  145. }
  146. }