DielectricSpecularNode.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.ShaderGraph.Drawing.Controls;
  6. using UnityEditor.ShaderGraph.Internal;
  7. using UnityEngine;
  8. namespace UnityEditor.ShaderGraph
  9. {
  10. enum DielectricMaterialType
  11. {
  12. Common,
  13. RustedMetal,
  14. Water,
  15. Ice,
  16. Glass,
  17. Custom
  18. };
  19. [Title("Input", "PBR", "Dielectric Specular")]
  20. class DielectricSpecularNode : AbstractMaterialNode, IGeneratesBodyCode
  21. {
  22. public DielectricSpecularNode()
  23. {
  24. name = "Dielectric Specular";
  25. UpdateNodeAfterDeserialization();
  26. }
  27. [SerializeField]
  28. DielectricMaterial m_Material = new DielectricMaterial(DielectricMaterialType.Common, 0.5f, 1.0f);
  29. [Serializable]
  30. public struct DielectricMaterial
  31. {
  32. public DielectricMaterialType type;
  33. public float range;
  34. public float indexOfRefraction;
  35. public DielectricMaterial(DielectricMaterialType type, float range, float indexOfRefraction)
  36. {
  37. this.type = type;
  38. this.range = range;
  39. this.indexOfRefraction = indexOfRefraction;
  40. }
  41. }
  42. [DielectricSpecularControl()]
  43. public DielectricMaterial material
  44. {
  45. get { return m_Material; }
  46. set
  47. {
  48. if ((value.type == m_Material.type) && (value.range == m_Material.range) && (value.indexOfRefraction == m_Material.indexOfRefraction))
  49. return;
  50. DielectricMaterialType previousType = m_Material.type;
  51. m_Material = value;
  52. if (value.type != previousType)
  53. Dirty(ModificationScope.Graph);
  54. else
  55. Dirty(ModificationScope.Node);
  56. }
  57. }
  58. static Dictionary<DielectricMaterialType, string> m_MaterialList = new Dictionary<DielectricMaterialType, string>
  59. {
  60. {DielectricMaterialType.RustedMetal, "0.030"},
  61. {DielectricMaterialType.Water, "0.020"},
  62. {DielectricMaterialType.Ice, "0.018"},
  63. {DielectricMaterialType.Glass, "0.040"}
  64. };
  65. private const int kOutputSlotId = 0;
  66. private const string kOutputSlotName = "Out";
  67. public override bool hasPreview { get { return true; } }
  68. public override PreviewMode previewMode
  69. {
  70. get { return PreviewMode.Preview2D; }
  71. }
  72. public sealed override void UpdateNodeAfterDeserialization()
  73. {
  74. AddSlot(new Vector1MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, 0));
  75. RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
  76. }
  77. public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
  78. {
  79. if (!generationMode.IsPreview())
  80. {
  81. switch (material.type)
  82. {
  83. case DielectricMaterialType.Custom:
  84. sb.AppendLine("$precision _{0}_IOR = {1};", GetVariableNameForNode(), material.indexOfRefraction);
  85. break;
  86. case DielectricMaterialType.Common:
  87. sb.AppendLine("$precision _{0}_Range = {1};", GetVariableNameForNode(), material.range);
  88. break;
  89. default:
  90. break;
  91. }
  92. }
  93. switch (material.type)
  94. {
  95. case DielectricMaterialType.Common:
  96. sb.AppendLine("$precision {0} = lerp(0.034, 0.048, _{1}_Range);", GetVariableNameForSlot(kOutputSlotId), GetVariableNameForNode());
  97. break;
  98. case DielectricMaterialType.Custom:
  99. sb.AppendLine("$precision {0} = pow(_{1}_IOR - 1, 2) / pow(_{1}_IOR + 1, 2);", GetVariableNameForSlot(kOutputSlotId), GetVariableNameForNode());
  100. break;
  101. default:
  102. sb.AppendLine("$precision {0} = {1};", GetVariableNameForSlot(kOutputSlotId), m_MaterialList[material.type].ToString(CultureInfo.InvariantCulture));
  103. break;
  104. }
  105. }
  106. public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
  107. {
  108. base.CollectPreviewMaterialProperties(properties);
  109. if (material.type == DielectricMaterialType.Common)
  110. {
  111. properties.Add(new PreviewProperty(PropertyType.Vector1)
  112. {
  113. name = string.Format("_{0}_Range", GetVariableNameForNode()),
  114. floatValue = material.range
  115. });
  116. }
  117. else if (material.type == DielectricMaterialType.Custom)
  118. {
  119. properties.Add(new PreviewProperty(PropertyType.Vector1)
  120. {
  121. name = string.Format("_{0}_IOR", GetVariableNameForNode()),
  122. floatValue = material.indexOfRefraction
  123. });
  124. }
  125. }
  126. public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
  127. {
  128. if (!generationMode.IsPreview())
  129. return;
  130. base.CollectShaderProperties(properties, generationMode);
  131. if (material.type == DielectricMaterialType.Common)
  132. {
  133. properties.AddShaderProperty(new Vector1ShaderProperty()
  134. {
  135. overrideReferenceName = string.Format("_{0}_Range", GetVariableNameForNode()),
  136. generatePropertyBlock = false
  137. });
  138. }
  139. else if (material.type == DielectricMaterialType.Custom)
  140. {
  141. properties.AddShaderProperty(new Vector1ShaderProperty()
  142. {
  143. overrideReferenceName = string.Format("_{0}_IOR", GetVariableNameForNode()),
  144. generatePropertyBlock = false
  145. });
  146. }
  147. }
  148. }
  149. }