설명 없음
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.

HDRDebugViewPass.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. using System;
  2. using UnityEngine.Experimental.Rendering;
  3. using UnityEngine.Rendering.RenderGraphModule;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. /// <summary>
  7. /// Generate HDR debug data into the given color target
  8. /// </summary>
  9. internal class HDRDebugViewPass : ScriptableRenderPass
  10. {
  11. private enum HDRDebugPassId
  12. {
  13. CIExyPrepass = 0,
  14. DebugViewPass = 1
  15. }
  16. PassDataCIExy m_PassDataCIExy;
  17. PassDataDebugView m_PassDataDebugView;
  18. RTHandle m_CIExyTarget; // xyBuffer;
  19. RTHandle m_PassthroughRT;
  20. Material m_material;
  21. /// <summary>
  22. /// Creates a new <c>HDRDebugViewPass</c> instance.
  23. /// </summary>
  24. /// <param name="mat">The <c>Material</c> to use.</param>
  25. /// <seealso cref="RenderPassEvent"/>
  26. public HDRDebugViewPass(Material mat)
  27. {
  28. base.profilingSampler = new ProfilingSampler(nameof(HDRDebugViewPass));
  29. renderPassEvent = RenderPassEvent.AfterRendering + 3;
  30. m_PassDataCIExy = new PassDataCIExy() { material = mat };
  31. m_PassDataDebugView = new PassDataDebugView() { material = mat };
  32. m_material = mat;
  33. // Disabling native render passes (for non-RG) because it renders to 2 different render targets
  34. useNativeRenderPass = false;
  35. }
  36. // Common to RenderGraph and non-RenderGraph paths
  37. private class PassDataCIExy
  38. {
  39. internal Material material;
  40. internal Vector4 luminanceParameters;
  41. internal TextureHandle srcColor;
  42. internal TextureHandle xyBuffer;
  43. internal TextureHandle passThrough;
  44. }
  45. private class PassDataDebugView
  46. {
  47. internal Material material;
  48. internal HDRDebugMode hdrDebugMode;
  49. internal UniversalCameraData cameraData;
  50. internal Vector4 luminanceParameters;
  51. internal TextureHandle overlayUITexture;
  52. internal TextureHandle xyBuffer;
  53. internal TextureHandle srcColor;
  54. internal TextureHandle dstColor;
  55. }
  56. public static void ConfigureDescriptorForCIEPrepass(ref RenderTextureDescriptor descriptor)
  57. {
  58. descriptor.graphicsFormat = GraphicsFormat.R32_SFloat;
  59. descriptor.width = descriptor.height = ShaderConstants._SizeOfHDRXYMapping;
  60. descriptor.useMipMap = false;
  61. descriptor.autoGenerateMips = false;
  62. descriptor.useDynamicScale = true;
  63. descriptor.depthBufferBits = (int)DepthBits.None;
  64. descriptor.enableRandomWrite = true;
  65. descriptor.msaaSamples = 1;
  66. descriptor.dimension = TextureDimension.Tex2D;
  67. descriptor.vrUsage = VRTextureUsage.None; // We only need one for both eyes in VR
  68. }
  69. internal static Vector4 GetLuminanceParameters(UniversalCameraData cameraData)
  70. {
  71. var luminanceParams = Vector4.zero;
  72. if (cameraData.isHDROutputActive)
  73. {
  74. Tonemapping tonemapping = VolumeManager.instance.stack.GetComponent<Tonemapping>();
  75. UniversalRenderPipeline.GetHDROutputLuminanceParameters(cameraData.hdrDisplayInformation, cameraData.hdrDisplayColorGamut, tonemapping, out luminanceParams);
  76. }
  77. else
  78. {
  79. luminanceParams.z = 1.0f;
  80. }
  81. return luminanceParams;
  82. }
  83. private static void ExecuteCIExyPrepass(CommandBuffer cmd, PassDataCIExy data, RTHandle sourceTexture, RTHandle xyTarget, RTHandle destTexture)
  84. {
  85. using (new ProfilingScope(cmd, new ProfilingSampler("Generate HDR DebugView CIExy")))
  86. {
  87. CoreUtils.SetRenderTarget(cmd, destTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare, ClearFlag.None, Color.clear);
  88. Vector4 debugParameters = new Vector4(ShaderConstants._SizeOfHDRXYMapping, ShaderConstants._SizeOfHDRXYMapping, 0, 0);
  89. cmd.SetRandomWriteTarget(ShaderConstants._CIExyUAVIndex, xyTarget);
  90. data.material.SetVector(ShaderConstants._HDRDebugParamsId, debugParameters);
  91. data.material.SetVector(ShaderPropertyId.hdrOutputLuminanceParams, data.luminanceParameters);
  92. Vector2 viewportScale = sourceTexture.useScaling ? new Vector2(sourceTexture.rtHandleProperties.rtHandleScale.x, sourceTexture.rtHandleProperties.rtHandleScale.y) : Vector2.one;
  93. Blitter.BlitTexture(cmd, sourceTexture, viewportScale, data.material, 0);
  94. cmd.ClearRandomWriteTargets();
  95. }
  96. }
  97. private static void ExecuteHDRDebugViewFinalPass(RasterCommandBuffer cmd, PassDataDebugView data, RTHandle sourceTexture, RTHandle destination, RTHandle xyTarget)
  98. {
  99. using (new ProfilingScope(cmd, new ProfilingSampler("HDR DebugView")))
  100. {
  101. if (data.cameraData.isHDROutputActive)
  102. {
  103. HDROutputUtils.ConfigureHDROutput(data.material, data.cameraData.hdrDisplayColorGamut, HDROutputUtils.Operation.ColorEncoding);
  104. }
  105. data.material.SetTexture(ShaderConstants._xyTextureId, xyTarget);
  106. Vector4 debugParameters = new Vector4(ShaderConstants._SizeOfHDRXYMapping, ShaderConstants._SizeOfHDRXYMapping, 0, 0);
  107. data.material.SetVector(ShaderConstants._HDRDebugParamsId, debugParameters);
  108. data.material.SetVector(ShaderPropertyId.hdrOutputLuminanceParams, data.luminanceParameters);
  109. data.material.SetInteger(ShaderConstants._DebugHDRModeId, (int)data.hdrDebugMode);
  110. Vector4 scaleBias = RenderingUtils.GetFinalBlitScaleBias(sourceTexture, destination, data.cameraData);
  111. RenderTargetIdentifier cameraTarget = BuiltinRenderTextureType.CameraTarget;
  112. #if ENABLE_VR && ENABLE_XR_MODULE
  113. if (data.cameraData.xr.enabled)
  114. cameraTarget = data.cameraData.xr.renderTarget;
  115. #endif
  116. if (destination.nameID == cameraTarget || data.cameraData.targetTexture != null)
  117. cmd.SetViewport(data.cameraData.pixelRect);
  118. Blitter.BlitTexture(cmd, sourceTexture, scaleBias, data.material, 1);
  119. }
  120. }
  121. // Non-RenderGraph path
  122. public void Dispose()
  123. {
  124. m_CIExyTarget?.Release();
  125. m_PassthroughRT?.Release();
  126. }
  127. /// <summary>
  128. /// Configure the pass
  129. /// </summary>
  130. /// <param name="cameraData">Descriptor for the color buffer.</param>
  131. /// <param name="hdrdebugMode">Active DebugMode for HDR.</param>
  132. public void Setup(UniversalCameraData cameraData, HDRDebugMode hdrdebugMode)
  133. {
  134. m_PassDataDebugView.hdrDebugMode = hdrdebugMode;
  135. RenderTextureDescriptor descriptor = cameraData.cameraTargetDescriptor;
  136. DebugHandler.ConfigureColorDescriptorForDebugScreen(ref descriptor, cameraData.pixelWidth, cameraData.pixelHeight);
  137. RenderingUtils.ReAllocateHandleIfNeeded(ref m_PassthroughRT, descriptor, name: "_HDRDebugDummyRT");
  138. RenderTextureDescriptor descriptorCIE = cameraData.cameraTargetDescriptor;
  139. HDRDebugViewPass.ConfigureDescriptorForCIEPrepass(ref descriptorCIE);
  140. RenderingUtils.ReAllocateHandleIfNeeded(ref m_CIExyTarget, descriptorCIE, name: "_xyBuffer");
  141. }
  142. /// <inheritdoc/>
  143. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  144. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  145. {
  146. UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
  147. var cmd = renderingData.commandBuffer;
  148. m_PassDataCIExy.luminanceParameters = m_PassDataDebugView.luminanceParameters = GetLuminanceParameters(cameraData);
  149. m_PassDataDebugView.cameraData = cameraData;
  150. var sourceTexture = renderingData.cameraData.renderer.cameraColorTargetHandle;
  151. var cameraTarget = RenderingUtils.GetCameraTargetIdentifier(ref renderingData);
  152. // Get RTHandle alias to use RTHandle apis
  153. RTHandleStaticHelpers.SetRTHandleStaticWrapper(cameraTarget);
  154. var cameraTargetHandle = RTHandleStaticHelpers.s_RTHandleWrapper;
  155. m_material.enabledKeywords = null;
  156. GetActiveDebugHandler(cameraData)?.UpdateShaderGlobalPropertiesForFinalValidationPass(cmd, cameraData, true);
  157. CoreUtils.SetRenderTarget(cmd, m_CIExyTarget, ClearFlag.Color, Color.clear);
  158. ExecutePass(cmd, m_PassDataCIExy, m_PassDataDebugView, sourceTexture, m_CIExyTarget, cameraTargetHandle);
  159. }
  160. private void ExecutePass(CommandBuffer cmd, PassDataCIExy dataCIExy, PassDataDebugView dataDebugView, RTHandle sourceTexture, RTHandle xyTarget, RTHandle destTexture)
  161. {
  162. RasterCommandBuffer rasterCmd = CommandBufferHelpers.GetRasterCommandBuffer(cmd);
  163. //CIExyPrepass
  164. bool requiresCIExyData = dataDebugView.hdrDebugMode != HDRDebugMode.ValuesAbovePaperWhite;
  165. if (requiresCIExyData)
  166. {
  167. ExecuteCIExyPrepass(cmd, dataCIExy, sourceTexture, xyTarget, m_PassthroughRT);
  168. }
  169. //HDR DebugView - should always be the last stack of the camera
  170. CoreUtils.SetRenderTarget(cmd, destTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.None, Color.clear);
  171. ExecuteHDRDebugViewFinalPass(rasterCmd, dataDebugView, sourceTexture, destTexture, xyTarget);
  172. // Disable obsolete warning for internal usage
  173. #pragma warning disable CS0618
  174. dataDebugView.cameraData.renderer.ConfigureCameraTarget(destTexture, destTexture);
  175. #pragma warning restore CS0618
  176. }
  177. //RenderGraph path
  178. internal void RenderHDRDebug(RenderGraph renderGraph, UniversalCameraData cameraData, TextureHandle srcColor, TextureHandle overlayUITexture, TextureHandle dstColor, HDRDebugMode hdrDebugMode)
  179. {
  180. bool requiresCIExyData = hdrDebugMode != HDRDebugMode.ValuesAbovePaperWhite;
  181. Vector4 luminanceParameters = GetLuminanceParameters(cameraData);
  182. TextureHandle intermediateRT = srcColor;
  183. TextureHandle xyBuffer = TextureHandle.nullHandle;
  184. if (requiresCIExyData)
  185. {
  186. RenderTextureDescriptor descriptor = cameraData.cameraTargetDescriptor;
  187. DebugHandler.ConfigureColorDescriptorForDebugScreen(ref descriptor, cameraData.pixelWidth, cameraData.pixelHeight);
  188. intermediateRT = UniversalRenderer.CreateRenderGraphTexture(renderGraph, descriptor, "_HDRDebugDummyRT", false);
  189. ConfigureDescriptorForCIEPrepass(ref descriptor);
  190. xyBuffer = UniversalRenderer.CreateRenderGraphTexture(renderGraph, descriptor, "_xyBuffer", true);
  191. // Using low level pass because of random UAV support, and since this is a debug view, we don't care much about merging passes or optimizing for TBDR.
  192. // This could be a compute pass (like in HDRP) but doing it in pixel is compatible with devices that might support HDR output but not compute shaders.
  193. using (var builder = renderGraph.AddUnsafePass<PassDataCIExy>("Generate HDR DebugView CIExy", out var passData, base.profilingSampler))
  194. {
  195. passData.material = m_material;
  196. passData.luminanceParameters = luminanceParameters;
  197. passData.srcColor = srcColor;
  198. builder.UseTexture(srcColor);
  199. passData.xyBuffer = xyBuffer;
  200. builder.UseTexture(xyBuffer, AccessFlags.Write);
  201. passData.passThrough = intermediateRT;
  202. builder.UseTexture(intermediateRT, AccessFlags.Write);
  203. builder.SetRenderFunc((PassDataCIExy data, UnsafeGraphContext context) =>
  204. {
  205. ExecuteCIExyPrepass(CommandBufferHelpers.GetNativeCommandBuffer(context.cmd), data, data.srcColor, data.xyBuffer, data.passThrough);
  206. });
  207. }
  208. }
  209. using (var builder = renderGraph.AddRasterRenderPass<PassDataDebugView>("HDR DebugView", out var passData, base.profilingSampler))
  210. {
  211. passData.material = m_material;
  212. passData.hdrDebugMode = hdrDebugMode;
  213. passData.luminanceParameters = luminanceParameters;
  214. passData.cameraData = cameraData;
  215. if (requiresCIExyData)
  216. {
  217. passData.xyBuffer = xyBuffer;
  218. builder.UseTexture(xyBuffer);
  219. }
  220. passData.srcColor = srcColor;
  221. builder.UseTexture(srcColor);
  222. passData.dstColor = dstColor;
  223. builder.SetRenderAttachment(dstColor, 0, AccessFlags.WriteAll);
  224. if (overlayUITexture.IsValid())
  225. {
  226. passData.overlayUITexture = overlayUITexture;
  227. builder.UseTexture(overlayUITexture);
  228. }
  229. builder.SetRenderFunc((PassDataDebugView data, RasterGraphContext context) =>
  230. {
  231. data.material.enabledKeywords = null;
  232. ExecuteHDRDebugViewFinalPass(context.cmd, data, data.srcColor, data.dstColor, data.xyBuffer);
  233. });
  234. }
  235. }
  236. internal class ShaderConstants
  237. {
  238. public static readonly int _DebugHDRModeId = Shader.PropertyToID("_DebugHDRMode");
  239. public static readonly int _HDRDebugParamsId = Shader.PropertyToID("_HDRDebugParams");
  240. public static readonly int _xyTextureId = Shader.PropertyToID("_xyBuffer");
  241. public static readonly int _SizeOfHDRXYMapping = 512;
  242. public static readonly int _CIExyUAVIndex = 1;
  243. }
  244. }
  245. }