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.

258 lines
8.9 KiB

  1. using System.Collections.Generic;
  2. using UnityEngine.Rendering;
  3. namespace UnityEngine.PostProcessing
  4. {
  5. using Mode = BuiltinDebugViewsModel.Mode;
  6. public sealed class BuiltinDebugViewsComponent : PostProcessingComponentCommandBuffer<BuiltinDebugViewsModel>
  7. {
  8. static class Uniforms
  9. {
  10. internal static readonly int _DepthScale = Shader.PropertyToID("_DepthScale");
  11. internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
  12. internal static readonly int _Opacity = Shader.PropertyToID("_Opacity");
  13. internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
  14. internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2");
  15. internal static readonly int _Amplitude = Shader.PropertyToID("_Amplitude");
  16. internal static readonly int _Scale = Shader.PropertyToID("_Scale");
  17. }
  18. const string k_ShaderString = "Hidden/Post FX/Builtin Debug Views";
  19. enum Pass
  20. {
  21. Depth,
  22. Normals,
  23. MovecOpacity,
  24. MovecImaging,
  25. MovecArrows
  26. }
  27. ArrowArray m_Arrows;
  28. class ArrowArray
  29. {
  30. public Mesh mesh { get; private set; }
  31. public int columnCount { get; private set; }
  32. public int rowCount { get; private set; }
  33. public void BuildMesh(int columns, int rows)
  34. {
  35. // Base shape
  36. var arrow = new Vector3[6]
  37. {
  38. new Vector3(0f, 0f, 0f),
  39. new Vector3(0f, 1f, 0f),
  40. new Vector3(0f, 1f, 0f),
  41. new Vector3(-1f, 1f, 0f),
  42. new Vector3(0f, 1f, 0f),
  43. new Vector3(1f, 1f, 0f)
  44. };
  45. // make the vertex array
  46. int vcount = 6 * columns * rows;
  47. var vertices = new List<Vector3>(vcount);
  48. var uvs = new List<Vector2>(vcount);
  49. for (int iy = 0; iy < rows; iy++)
  50. {
  51. for (int ix = 0; ix < columns; ix++)
  52. {
  53. var uv = new Vector2(
  54. (0.5f + ix) / columns,
  55. (0.5f + iy) / rows
  56. );
  57. for (int i = 0; i < 6; i++)
  58. {
  59. vertices.Add(arrow[i]);
  60. uvs.Add(uv);
  61. }
  62. }
  63. }
  64. // make the index array
  65. var indices = new int[vcount];
  66. for (int i = 0; i < vcount; i++)
  67. indices[i] = i;
  68. // initialize the mesh object
  69. mesh = new Mesh { hideFlags = HideFlags.DontSave };
  70. mesh.SetVertices(vertices);
  71. mesh.SetUVs(0, uvs);
  72. mesh.SetIndices(indices, MeshTopology.Lines, 0);
  73. mesh.UploadMeshData(true);
  74. // update the properties
  75. columnCount = columns;
  76. rowCount = rows;
  77. }
  78. public void Release()
  79. {
  80. GraphicsUtils.Destroy(mesh);
  81. mesh = null;
  82. }
  83. }
  84. public override bool active
  85. {
  86. get
  87. {
  88. return model.IsModeActive(Mode.Depth)
  89. || model.IsModeActive(Mode.Normals)
  90. || model.IsModeActive(Mode.MotionVectors);
  91. }
  92. }
  93. public override DepthTextureMode GetCameraFlags()
  94. {
  95. var mode = model.settings.mode;
  96. var flags = DepthTextureMode.None;
  97. switch (mode)
  98. {
  99. case Mode.Normals:
  100. flags |= DepthTextureMode.DepthNormals;
  101. break;
  102. case Mode.MotionVectors:
  103. flags |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
  104. break;
  105. case Mode.Depth:
  106. flags |= DepthTextureMode.Depth;
  107. break;
  108. }
  109. return flags;
  110. }
  111. public override CameraEvent GetCameraEvent()
  112. {
  113. return model.settings.mode == Mode.MotionVectors
  114. ? CameraEvent.BeforeImageEffects
  115. : CameraEvent.BeforeImageEffectsOpaque;
  116. }
  117. public override string GetName()
  118. {
  119. return "Builtin Debug Views";
  120. }
  121. public override void PopulateCommandBuffer(CommandBuffer cb)
  122. {
  123. var settings = model.settings;
  124. var material = context.materialFactory.Get(k_ShaderString);
  125. material.shaderKeywords = null;
  126. if (context.isGBufferAvailable)
  127. material.EnableKeyword("SOURCE_GBUFFER");
  128. switch (settings.mode)
  129. {
  130. case Mode.Depth:
  131. DepthPass(cb);
  132. break;
  133. case Mode.Normals:
  134. DepthNormalsPass(cb);
  135. break;
  136. case Mode.MotionVectors:
  137. MotionVectorsPass(cb);
  138. break;
  139. }
  140. context.Interrupt();
  141. }
  142. void DepthPass(CommandBuffer cb)
  143. {
  144. var material = context.materialFactory.Get(k_ShaderString);
  145. var settings = model.settings.depth;
  146. cb.SetGlobalFloat(Uniforms._DepthScale, 1f / settings.scale);
  147. cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Depth);
  148. }
  149. void DepthNormalsPass(CommandBuffer cb)
  150. {
  151. var material = context.materialFactory.Get(k_ShaderString);
  152. cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Normals);
  153. }
  154. void MotionVectorsPass(CommandBuffer cb)
  155. {
  156. #if UNITY_EDITOR
  157. // Don't render motion vectors preview when the editor is not playing as it can in some
  158. // cases results in ugly artifacts (i.e. when resizing the game view).
  159. if (!Application.isPlaying)
  160. return;
  161. #endif
  162. var material = context.materialFactory.Get(k_ShaderString);
  163. var settings = model.settings.motionVectors;
  164. // Blit the original source image
  165. int tempRT = Uniforms._TempRT;
  166. cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear);
  167. cb.SetGlobalFloat(Uniforms._Opacity, settings.sourceOpacity);
  168. cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget);
  169. cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, material, (int)Pass.MovecOpacity);
  170. // Motion vectors (imaging)
  171. if (settings.motionImageOpacity > 0f && settings.motionImageAmplitude > 0f)
  172. {
  173. int tempRT2 = Uniforms._TempRT2;
  174. cb.GetTemporaryRT(tempRT2, context.width, context.height, 0, FilterMode.Bilinear);
  175. cb.SetGlobalFloat(Uniforms._Opacity, settings.motionImageOpacity);
  176. cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionImageAmplitude);
  177. cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
  178. cb.Blit(tempRT, tempRT2, material, (int)Pass.MovecImaging);
  179. cb.ReleaseTemporaryRT(tempRT);
  180. tempRT = tempRT2;
  181. }
  182. // Motion vectors (arrows)
  183. if (settings.motionVectorsOpacity > 0f && settings.motionVectorsAmplitude > 0f)
  184. {
  185. PrepareArrows();
  186. float sy = 1f / settings.motionVectorsResolution;
  187. float sx = sy * context.height / context.width;
  188. cb.SetGlobalVector(Uniforms._Scale, new Vector2(sx, sy));
  189. cb.SetGlobalFloat(Uniforms._Opacity, settings.motionVectorsOpacity);
  190. cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionVectorsAmplitude);
  191. cb.DrawMesh(m_Arrows.mesh, Matrix4x4.identity, material, 0, (int)Pass.MovecArrows);
  192. }
  193. cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
  194. cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget);
  195. cb.ReleaseTemporaryRT(tempRT);
  196. }
  197. void PrepareArrows()
  198. {
  199. int row = model.settings.motionVectors.motionVectorsResolution;
  200. int col = row * Screen.width / Screen.height;
  201. if (m_Arrows == null)
  202. m_Arrows = new ArrowArray();
  203. if (m_Arrows.columnCount != col || m_Arrows.rowCount != row)
  204. {
  205. m_Arrows.Release();
  206. m_Arrows.BuildMesh(col, row);
  207. }
  208. }
  209. public override void OnDisable()
  210. {
  211. if (m_Arrows != null)
  212. m_Arrows.Release();
  213. m_Arrows = null;
  214. }
  215. }
  216. }