110 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			110 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using UnityEngine; | ||
|  | using UnityEngine.Rendering; | ||
|  | using UnityEngine.Rendering.RenderGraphModule; | ||
|  | using UnityEngine.Rendering.RenderGraphModule.Util; | ||
|  | using UnityEngine.Rendering.Universal; | ||
|  | 
 | ||
|  | // This pass creates an RTHandle and blits the camera color to it after rendering transparent objects. | ||
|  | // The RTHandle is then set as a global texture, which is available to shaders in the scene. The RTHandle is preserved in all frames while the renderer feature is running to create a recursive rendering effect. | ||
|  | public class BlitToRTHandlePass : ScriptableRenderPass | ||
|  | { | ||
|  |     private class PassData | ||
|  |     { | ||
|  |     } | ||
|  |      | ||
|  |     private ProfilingSampler m_ProfilingSampler = new ProfilingSampler("BlitToRTHandle_CopyColor"); | ||
|  |     private RTHandle m_InputHandle; | ||
|  |     private RTHandle m_OutputHandle; | ||
|  |     private const string k_OutputName = "_CopyColorTexture"; | ||
|  |     private static readonly int m_OutputId = Shader.PropertyToID(k_OutputName); | ||
|  |     private Material m_Material; | ||
|  | 
 | ||
|  |     public BlitToRTHandlePass(RenderPassEvent evt, Material mat) | ||
|  |     { | ||
|  |         renderPassEvent = evt; | ||
|  |         m_Material = mat; | ||
|  |     } | ||
|  | 
 | ||
|  | #pragma warning disable 618, 672 // Type or member is obsolete, Member overrides obsolete member | ||
|  | 
 | ||
|  |     // Unity calls the Configure method in the Compatibility mode (non-RenderGraph path) | ||
|  |     public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) | ||
|  |     { | ||
|  |         // Configure the custom RTHandle | ||
|  |         var desc = cameraTextureDescriptor; | ||
|  |         desc.depthBufferBits = 0; | ||
|  |         desc.msaaSamples = 1; | ||
|  |         RenderingUtils.ReAllocateIfNeeded(ref m_OutputHandle, desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: k_OutputName ); | ||
|  | 
 | ||
|  |         // Set the RTHandle as the output target in the Compatibility mode | ||
|  |         ConfigureTarget(m_OutputHandle); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Unity calls the Execute method in the Compatibility mode | ||
|  |     public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) | ||
|  |     { | ||
|  |         // Set camera color as the input | ||
|  |         m_InputHandle = renderingData.cameraData.renderer.cameraColorTargetHandle; | ||
|  | 
 | ||
|  |         CommandBuffer cmd = CommandBufferPool.Get(); | ||
|  |         using (new ProfilingScope(cmd, m_ProfilingSampler)) | ||
|  |         { | ||
|  |             // Blit the input RTHandle to the output one | ||
|  |             Blitter.BlitCameraTexture(cmd, m_InputHandle, m_OutputHandle, m_Material, 0); | ||
|  | 
 | ||
|  |             // Make the output texture available for the shaders in the scene | ||
|  |             cmd.SetGlobalTexture(m_OutputId, m_OutputHandle.nameID); | ||
|  |         } | ||
|  |         context.ExecuteCommandBuffer(cmd); | ||
|  |         cmd.Clear(); | ||
|  |         CommandBufferPool.Release(cmd); | ||
|  |     } | ||
|  | 
 | ||
|  | #pragma warning restore 618, 672 | ||
|  | 
 | ||
|  |     // Unity calls the RecordRenderGraph method to add and configure one or more render passes in the render graph system. | ||
|  |     public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) | ||
|  |     { | ||
|  |         UniversalResourceData resourceData = frameData.Get<UniversalResourceData>(); | ||
|  |         UniversalCameraData cameraData = frameData.Get<UniversalCameraData>(); | ||
|  | 
 | ||
|  |         if (cameraData.camera.cameraType != CameraType.Game) | ||
|  |             return; | ||
|  | 
 | ||
|  |         // Create the custom RTHandle | ||
|  |         var desc = cameraData.cameraTargetDescriptor; | ||
|  |         desc.depthBufferBits = 0; | ||
|  |         desc.msaaSamples = 1; | ||
|  |         RenderingUtils.ReAllocateHandleIfNeeded(ref m_OutputHandle, desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: k_OutputName ); | ||
|  |          | ||
|  |         // Make the output texture available for the shaders in the scene. | ||
|  |         // In this sample the output texture is used recursively by the subsequent frames, so it must stay in memory while the renderer feature is running. | ||
|  |         // A TextureHandle object is discarded after each frame, that's why we cannot bind it as a global texture using the RenderGraph API (builder.SetGlobalTextureAfterPass). | ||
|  |         // Instead, we bind the RTHandle as a global texture using the shader API, because the RTHandle is not managed by the render graph system. | ||
|  |         Shader.SetGlobalTexture(m_OutputId, m_OutputHandle); | ||
|  | 
 | ||
|  |         // Set camera color as a texture resource for this render graph instance | ||
|  |         TextureHandle source = resourceData.activeColorTexture; | ||
|  | 
 | ||
|  |         // Set RTHandle as a texture resource for this render graph instance | ||
|  |         TextureHandle destination = renderGraph.ImportTexture(m_OutputHandle); | ||
|  |          | ||
|  |         if (!source.IsValid() || !destination.IsValid()) | ||
|  |             return; | ||
|  |          | ||
|  |         // Blit the input texture to the destination texture | ||
|  |         RenderGraphUtils.BlitMaterialParameters para = new(source, destination, Blitter.GetBlitMaterial(TextureDimension.Tex2D), 0); | ||
|  |         renderGraph.AddBlitPass(para, "BlitToRTHandle_CopyColor"); | ||
|  | 
 | ||
|  |         // In this example the pass executes after rendering transparent objects, and the transparent objects are reading the destination texture. | ||
|  |         // The following code sets the TextureHandle as the camera color target to avoid visual artefacts. | ||
|  |         resourceData.cameraColor = destination; | ||
|  |     } | ||
|  | 
 | ||
|  |     public void Dispose() | ||
|  |     { | ||
|  |         m_InputHandle?.Release(); | ||
|  |         m_OutputHandle?.Release(); | ||
|  |     } | ||
|  | } |