Açıklama Yok
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.

VirtualTextureShaderProperty.cs 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEditor.ShaderGraph.Drawing.Controls;
  6. using UnityEngine;
  7. using UnityEditor.Graphing;
  8. using UnityEditor.ShaderGraph.Internal;
  9. namespace UnityEditor.ShaderGraph
  10. {
  11. [Serializable]
  12. [BlackboardInputInfo(60)]
  13. class VirtualTextureShaderProperty : AbstractShaderProperty<SerializableVirtualTexture>
  14. {
  15. public VirtualTextureShaderProperty()
  16. {
  17. displayName = "VirtualTexture";
  18. value = new SerializableVirtualTexture();
  19. // add at least one layer
  20. value.layers = new List<SerializableVirtualTextureLayer>();
  21. value.layers.Add(new SerializableVirtualTextureLayer("Layer0", new SerializableTexture()));
  22. value.layers.Add(new SerializableVirtualTextureLayer("Layer1", new SerializableTexture()));
  23. }
  24. public override PropertyType propertyType => PropertyType.VirtualTexture;
  25. internal override bool isExposable => true; // the textures are exposable at least..
  26. internal override bool isRenamable => true;
  27. internal override void GetPropertyReferenceNames(List<string> result)
  28. {
  29. result.Add(referenceName);
  30. for (int layer = 0; layer < value.layers.Count; layer++)
  31. {
  32. result.Add(value.layers[layer].layerRefName);
  33. }
  34. }
  35. internal override void GetPropertyDisplayNames(List<string> result)
  36. {
  37. result.Add(displayName);
  38. for (int layer = 0; layer < value.layers.Count; layer++)
  39. {
  40. result.Add(value.layers[layer].layerName);
  41. }
  42. }
  43. // this is used for properties exposed to the Material in the shaderlab Properties{} block
  44. internal override void AppendPropertyBlockStrings(ShaderStringBuilder builder)
  45. {
  46. if (!value.procedural)
  47. {
  48. // adds properties in this format so: [TextureStack.MyStack(0)] [NoScaleOffset] Layer0("Layer0", 2D) = "white" {}
  49. for (int layer = 0; layer < value.layers.Count; layer++)
  50. {
  51. string layerName = value.layers[layer].layerName;
  52. string layerRefName = value.layers[layer].layerRefName;
  53. builder.AppendLine($"{hideTagString}[TextureStack.{referenceName}({layer})][NoScaleOffset]{layerRefName}(\"{layerName}\", 2D) = \"white\" {{}}");
  54. }
  55. }
  56. else
  57. {
  58. // For procedural VT, we only need to expose a single property, indicating the referenceName and the number of layers
  59. // Adds a property as:
  60. // [ProceduralTextureStack.MyStack(1)] [NoScaleOffset] MyStack("Procedural Virtual Texture", 2D) = "white" {}
  61. // or:
  62. // [GlobalProceduralTextureStack.MyStack(2)] [NoScaleOffset] MyStack("Procedural Virtual Texture", 2D) = "white" {}
  63. string prefixString = value.shaderDeclaration == HLSLDeclaration.UnityPerMaterial
  64. ? "ProceduralTextureStack"
  65. : "GlobalProceduralTextureStack";
  66. int numLayers = value.layers.Count;
  67. builder.AppendLine($"{hideTagString}[{prefixString}.{referenceName}({numLayers})][NoScaleOffset]{referenceName}(\"{"Procedural Virtual Texture"}\", 2D) = \"white\" {{}}");
  68. }
  69. }
  70. internal override string GetPropertyBlockString()
  71. {
  72. // this should not be called, as it is replaced by the Append*PropertyBlockStrings function above
  73. throw new NotSupportedException();
  74. }
  75. internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
  76. internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
  77. {
  78. int numLayers = value.layers.Count;
  79. if (numLayers > 0)
  80. {
  81. HLSLDeclaration decl = (value.procedural) ? value.shaderDeclaration : HLSLDeclaration.UnityPerMaterial;
  82. action(new HLSLProperty(HLSLType._CUSTOM, referenceName + "_CBDecl", decl, concretePrecision)
  83. {
  84. customDeclaration = (ssb) =>
  85. {
  86. ssb.TryAppendIndentation();
  87. ssb.Append("DECLARE_STACK_CB(");
  88. ssb.Append(referenceName);
  89. ssb.Append(");");
  90. ssb.AppendNewLine();
  91. }
  92. });
  93. if (!value.procedural)
  94. {
  95. //declare regular texture properties (for fallback case)
  96. for (int i = 0; i < numLayers; i++)
  97. {
  98. string layerRefName = value.layers[i].layerRefName;
  99. action(new HLSLProperty(HLSLType._Texture2D, layerRefName, HLSLDeclaration.Global));
  100. action(new HLSLProperty(HLSLType._SamplerState, "sampler" + layerRefName, HLSLDeclaration.Global));
  101. }
  102. }
  103. Action<ShaderStringBuilder> customDecl = (builder) =>
  104. {
  105. // declare texture stack
  106. builder.TryAppendIndentation();
  107. builder.Append("DECLARE_STACK");
  108. builder.Append((numLayers <= 1) ? "" : numLayers.ToString());
  109. builder.Append("(");
  110. builder.Append(referenceName);
  111. builder.Append(",");
  112. for (int i = 0; i < value.layers.Count; i++)
  113. {
  114. if (i != 0) builder.Append(",");
  115. builder.Append(value.layers[i].layerRefName);
  116. }
  117. builder.Append(");");
  118. builder.AppendNewLine();
  119. // declare the actual virtual texture property "variable" as a macro define to the BuildVTProperties function
  120. builder.TryAppendIndentation();
  121. builder.Append("#define ");
  122. builder.Append(referenceName);
  123. builder.Append(" AddTextureType(BuildVTProperties_");
  124. builder.Append(referenceName);
  125. builder.Append("()");
  126. for (int i = 0; i < value.layers.Count; i++)
  127. {
  128. builder.Append(",");
  129. builder.Append("TEXTURETYPE_");
  130. builder.Append(value.layers[i].layerTextureType.ToString().ToUpper());
  131. }
  132. builder.Append(")");
  133. builder.AppendNewLine();
  134. };
  135. action(new HLSLProperty(HLSLType._CUSTOM, referenceName + "_Global", HLSLDeclaration.Global, concretePrecision)
  136. {
  137. customDeclaration = customDecl
  138. });
  139. }
  140. }
  141. // argument string used to pass this property to a subgraph
  142. internal override string GetPropertyAsArgumentString(string precisionString)
  143. {
  144. return "VTPropertyWithTextureType " + referenceName;
  145. }
  146. // if a blackboard property is deleted, or copy/pasted, all node instances of it are replaced with this:
  147. internal override AbstractMaterialNode ToConcreteNode()
  148. {
  149. return null; // return null to indicate there is NO concrete form of a VT property
  150. }
  151. internal override PreviewProperty GetPreviewMaterialProperty()
  152. {
  153. return new PreviewProperty(propertyType)
  154. {
  155. name = referenceName,
  156. vtProperty = this
  157. };
  158. }
  159. internal override ShaderInput Copy()
  160. {
  161. var vt = new VirtualTextureShaderProperty
  162. {
  163. displayName = displayName,
  164. value = new SerializableVirtualTexture(),
  165. };
  166. // duplicate layer data, but reset reference names (they should be unique)
  167. for (int layer = 0; layer < value.layers.Count; layer++)
  168. {
  169. var guid = Guid.NewGuid();
  170. vt.value.layers.Add(new SerializableVirtualTextureLayer(value.layers[layer]));
  171. }
  172. return vt;
  173. }
  174. internal void AddTextureInfo(List<PropertyCollector.TextureInfo> infos)
  175. {
  176. for (int layer = 0; layer < value.layers.Count; layer++)
  177. {
  178. string layerRefName = value.layers[layer].layerRefName;
  179. var layerTexture = value.layers[layer].layerTexture;
  180. var texture = layerTexture != null ? layerTexture.texture : null;
  181. var textureInfo = new PropertyCollector.TextureInfo
  182. {
  183. name = layerRefName,
  184. textureId = texture != null ? texture.GetInstanceID() : 0,
  185. dimension = texture != null ? texture.dimension : UnityEngine.Rendering.TextureDimension.Any,
  186. modifiable = true
  187. };
  188. infos.Add(textureInfo);
  189. }
  190. }
  191. internal override bool isAlwaysExposed => true;
  192. internal override bool isCustomSlotAllowed => false;
  193. public override void OnAfterDeserialize(string json)
  194. {
  195. // VT shader properties must be exposed so they can be picked up by the native-side VT system
  196. generatePropertyBlock = true;
  197. }
  198. }
  199. }