FinalBlitPass.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. namespace UnityEngine.Rendering.Universal.Internal
  2. {
  3. /// <summary>
  4. /// Copy the given color target to the current camera target
  5. ///
  6. /// You can use this pass to copy the result of rendering to
  7. /// the camera target. The pass takes the screen viewport into
  8. /// consideration.
  9. /// </summary>
  10. public class FinalBlitPass : ScriptableRenderPass
  11. {
  12. RenderTargetIdentifier m_Source;
  13. Material m_BlitMaterial;
  14. public FinalBlitPass(RenderPassEvent evt, Material blitMaterial)
  15. {
  16. base.profilingSampler = new ProfilingSampler(nameof(FinalBlitPass));
  17. base.useNativeRenderPass = false;
  18. m_BlitMaterial = blitMaterial;
  19. renderPassEvent = evt;
  20. }
  21. /// <summary>
  22. /// Configure the pass
  23. /// </summary>
  24. /// <param name="baseDescriptor"></param>
  25. /// <param name="colorHandle"></param>
  26. public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorHandle)
  27. {
  28. m_Source = colorHandle.id;
  29. }
  30. /// <inheritdoc/>
  31. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  32. {
  33. if (m_BlitMaterial == null)
  34. {
  35. Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_BlitMaterial, GetType().Name);
  36. return;
  37. }
  38. // Note: We need to get the cameraData.targetTexture as this will get the targetTexture of the camera stack.
  39. // Overlay cameras need to output to the target described in the base camera while doing camera stack.
  40. ref CameraData cameraData = ref renderingData.cameraData;
  41. RenderTargetIdentifier cameraTarget = (cameraData.targetTexture != null) ? new RenderTargetIdentifier(cameraData.targetTexture) : BuiltinRenderTextureType.CameraTarget;
  42. bool isSceneViewCamera = cameraData.isSceneViewCamera;
  43. CommandBuffer cmd = CommandBufferPool.Get();
  44. if (m_Source == cameraData.renderer.GetCameraColorFrontBuffer(cmd))
  45. {
  46. m_Source = renderingData.cameraData.renderer.cameraColorTarget;
  47. }
  48. using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.FinalBlit)))
  49. {
  50. GetActiveDebugHandler(renderingData)?.UpdateShaderGlobalPropertiesForFinalValidationPass(cmd, ref cameraData, true);
  51. CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LinearToSRGBConversion,
  52. cameraData.requireSrgbConversion);
  53. cmd.SetGlobalTexture(ShaderPropertyId.sourceTex, m_Source);
  54. #if ENABLE_VR && ENABLE_XR_MODULE
  55. if (cameraData.xr.enabled)
  56. {
  57. int depthSlice = cameraData.xr.singlePassEnabled ? -1 : cameraData.xr.GetTextureArraySlice();
  58. cameraTarget =
  59. new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, depthSlice);
  60. CoreUtils.SetRenderTarget(
  61. cmd,
  62. cameraTarget,
  63. RenderBufferLoadAction.Load,
  64. RenderBufferStoreAction.Store,
  65. ClearFlag.None,
  66. Color.black);
  67. cmd.SetViewport(cameraData.pixelRect);
  68. // We y-flip if
  69. // 1) we are bliting from render texture to back buffer(UV starts at bottom) and
  70. // 2) renderTexture starts UV at top
  71. bool yflip = !cameraData.xr.renderTargetIsRenderTexture && SystemInfo.graphicsUVStartsAtTop;
  72. Vector4 scaleBias = yflip ? new Vector4(1, -1, 0, 1) : new Vector4(1, 1, 0, 0);
  73. cmd.SetGlobalVector(ShaderPropertyId.scaleBias, scaleBias);
  74. cmd.DrawProcedural(Matrix4x4.identity, m_BlitMaterial, 0, MeshTopology.Quads, 4);
  75. }
  76. else
  77. #endif
  78. if (isSceneViewCamera || cameraData.isDefaultViewport)
  79. {
  80. // This set render target is necessary so we change the LOAD state to DontCare.
  81. cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget,
  82. RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, // color
  83. RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); // depth
  84. cmd.Blit(m_Source, cameraTarget, m_BlitMaterial);
  85. cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
  86. }
  87. else
  88. {
  89. // TODO: Final blit pass should always blit to backbuffer. The first time we do we don't need to Load contents to tile.
  90. // We need to keep in the pipeline of first render pass to each render target to properly set load/store actions.
  91. // meanwhile we set to load so split screen case works.
  92. CoreUtils.SetRenderTarget(
  93. cmd,
  94. cameraTarget,
  95. RenderBufferLoadAction.Load,
  96. RenderBufferStoreAction.Store,
  97. ClearFlag.None,
  98. Color.black);
  99. Camera camera = cameraData.camera;
  100. cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
  101. cmd.SetViewport(cameraData.pixelRect);
  102. cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_BlitMaterial);
  103. cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
  104. cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
  105. }
  106. }
  107. context.ExecuteCommandBuffer(cmd);
  108. CommandBufferPool.Release(cmd);
  109. }
  110. }
  111. }