【從UnityURP開始探索游戲渲染】專欄-直達
自定義渲染通道是一種改變通用渲染管道(URP)如何渲染場景或場景中的對象的方法。自定義呈現通道(RenderPass)包含自己的Render代碼,可以在注入點將其添加到RenderPass中。
添加自定義呈現通道(RenderPass):
- 使用Scriptable render pass?API創建自定義render pass的代碼。
- 將自定的render pass注入到URP管線中的指定注入點中,有兩種方式:
- 用RenderPipelineManager?API注入自定義渲染通道
- 或者通過創建一個可腳本化的RendererFeature添加到URP渲染器中。
使用Scriptable render pass?API創建自定義render pass
-
Example custom render pass
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal;internal class ColorBlitPass : ScriptableRenderPass {ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit");Material m_Material;RTHandle m_CameraColorTarget;float m_Intensity;public ColorBlitPass(Material material){m_Material = material;renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;}public void SetTarget(RTHandle colorHandle, float intensity){m_CameraColorTarget = colorHandle;m_Intensity = intensity;}public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData){ConfigureTarget(m_CameraColorTarget);}public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){var cameraData = renderingData.cameraData;if (cameraData.camera.cameraType != CameraType.Game)return;if (m_Material == null)return;CommandBuffer cmd = CommandBufferPool.Get();using (new ProfilingScope(cmd, m_ProfilingSampler)){m_Material.SetFloat("_Intensity", m_Intensity);Blitter.BlitCameraTexture(cmd, m_CameraColorTarget, m_CameraColorTarget, m_Material, 0);}context.ExecuteCommandBuffer(cmd);cmd.Clear();CommandBufferPool.Release(cmd);} }
將自定的render pass注入到URP管線中的指定注入點中
用RenderPipelineManager?API注入自定義渲染通道
-
通過RenderPipelineManager的注入點委托提供執行時機,加上Camera的EnqueuePass方法注入自定義RenderPass。
public class EnqueuePass : MonoBehaviour {[SerializeField] private BlurSettings settings; private BlurRenderPass blurRenderPass;private void OnEnable(){...blurRenderPass = new BlurRenderPass(settings);// Subscribe the OnBeginCamera method to the beginCameraRendering event.RenderPipelineManager.beginCameraRendering += OnBeginCamera;}private void OnDisable(){RenderPipelineManager.beginCameraRendering -= OnBeginCamera;blurRenderPass.Dispose();...}private void OnBeginCamera(ScriptableRenderContext context, Camera cam){...// Use the EnqueuePass method to inject a custom render passcam.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(blurRenderPass);} }
創建一個可腳本化的RendererFeature
此示例執行將屏幕染成綠色的全屏blit。
-
要創建自定義渲染通道,創建一個名為ColorBlitPass.cs的新c#腳本,然后從示例自定義渲染通道部分粘貼代碼。
- 注意:這個例子使用了Blitter API。不要使用CommandBuffer。URP中的Blit API。更多信息請參考Blit。
- 使用上面定義好的定制Render Pass
-
要創建Scriptable RendererFeature,將自定義渲染通道添加到渲染循環中,請創建一個名為ColorBlitRendererFeature.cs的新c#腳本,然后將示例Scriptable RendererFeature部分中的代碼粘貼進來。
-
Example Scriptable Renderer Feature Scriptable Renderer Feature 添加 render pass 到渲染循環.
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal;internal class ColorBlitRendererFeature : ScriptableRendererFeature {public Shader m_Shader;public float m_Intensity;Material m_Material;ColorBlitPass m_RenderPass = null;public override void AddRenderPasses(ScriptableRenderer renderer,ref RenderingData renderingData){if (renderingData.cameraData.cameraType == CameraType.Game)renderer.EnqueuePass(m_RenderPass);}public override void SetupRenderPasses(ScriptableRenderer renderer,in RenderingData renderingData){if (renderingData.cameraData.cameraType == CameraType.Game){// Calling ConfigureInput with the ScriptableRenderPassInput.Color argument// ensures that the opaque texture is available to the Render Pass.m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color);m_RenderPass.SetTarget(renderer.cameraColorTargetHandle, m_Intensity);}}public override void Create(){m_Material = CoreUtils.CreateEngineMaterial(m_Shader);m_RenderPass = new ColorBlitPass(m_Material);}protected override void Dispose(bool disposing){CoreUtils.Destroy(m_Material);} }
-
-
要創建將像素染成綠色的著色器代碼,請創建一個著色器文件,然后從示例著色器部分粘貼代碼。
-
Example shader
-
著色器執行渲染的GPU端。它從相機中采樣顏色紋理,然后輸出綠色值設置為所選強度的顏色。
注意:與Blitter API一起使用的著色器必須是手工編碼的著色器。圖形著色器與Blitter API不兼容。Shader "ColorBlit" {SubShader{Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}LOD 100ZWrite Off Cull OffPass{Name "ColorBlitPass"HLSLPROGRAM#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"// The Blit.hlsl file provides the vertex shader (Vert),// the input structure (Attributes) and the output structure (Varyings)#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"#pragma vertex Vert#pragma fragment frag// Set the color texture from the camera as the input textureTEXTURE2D_X(_CameraOpaqueTexture);SAMPLER(sampler_CameraOpaqueTexture);// Set up an intensity parameterfloat _Intensity;half4 frag (Varyings input) : SV_Target{UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);// Sample the color from the input texturefloat4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, input.texcoord);// Output the color from the texture, with the green value set to the chosen intensityreturn color * float4(0, _Intensity, 0, 1);}ENDHLSL}} }
-
-
將ColorBlitRendererFeature添加到當前URP Renderer資源中。有關更多信息,請參閱向URP渲染器添加渲染器功能。
-
要更改亮度,請調整Color Blit Renderer Feature組件中的Intensity屬性。
注意:如果項目使用XR,為了使示例可視化,在項目中安裝MockHMD XR插件包,然后將渲染模式屬性設置為單通道實例化。
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/renderer-features/custom-rendering-pass-workflow-in-urp.html
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)