UniversalFastBlinnMasterNode.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using System;
  2. namespace UnityEditor.ShaderGraph
  3. {
  4. /* [Serializable]
  5. [Title("Master", "Universal", "Fast Blinn")]
  6. class UniversalFastBlinnMasterNode : AbstractMasterNode
  7. {
  8. public const string AlbedoSlotName = "Diffuse";
  9. public const string SpecularSlotName = "Specular";
  10. public const string ShininessSlotName = "Shininess";
  11. public const string GlossinessSlotName = "Glossiness";
  12. public const string NormalSlotName = "Normal";
  13. public const string EmissionSlotName = "Emission";
  14. public const string AlphaSlotName = "Alpha";
  15. public const string VertexOffsetName = "VertexPosition";
  16. public const int AlbedoSlotId = 0;
  17. public const int SpecularSlotId = 1;
  18. public const int ShininessSlotId = 3;
  19. public const int GlossinessSlotId = 4;
  20. public const int NormalSlotId = 5;
  21. public const int EmissionSlotId = 6;
  22. public const int AlphaSlotId = 7;
  23. public const int VertexOffsetId = 8;
  24. [SerializeField]
  25. private SurfaceMaterialOptions m_MaterialOptions = new SurfaceMaterialOptions();
  26. public SurfaceMaterialOptions options
  27. {
  28. get { return m_MaterialOptions; }
  29. }
  30. public UniversalFastBlinnMasterNode()
  31. {
  32. name = "UniversalFastBlinnMasterNode";
  33. UpdateNodeAfterDeserialization();
  34. }
  35. public sealed override void UpdateNodeAfterDeserialization()
  36. {
  37. AddSlot(new MaterialSlot(VertexOffsetId, VertexOffsetName, VertexOffsetName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Vertex));
  38. AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
  39. AddSlot(new MaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
  40. AddSlot(new MaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
  41. AddSlot(new MaterialSlot(ShininessSlotId, ShininessSlotName, ShininessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
  42. AddSlot(new MaterialSlot(GlossinessSlotId, GlossinessSlotName, GlossinessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
  43. AddSlot(new MaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
  44. AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
  45. // clear out slot names that do not match the slots
  46. // we support
  47. RemoveSlotsNameNotMatching(
  48. new[]
  49. {
  50. AlbedoSlotId,
  51. NormalSlotId,
  52. EmissionSlotId,
  53. SpecularSlotId,
  54. ShininessSlotId,
  55. GlossinessSlotId,
  56. AlphaSlotId,
  57. VertexOffsetId
  58. });
  59. }
  60. protected int[] surfaceInputs
  61. {
  62. get
  63. {
  64. return new[]
  65. {
  66. AlbedoSlotId,
  67. NormalSlotId,
  68. EmissionSlotId,
  69. SpecularSlotId,
  70. ShininessSlotId,
  71. GlossinessSlotId,
  72. AlphaSlotId,
  73. };
  74. }
  75. }
  76. protected int[] vertexInputs
  77. {
  78. get
  79. {
  80. return new[]
  81. {
  82. VertexOffsetId
  83. };
  84. }
  85. }
  86. void GenerateNodeFunctionsAndPropertyUsages(
  87. ShaderGenerator shaderBody,
  88. ShaderGenerator propertyUsages,
  89. ShaderGenerator nodeFunction,
  90. GenerationMode mode,
  91. int[] validNodeIds)
  92. {
  93. var activeNodeList = new List<AbstractMaterialNode>();
  94. NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this, NodeUtils.IncludeSelf.Include,
  95. new List<int>(validNodeIds));
  96. foreach (var node in activeNodeList.OfType<AbstractMaterialNode>())
  97. {
  98. if (node is IGeneratesFunction)
  99. (node as IGeneratesFunction).GenerateNodeFunction(nodeFunction, mode);
  100. node.GeneratePropertyUsages(propertyUsages, mode);
  101. }
  102. var nodes = ListPool<AbstractMaterialNode>.Get();
  103. //Get the rest of the nodes for all the other slots
  104. NodeUtils.DepthFirstCollectNodesFromNode(nodes, this, NodeUtils.IncludeSelf.Exclude, new List<int>(vertexInputs));
  105. for (var i = 0; i < nodes.Count; i++)
  106. {
  107. var node = nodes[i];
  108. if (node is IGeneratesBodyCode)
  109. (node as IGeneratesBodyCode).GenerateNodeCode(shaderBody, mode);
  110. }
  111. ListPool<AbstractMaterialNode>.Release(nodes);
  112. }
  113. void GenerateVertexShaderInternal(
  114. ShaderGenerator propertyUsages,
  115. ShaderGenerator shaderBody,
  116. ShaderGenerator nodeFunction,
  117. ShaderGenerator vertexShaderBlock,
  118. GenerationMode mode)
  119. {
  120. GenerateNodeFunctionsAndPropertyUsages(vertexShaderBlock, propertyUsages, nodeFunction, mode, vertexInputs);
  121. var slot = FindInputSlot<MaterialSlot>(VertexOffsetId);
  122. foreach (var edge in owner.GetEdges(slot.slotReference))
  123. {
  124. var outputRef = edge.outputSlot;
  125. var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
  126. if (fromNode == null)
  127. continue;
  128. var remapper = fromNode as AbstractMaterialNodeGroupRemapper;
  129. if (remapper != null && !remapper.IsValidSlotConnection(outputRef.slotId))
  130. continue;
  131. vertexShaderBlock.AddShaderChunk("v.vertex.xyz += " + fromNode.GetVariableNameForSlot(outputRef.slotId) + ";", true);
  132. }
  133. }
  134. public override string GetSubShader(GenerationMode mode, PropertyGenerator shaderPropertiesVisitor)
  135. {
  136. var templateLocation = ShaderGenerator.GetTemplatePath("universalSubshaderFastBlinn.template");
  137. if (!File.Exists(templateLocation))
  138. return string.Empty;
  139. var activeNodeList = new List<AbstractMaterialNode>();
  140. NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
  141. foreach (var node in activeNodeList.OfType<AbstractMaterialNode>())
  142. node.GeneratePropertyBlock(shaderPropertiesVisitor, mode);
  143. var templateText = File.ReadAllText(templateLocation);
  144. var shaderBodyVisitor = new ShaderGenerator();
  145. var shaderFunctionVisitor = new ShaderGenerator();
  146. var shaderPropertyUsagesVisitor = new ShaderGenerator();
  147. var shaderInputVisitor = new ShaderGenerator();
  148. var shaderOutputVisitor = new ShaderGenerator();
  149. var vertexShaderBlock = new ShaderGenerator();
  150. var definesVisitor = new ShaderGenerator();
  151. GenerateSurfaceShaderInternal(
  152. shaderPropertyUsagesVisitor,
  153. shaderBodyVisitor,
  154. shaderFunctionVisitor,
  155. shaderInputVisitor,
  156. shaderOutputVisitor,
  157. vertexShaderBlock,
  158. definesVisitor,
  159. mode);
  160. GenerateVertexShaderInternal(
  161. shaderPropertyUsagesVisitor,
  162. shaderBodyVisitor,
  163. shaderFunctionVisitor,
  164. vertexShaderBlock,
  165. mode);
  166. var tagsVisitor = new ShaderGenerator();
  167. var blendingVisitor = new ShaderGenerator();
  168. var cullingVisitor = new ShaderGenerator();
  169. var zTestVisitor = new ShaderGenerator();
  170. var zWriteVisitor = new ShaderGenerator();
  171. m_MaterialOptions.GetTags(tagsVisitor);
  172. m_MaterialOptions.GetBlend(blendingVisitor);
  173. m_MaterialOptions.GetCull(cullingVisitor);
  174. m_MaterialOptions.GetDepthTest(zTestVisitor);
  175. m_MaterialOptions.GetDepthWrite(zWriteVisitor);
  176. GetDefines(definesVisitor);
  177. var resultShader = templateText.Replace("${ShaderPropertyUsages}", shaderPropertyUsagesVisitor.GetShaderString(2));
  178. resultShader = resultShader.Replace("${ShaderFunctions}", shaderFunctionVisitor.GetShaderString(2));
  179. resultShader = resultShader.Replace("${VertexInputs}", shaderInputVisitor.GetShaderString(3));
  180. resultShader = resultShader.Replace("${VertexOutputs}", shaderOutputVisitor.GetShaderString(3));
  181. resultShader = resultShader.Replace("${PixelShaderBody}", shaderBodyVisitor.GetShaderString(3));
  182. resultShader = resultShader.Replace("${Tags}", tagsVisitor.GetShaderString(2));
  183. resultShader = resultShader.Replace("${Blending}", blendingVisitor.GetShaderString(2));
  184. resultShader = resultShader.Replace("${Culling}", cullingVisitor.GetShaderString(2));
  185. resultShader = resultShader.Replace("${ZTest}", zTestVisitor.GetShaderString(2));
  186. resultShader = resultShader.Replace("${ZWrite}", zWriteVisitor.GetShaderString(2));
  187. resultShader = resultShader.Replace("${LOD}", "" + m_MaterialOptions.lod);
  188. resultShader = resultShader.Replace("${Defines}", definesVisitor.GetShaderString(2));
  189. resultShader = resultShader.Replace("${VertexShaderBody}", vertexShaderBlock.GetShaderString(3));
  190. return resultShader;
  191. }
  192. public void GetDefines(ShaderGenerator visitor)
  193. {
  194. visitor.AddShaderChunk("#define _GLOSSYREFLECTIONS_ON", true);
  195. visitor.AddShaderChunk("#define _SPECULARHIGHLIGHTS_ON", true);
  196. }
  197. public override string GetFullShader(GenerationMode mode, string name, out List<PropertyGenerator.TextureInfo> configuredTextures)
  198. {
  199. var templateLocation = ShaderGenerator.GetTemplatePath("shader.template");
  200. if (!File.Exists(templateLocation))
  201. {
  202. configuredTextures = new List<PropertyGenerator.TextureInfo>();
  203. return string.Empty;
  204. }
  205. var templateText = File.ReadAllText(templateLocation);
  206. var shaderPropertiesVisitor = new PropertyGenerator();
  207. var resultShader = templateText.Replace("${ShaderName}", name);
  208. resultShader = resultShader.Replace("${SubShader}", GetSubShader(mode, shaderPropertiesVisitor));
  209. resultShader = resultShader.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetShaderString(2));
  210. configuredTextures = shaderPropertiesVisitor.GetConfiguredTexutres();
  211. Debug.Log(resultShader);
  212. return Regex.Replace(resultShader, @"\r\n|\n\r|\n|\r", Environment.NewLine);
  213. }
  214. private void GenerateSurfaceShaderInternal(
  215. ShaderGenerator propertyUsages,
  216. ShaderGenerator shaderBody,
  217. ShaderGenerator nodeFunction,
  218. ShaderGenerator shaderInputVisitor,
  219. ShaderGenerator shaderOutputVisitor,
  220. ShaderGenerator vertexShaderBlock,
  221. ShaderGenerator definesVisitor,
  222. GenerationMode mode)
  223. {
  224. var activeNodeList = new List<AbstractMaterialNode>();
  225. NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this, NodeUtils.IncludeSelf.Include,
  226. new List<int>(surfaceInputs));
  227. foreach (var node in activeNodeList.OfType<AbstractMaterialNode>())
  228. {
  229. if (node is IGeneratesFunction)
  230. {
  231. ((IGeneratesFunction)node).GenerateNodeFunction(nodeFunction, mode);
  232. }
  233. node.GeneratePropertyUsages(propertyUsages, mode);
  234. }
  235. int vertInputIndex = 2;
  236. int vertOutputIndex = 5;
  237. shaderInputVisitor.AddShaderChunk("half4 texcoord1 : TEXCOORD1;", true);
  238. bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
  239. bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
  240. bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
  241. bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
  242. bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
  243. bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
  244. bool requiresScreenPosition = activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
  245. bool requiresVertexColor = activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
  246. foreach (var slot in GetInputSlots<MaterialSlot>())
  247. {
  248. if (surfaceInputs.Contains(slot.id))
  249. {
  250. foreach (var edge in owner.GetEdges(slot.slotReference))
  251. {
  252. var outputRef = edge.outputSlot;
  253. var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
  254. if (fromNode == null)
  255. continue;
  256. var remapper = fromNode as AbstractMaterialNodeGroupRemapper;
  257. if (remapper != null && !remapper.IsValidSlotConnection(outputRef.slotId))
  258. continue;
  259. if (slot.id == NormalSlotId)
  260. {
  261. requiresBitangent = true;
  262. requiresTangent = true;
  263. definesVisitor.AddShaderChunk("#define _NORMALMAP 1", true);
  264. }
  265. }
  266. }
  267. }
  268. for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
  269. {
  270. var channel = (UVChannel)uvIndex;
  271. if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
  272. {
  273. if(uvIndex != 0)
  274. {
  275. shaderInputVisitor.AddShaderChunk(string.Format("half4 texcoord{0} : TEXCOORD{1};", uvIndex, vertInputIndex), true);
  276. shaderOutputVisitor.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, vertOutputIndex), true);
  277. vertexShaderBlock.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex), true);
  278. vertInputIndex++;
  279. vertOutputIndex++;
  280. }
  281. shaderBody.AddShaderChunk(string.Format("half4 {0} = i.meshUV{1};", channel.GetUVName(), uvIndex), true);
  282. }
  283. }
  284. if (requiresViewDir || requiresViewDirTangentSpace)
  285. {
  286. shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceViewDirection + " = i.viewDir;", true);
  287. }
  288. if (requiresWorldPos)
  289. {
  290. shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpacePosition + " = i.posWS;", true);
  291. }
  292. if (requiresScreenPosition)
  293. {
  294. shaderOutputVisitor.AddShaderChunk(string.Format("half4 screenPos : TEXCOORD{0};", vertOutputIndex), true);
  295. vertexShaderBlock.AddShaderChunk("o.screenPos = ComputeScreenPos(v.vertex);", true);
  296. shaderBody.AddShaderChunk("float4 " + ShaderGeneratorNames.ScreenPosition + " = i.screenPos;", true);
  297. vertOutputIndex++;
  298. }
  299. if (requiresBitangent || requiresTangent || requiresViewDirTangentSpace)
  300. {
  301. shaderOutputVisitor.AddShaderChunk(string.Format("half3 tangent : TEXCOORD{0}; \\", vertOutputIndex), true);
  302. vertexShaderBlock.AddShaderChunk("o.tangent = normalize(UnityObjectToWorldDir(v.tangent)); \\", true);
  303. shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceTangent + " = normalize(i.tangent.xyz);", true);
  304. vertOutputIndex++;
  305. }
  306. if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
  307. {
  308. shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(i.normal);", true);
  309. }
  310. if (requiresBitangent || requiresViewDirTangentSpace)
  311. {
  312. shaderOutputVisitor.AddShaderChunk(string.Format("half3 binormal : TEXCOORD{0};", vertOutputIndex), true);
  313. vertexShaderBlock.AddShaderChunk("o.binormal = cross(o.normal, o.tangent) * v.tangent.w;", true);
  314. shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceBitangent + " = i.binormal;", true);
  315. vertOutputIndex++;
  316. }
  317. if (requiresViewDirTangentSpace)
  318. {
  319. shaderBody.AddShaderChunk(
  320. "float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + ";", true);
  321. shaderBody.AddShaderChunk(
  322. ShaderGeneratorNames.TangentSpaceViewDirection + ".x = dot(" +
  323. ShaderGeneratorNames.WorldSpaceViewDirection + "," +
  324. ShaderGeneratorNames.WorldSpaceTangent + ");", true);
  325. shaderBody.AddShaderChunk(
  326. ShaderGeneratorNames.TangentSpaceViewDirection + ".y = dot(" +
  327. ShaderGeneratorNames.WorldSpaceViewDirection + "," +
  328. ShaderGeneratorNames.WorldSpaceBitangent + ");", true);
  329. shaderBody.AddShaderChunk(
  330. ShaderGeneratorNames.TangentSpaceViewDirection + ".z = dot(" +
  331. ShaderGeneratorNames.WorldSpaceViewDirection + "," +
  332. ShaderGeneratorNames.WorldSpaceNormal + ");", true);
  333. }
  334. if (requiresVertexColor)
  335. {
  336. shaderOutputVisitor.AddShaderChunk(string.Format("half4 color : TEXCOORD{0};", vertOutputIndex), true);
  337. shaderBody.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = i.color;", true);
  338. vertInputIndex++;
  339. vertOutputIndex++;
  340. }
  341. GenerateNodeCode(shaderBody, propertyUsages, mode);
  342. }
  343. public void GenerateNodeCode(ShaderGenerator shaderBody, ShaderGenerator propertyUsages, GenerationMode generationMode)
  344. {
  345. var nodes = ListPool<AbstractMaterialNode>.Get();
  346. //Get the rest of the nodes for all the other slots
  347. NodeUtils.DepthFirstCollectNodesFromNode(nodes, this, NodeUtils.IncludeSelf.Exclude, new List<int>(surfaceInputs));
  348. for (var i = 0; i < nodes.Count; i++)
  349. {
  350. var node = nodes[i];
  351. if (node is IGeneratesBodyCode)
  352. (node as IGeneratesBodyCode).GenerateNodeCode(shaderBody, generationMode);
  353. }
  354. ListPool<AbstractMaterialNode>.Release(nodes);
  355. foreach (var slot in GetInputSlots<MaterialSlot>())
  356. {
  357. if (surfaceInputs.Contains(slot.id))
  358. {
  359. foreach (var edge in owner.GetEdges(slot.slotReference))
  360. {
  361. var outputRef = edge.outputSlot;
  362. var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
  363. if (fromNode == null)
  364. continue;
  365. var remapper = fromNode as AbstractMaterialNodeGroupRemapper;
  366. if (remapper != null && !remapper.IsValidSlotConnection(outputRef.slotId))
  367. continue;
  368. shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(outputRef.slotId) + ";", true);
  369. if (slot.id == NormalSlotId)
  370. shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " += 1e-6;", true);
  371. if (slot.id == AlphaSlotId)
  372. propertyUsages.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON", true);
  373. }
  374. }
  375. }
  376. }
  377. }*/
  378. }