暫無描述
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.

UniversalSampleBufferNode.cs 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using System.Collections.Generic;
  2. using System;
  3. using UnityEngine;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.ShaderGraph;
  6. using UnityEditor.ShaderGraph.Drawing.Controls;
  7. using UnityEditor.ShaderGraph.Internal;
  8. using UnityEngine.Rendering.Universal;
  9. using System.Reflection;
  10. using System.Linq;
  11. using UnityEngine.XR;
  12. namespace UnityEditor.Rendering.Universal
  13. {
  14. [SRPFilter(typeof(UniversalRenderPipeline))]
  15. [Title("Input", "Universal", "URP Sample Buffer")]
  16. sealed class UniversalSampleBufferNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireScreenPosition, IMayRequireNDCPosition
  17. {
  18. const string k_ScreenPositionSlotName = "UV";
  19. const string k_OutputSlotName = "Output";
  20. const int k_ScreenPositionSlotId = 0;
  21. const int k_OutputSlotId = 2;
  22. public enum BufferType
  23. {
  24. NormalWorldSpace,
  25. MotionVectors,
  26. BlitSource,
  27. }
  28. [SerializeField]
  29. private BufferType m_BufferType = BufferType.NormalWorldSpace;
  30. [EnumControl("Source Buffer")]
  31. public BufferType bufferType
  32. {
  33. get { return m_BufferType; }
  34. set
  35. {
  36. if (m_BufferType == value)
  37. return;
  38. m_BufferType = value;
  39. UpdateNodeAfterDeserialization();
  40. Dirty(ModificationScope.Graph);
  41. }
  42. }
  43. public override string documentationURL => Documentation.GetPageLink(Documentation.packageName, "SGNode-Universal-Sample-Buffer");
  44. public UniversalSampleBufferNode()
  45. {
  46. name = "URP Sample Buffer";
  47. synonyms = new string[] { "normal", "motion vector", "blit" };
  48. UpdateNodeAfterDeserialization();
  49. }
  50. public override bool hasPreview { get { return true; } }
  51. public override PreviewMode previewMode => PreviewMode.Preview2D;
  52. int channelCount;
  53. public sealed override void UpdateNodeAfterDeserialization()
  54. {
  55. AddSlot(new ScreenPositionMaterialSlot(k_ScreenPositionSlotId, k_ScreenPositionSlotName, k_ScreenPositionSlotName, ScreenSpaceType.Default));
  56. switch (bufferType)
  57. {
  58. case BufferType.NormalWorldSpace:
  59. AddSlot(new Vector3MaterialSlot(k_OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector3.zero, ShaderStageCapability.Fragment));
  60. channelCount = 3;
  61. break;
  62. case BufferType.MotionVectors:
  63. AddSlot(new Vector2MaterialSlot(k_OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector2.zero, ShaderStageCapability.Fragment));
  64. channelCount = 2;
  65. break;
  66. case BufferType.BlitSource:
  67. AddSlot(new ColorRGBAMaterialSlot(k_OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Color.black, ShaderStageCapability.Fragment));
  68. channelCount = 4;
  69. break;
  70. }
  71. RemoveSlotsNameNotMatching(new[]
  72. {
  73. k_ScreenPositionSlotId,
  74. k_OutputSlotId,
  75. });
  76. }
  77. public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
  78. {
  79. if (generationMode.IsPreview())
  80. return;
  81. }
  82. string GetFunctionName() => $"Unity_Universal_SampleBuffer_{bufferType}_$precision";
  83. public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
  84. {
  85. // Preview SG doesn't have access to render pipeline buffer
  86. if (!generationMode.IsPreview())
  87. {
  88. registry.ProvideFunction(GetFunctionName(), s =>
  89. {
  90. if (bufferType == BufferType.MotionVectors)
  91. s.AppendLine("TEXTURE2D_X(_MotionVectorTexture);");
  92. if (bufferType == BufferType.BlitSource)
  93. {
  94. s.AppendLine("TEXTURE2D_X(_BlitTexture);");
  95. }
  96. s.AppendLine("$precision{1} {0}($precision2 uv)", GetFunctionName(), channelCount);
  97. using (s.BlockScope())
  98. {
  99. switch (bufferType)
  100. {
  101. case BufferType.NormalWorldSpace:
  102. s.AppendLine("return SHADERGRAPH_SAMPLE_SCENE_NORMAL(uv);");
  103. break;
  104. case BufferType.MotionVectors:
  105. s.AppendLine("uint2 pixelCoords = uint2(uv * _ScreenSize.xy);");
  106. s.AppendLine($"return LOAD_TEXTURE2D_X_LOD(_MotionVectorTexture, pixelCoords, 0).xy;");
  107. break;
  108. case BufferType.BlitSource:
  109. s.AppendLine("uint2 pixelCoords = uint2(uv * _ScreenSize.xy);");
  110. s.AppendLine($"return LOAD_TEXTURE2D_X_LOD(_BlitTexture, pixelCoords, 0);");
  111. break;
  112. default:
  113. s.AppendLine("return 0.0;");
  114. break;
  115. }
  116. }
  117. });
  118. }
  119. else
  120. {
  121. registry.ProvideFunction(GetFunctionName(), s =>
  122. {
  123. s.AppendLine("$precision{1} {0}($precision2 uv)", GetFunctionName(), channelCount);
  124. using (s.BlockScope())
  125. {
  126. switch (bufferType)
  127. {
  128. case BufferType.NormalWorldSpace:
  129. s.AppendLine("return LatlongToDirectionCoordinate(uv);");
  130. break;
  131. case BufferType.MotionVectors:
  132. s.AppendLine("return uv * 2 - 1;");
  133. break;
  134. case BufferType.BlitSource:
  135. default:
  136. s.AppendLine("return 0.0;");
  137. break;
  138. }
  139. }
  140. });
  141. }
  142. }
  143. public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
  144. {
  145. string uv = GetSlotValue(k_ScreenPositionSlotId, generationMode);
  146. sb.AppendLine($"$precision{channelCount} {GetVariableNameForSlot(k_OutputSlotId)} = {GetFunctionName()}({uv}.xy);");
  147. }
  148. public bool RequiresNDCPosition(ShaderStageCapability stageCapability = ShaderStageCapability.All) => true;
  149. public bool RequiresScreenPosition(ShaderStageCapability stageCapability = ShaderStageCapability.All) => true;
  150. }
  151. }