CopyColorPass.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System;
  2. namespace UnityEngine.Rendering.Universal.Internal
  3. {
  4. /// <summary>
  5. /// Copy the given color buffer to the given destination color buffer.
  6. ///
  7. /// You can use this pass to copy a color buffer to the destination,
  8. /// so you can use it later in rendering. For example, you can copy
  9. /// the opaque texture to use it for distortion effects.
  10. /// </summary>
  11. public class CopyColorPass : ScriptableRenderPass
  12. {
  13. int m_SampleOffsetShaderHandle;
  14. Material m_SamplingMaterial;
  15. Downsampling m_DownsamplingMethod;
  16. Material m_CopyColorMaterial;
  17. private RenderTargetIdentifier source { get; set; }
  18. private RenderTargetHandle destination { get; set; }
  19. /// <summary>
  20. /// Create the CopyColorPass
  21. /// </summary>
  22. public CopyColorPass(RenderPassEvent evt, Material samplingMaterial, Material copyColorMaterial = null)
  23. {
  24. base.profilingSampler = new ProfilingSampler(nameof(CopyColorPass));
  25. m_SamplingMaterial = samplingMaterial;
  26. m_CopyColorMaterial = copyColorMaterial;
  27. m_SampleOffsetShaderHandle = Shader.PropertyToID("_SampleOffset");
  28. renderPassEvent = evt;
  29. m_DownsamplingMethod = Downsampling.None;
  30. base.useNativeRenderPass = false;
  31. }
  32. /// <summary>
  33. /// Configure the pass with the source and destination to execute on.
  34. /// </summary>
  35. /// <param name="source">Source Render Target</param>
  36. /// <param name="destination">Destination Render Target</param>
  37. public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination, Downsampling downsampling)
  38. {
  39. this.source = source;
  40. this.destination = destination;
  41. m_DownsamplingMethod = downsampling;
  42. }
  43. public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
  44. {
  45. RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
  46. descriptor.msaaSamples = 1;
  47. descriptor.depthBufferBits = 0;
  48. if (m_DownsamplingMethod == Downsampling._2xBilinear)
  49. {
  50. descriptor.width /= 2;
  51. descriptor.height /= 2;
  52. }
  53. else if (m_DownsamplingMethod == Downsampling._4xBox || m_DownsamplingMethod == Downsampling._4xBilinear)
  54. {
  55. descriptor.width /= 4;
  56. descriptor.height /= 4;
  57. }
  58. cmd.GetTemporaryRT(destination.id, descriptor, m_DownsamplingMethod == Downsampling.None ? FilterMode.Point : FilterMode.Bilinear);
  59. }
  60. /// <inheritdoc/>
  61. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  62. {
  63. if (m_SamplingMaterial == null)
  64. {
  65. Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_SamplingMaterial, GetType().Name);
  66. return;
  67. }
  68. CommandBuffer cmd = CommandBufferPool.Get();
  69. //It is possible that the given color target is now the frontbuffer
  70. if (source == renderingData.cameraData.renderer.GetCameraColorFrontBuffer(cmd))
  71. {
  72. source = renderingData.cameraData.renderer.cameraColorTarget;
  73. }
  74. using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.CopyColor)))
  75. {
  76. RenderTargetIdentifier opaqueColorRT = destination.Identifier();
  77. ScriptableRenderer.SetRenderTarget(cmd, opaqueColorRT, BuiltinRenderTextureType.CameraTarget, clearFlag,
  78. clearColor);
  79. bool useDrawProceduleBlit = renderingData.cameraData.xr.enabled;
  80. switch (m_DownsamplingMethod)
  81. {
  82. case Downsampling.None:
  83. RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
  84. break;
  85. case Downsampling._2xBilinear:
  86. RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
  87. break;
  88. case Downsampling._4xBox:
  89. m_SamplingMaterial.SetFloat(m_SampleOffsetShaderHandle, 2);
  90. RenderingUtils.Blit(cmd, source, opaqueColorRT, m_SamplingMaterial, 0, useDrawProceduleBlit);
  91. break;
  92. case Downsampling._4xBilinear:
  93. RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
  94. break;
  95. }
  96. }
  97. context.ExecuteCommandBuffer(cmd);
  98. CommandBufferPool.Release(cmd);
  99. }
  100. /// <inheritdoc/>
  101. public override void OnCameraCleanup(CommandBuffer cmd)
  102. {
  103. if (cmd == null)
  104. throw new ArgumentNullException("cmd");
  105. if (destination != RenderTargetHandle.CameraTarget)
  106. {
  107. cmd.ReleaseTemporaryRT(destination.id);
  108. destination = RenderTargetHandle.CameraTarget;
  109. }
  110. }
  111. }
  112. }