No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ShaderGraphVfxAsset.cs 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.ShaderGraph.Serialization;
  6. using UnityEngine;
  7. using TextureDimension = UnityEngine.Rendering.TextureDimension;
  8. namespace UnityEditor.ShaderGraph.Internal
  9. {
  10. [Serializable]
  11. public struct TextureInfo
  12. {
  13. public TextureInfo(string name, Texture texture, TextureDimension dimension)
  14. {
  15. this.name = name;
  16. this.texture = texture;
  17. this.dimension = dimension;
  18. Debug.Assert(texture == null || texture.dimension == dimension);
  19. }
  20. public string name;
  21. public Texture texture;
  22. public TextureDimension dimension;
  23. public int instanceID => texture != null ? texture.GetInstanceID() : 0;
  24. }
  25. public sealed class ShaderGraphVfxAsset : ScriptableObject, ISerializationCallbackReceiver
  26. {
  27. private class ShaderGraphVfxAssetData : JsonObject
  28. {
  29. public List<JsonData<ShaderInput>> m_Properties = new();
  30. }
  31. public const int BaseColorSlotId = 1;
  32. public const int MetallicSlotId = 2;
  33. public const int SmoothnessSlotId = 3;
  34. public const int NormalSlotId = 8;
  35. public const int AlphaSlotId = 4;
  36. public const int EmissiveSlotId = 5;
  37. public const int ColorSlotId = 6;
  38. public const int AlphaThresholdSlotId = 7;
  39. [SerializeField]
  40. public bool generatesWithShaderGraph;
  41. [SerializeField]
  42. public bool lit;
  43. [SerializeField]
  44. public bool alphaClipping;
  45. [SerializeField]
  46. internal ShaderStageCapability[] m_PropertiesStages;
  47. [SerializeField]
  48. internal GraphCompilationResult compilationResult;
  49. [SerializeField]
  50. internal ShaderGraphRequirements[] portRequirements;
  51. [SerializeField]
  52. string m_EvaluationFunctionName;
  53. [SerializeField]
  54. string m_InputStructName;
  55. [SerializeField]
  56. string m_OutputStructName;
  57. [SerializeField]
  58. ConcretePrecision m_ConcretePrecision = ConcretePrecision.Single;
  59. ShaderGraphVfxAssetData m_Data = new ShaderGraphVfxAssetData();
  60. [HideInInspector]
  61. [SerializeField]
  62. private SerializationHelper.JSONSerializedElement m_SerializedVfxAssetData;
  63. [SerializeField]
  64. internal IntArray[] outputPropertyIndices;
  65. internal ConcretePrecision concretePrecision
  66. {
  67. get => m_ConcretePrecision;
  68. set => m_ConcretePrecision = value;
  69. }
  70. [SerializeField]
  71. OutputMetadata[] m_Outputs;
  72. [SerializeField]
  73. TextureInfo[] m_TextureInfos;
  74. public IEnumerable<TextureInfo> textureInfos { get => m_TextureInfos; }
  75. internal void SetTextureInfos(IList<PropertyCollector.TextureInfo> textures)
  76. {
  77. m_TextureInfos = textures.Select(t => new TextureInfo(t.name, EditorUtility.InstanceIDToObject(t.textureId) as Texture, t.dimension)).ToArray();
  78. }
  79. internal void SetOutputs(OutputMetadata[] outputs)
  80. {
  81. m_Outputs = outputs;
  82. }
  83. public OutputMetadata GetOutput(int id)
  84. {
  85. return m_Outputs.FirstOrDefault(t => t.id == id);
  86. }
  87. public bool HasOutput(int id)
  88. {
  89. return m_Outputs.Any(t => t.id == id);
  90. }
  91. public string evaluationFunctionName
  92. {
  93. get { return m_EvaluationFunctionName; }
  94. internal set { m_EvaluationFunctionName = value; }
  95. }
  96. public string inputStructName
  97. {
  98. get { return m_InputStructName; }
  99. internal set { m_InputStructName = value; }
  100. }
  101. public string outputStructName
  102. {
  103. get { return m_OutputStructName; }
  104. internal set { m_OutputStructName = value; }
  105. }
  106. public List<ShaderInput> properties
  107. {
  108. get
  109. {
  110. EnsureProperties();
  111. return m_Data.m_Properties.SelectValue().ToList();
  112. }
  113. }
  114. public List<AbstractShaderProperty> fragmentProperties
  115. {
  116. get
  117. {
  118. EnsureProperties();
  119. var allProperties = m_Data.m_Properties.SelectValue().ToList();
  120. var fragProperties = new List<AbstractShaderProperty>();
  121. for (var i = 0; i < allProperties.Count(); i++)
  122. {
  123. if (allProperties[i] is AbstractShaderProperty property
  124. && (m_PropertiesStages[i] & ShaderStageCapability.Fragment) != 0)
  125. fragProperties.Add(property);
  126. }
  127. return fragProperties;
  128. }
  129. }
  130. public List<AbstractShaderProperty> vertexProperties
  131. {
  132. get
  133. {
  134. EnsureProperties();
  135. var allProperties = m_Data.m_Properties.SelectValue().ToList();
  136. var vertexProperties = new List<AbstractShaderProperty>();
  137. for (var i = 0; i < allProperties.Count(); i++)
  138. {
  139. if (allProperties[i] is AbstractShaderProperty property
  140. && (m_PropertiesStages[i] & ShaderStageCapability.Vertex) != 0)
  141. vertexProperties.Add(property);
  142. }
  143. return vertexProperties;
  144. }
  145. }
  146. internal void SetProperties(List<ShaderInput> propertiesList)
  147. {
  148. m_Data.m_Properties.Clear();
  149. foreach (var property in propertiesList)
  150. {
  151. m_Data.m_Properties.Add(property);
  152. }
  153. var json = MultiJson.Serialize(m_Data);
  154. m_SerializedVfxAssetData = new SerializationHelper.JSONSerializedElement() { JSONnodeData = json };
  155. m_Data = null;
  156. }
  157. void EnsureProperties()
  158. {
  159. if ((m_Data == null || m_Data.m_Properties == null || !m_Data.m_Properties.Any()) && !String.IsNullOrEmpty(m_SerializedVfxAssetData.JSONnodeData))
  160. {
  161. m_Data = new ShaderGraphVfxAssetData();
  162. MultiJson.Deserialize(m_Data, m_SerializedVfxAssetData.JSONnodeData);
  163. }
  164. foreach (var property in m_Data.m_Properties.SelectValue())
  165. {
  166. if (property is AbstractShaderProperty shaderProperty)
  167. shaderProperty.SetupConcretePrecision(m_ConcretePrecision);
  168. }
  169. }
  170. void ISerializationCallbackReceiver.OnAfterDeserialize()
  171. {
  172. m_Data = null;
  173. }
  174. void ISerializationCallbackReceiver.OnBeforeSerialize() { }
  175. public GraphCode GetCode(OutputMetadata[] outputs)
  176. {
  177. var graphCode = new GraphCode();
  178. graphCode.requirements = ShaderGraphRequirements.none;
  179. var outputIndices = new int[outputs.Length];
  180. for (var i = 0; i < outputs.Length; i++)
  181. {
  182. if (!outputs[i].isValid)
  183. {
  184. throw new ArgumentException($"Invalid {nameof(OutputMetadata)} at index {i}.", nameof(outputs));
  185. }
  186. outputIndices[i] = outputs[i].index;
  187. graphCode.requirements = graphCode.requirements.Union(portRequirements[outputs[i].index]);
  188. }
  189. graphCode.code = compilationResult.GenerateCode(outputIndices);
  190. var propertyIndexSet = new HashSet<int>();
  191. foreach (var outputIndex in outputIndices)
  192. {
  193. foreach (var propertyIndex in outputPropertyIndices[outputIndex].array)
  194. {
  195. propertyIndexSet.Add(propertyIndex);
  196. }
  197. }
  198. var propertyIndices = propertyIndexSet.ToArray();
  199. Array.Sort(propertyIndices);
  200. var filteredProperties = propertyIndices.Select(i => properties[i]).OfType<AbstractShaderProperty>().ToArray();
  201. graphCode.properties = filteredProperties;
  202. return graphCode;
  203. }
  204. }
  205. }