注意:Unity 不再开发或改进不使用Render Graph API 的渲染路径。在开发新的图形功能时,请改用 Render Graph API。要使用此页面上的说明,请在 URP 图形设置(项目设置 (Project Settings) > 图形 (Graphics))中启用兼容性模式(禁用 Render Graph)(Compatibility Mode (Render Graph Disabled))。
以下示例是执行以下步骤的 ScriptableRenderPass 实例:
RenderTextureDescriptor API 创建临时渲染纹理。RTHandle 和 Blit API 将自定义着色器的两个通道应用于摄像机输出。编写可编程渲染通道后,可使用以下方法之一注入渲染通道:
本节演示如何创建可编程渲染通道。
创建一段新的 C# 脚本并将其命名为 RedTintRenderPass.cs。
在脚本中,删除 Unity 在 RedTintRenderPass 类中插入的代码。添加以下 using 指令:
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
创建继承自 ScriptableRenderPass 类的 RedTintRenderPass 类。
public class RedTintRenderPass : ScriptableRenderPass
将 Execute 方法添加到类中。Unity 每帧调用此方法,每个摄像机调用一次。此方法可用于实现可编程渲染通道的渲染逻辑。
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{ }
以下是本节中 RedTintRenderPass.cs 文件的完整代码。
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class RedTintRenderPass : ScriptableRenderPass
{
public override void Execute(ScriptableRenderContext context,
ref RenderingData renderingData)
{
}
}
为材质添加一个字段以及使用该字段的构造函数。
private Material material;
public RedTintRenderPass(Material material)
{
this.material = material;
}
添加 RenderTextureDescriptor 字段并在构造函数中将其初始化:
using UnityEngine;
private RenderTextureDescriptor textureDescriptor;
public RedTintRenderPass(Material material)
{
this.material = material;
textureDescriptor = new RenderTextureDescriptor(Screen.width,
Screen.height, RenderTextureFormat.Default, 0);
}
声明 RTHandle 字段以存储对临时红色色调纹理的引用。
private RTHandle textureHandle;
实现 Configure 方法。Unity 在执行渲染通道之前调用此方法。
public override void Configure(CommandBuffer cmd,
RenderTextureDescriptor cameraTextureDescriptor)
{
//Set the red tint texture size to be the same as the camera target size.
textureDescriptor.width = cameraTextureDescriptor.width;
textureDescriptor.height = cameraTextureDescriptor.height;
//Check if the descriptor has changed, and reallocate the RTHandle if necessary.
RenderingUtils.ReAllocateIfNeeded(ref textureHandle, textureDescriptor);
}
使用__ Blit__“位块传输 (Bit Block Transfer)”的简写。blit 操作是将数据块从内存中的一个位置传输到另一个位置的过程。
See in Glossary 方法可将自定义着色器中的两个渲染通道应用于摄像机输出。
public override void Execute(ScriptableRenderContext context,
ref RenderingData renderingData)
{
//Get a CommandBuffer from pool.
CommandBuffer cmd = CommandBufferPool.Get();
RTHandle cameraTargetHandle =
renderingData.cameraData.renderer.cameraColorTargetHandle;
// Blit from the camera target to the temporary render texture,
// using the first shader pass.
Blit(cmd, cameraTargetHandle, textureHandle, material, 0);
// Blit from the temporary render texture to the camera target,
// using the second shader pass.
Blit(cmd, textureHandle, cameraTargetHandle, material, 1);
//Execute the command buffer and release it back to the pool.
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
实现在渲染通道执行后销毁材质和临时渲染纹理的 Dispose 方法。
public void Dispose()
{
#if UNITY_EDITOR
if (EditorApplication.isPlaying)
{
Object.Destroy(material);
}
else
{
Object.DestroyImmediate(material);
}
#else
Object.Destroy(material);
#endif
if (textureHandle != null) textureHandle.Release();
}
以下是自定义渲染通道脚本的完整代码。
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class RedTintRenderPass : ScriptableRenderPass
{
private Material material;
private RenderTextureDescriptor textureDescriptor;
private RTHandle textureHandle;
public RedTintRenderPass(Material material)
{
this.material = material;
textureDescriptor = new RenderTextureDescriptor(Screen.width,
Screen.height, RenderTextureFormat.Default, 0);
}
public override void Configure(CommandBuffer cmd,
RenderTextureDescriptor cameraTextureDescriptor)
{
// Set the texture size to be the same as the camera target size.
textureDescriptor.width = cameraTextureDescriptor.width;
textureDescriptor.height = cameraTextureDescriptor.height;
// Check if the descriptor has changed, and reallocate the RTHandle if necessary
RenderingUtils.ReAllocateIfNeeded(ref textureHandle, textureDescriptor);
}
public override void Execute(ScriptableRenderContext context,
ref RenderingData renderingData)
{
//Get a CommandBuffer from pool.
CommandBuffer cmd = CommandBufferPool.Get();
RTHandle cameraTargetHandle =
renderingData.cameraData.renderer.cameraColorTargetHandle;
// Blit from the camera target to the temporary render texture,
// using the first shader pass.
Blit(cmd, cameraTargetHandle, textureHandle, material, 0);
// Blit from the temporary render texture to the camera target,
// using the second shader pass.
Blit(cmd, textureHandle, cameraTargetHandle, material, 1);
//Execute the command buffer and release it back to the pool.
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public void Dispose()
{
#if UNITY_EDITOR
if (EditorApplication.isPlaying)
{
Object.Destroy(material);
}
else
{
Object.DestroyImmediate(material);
}
#else
Object.Destroy(material);
#endif
if (textureHandle != null) textureHandle.Release();
}
}
本节包含用于实现红色色调效果的自定义着色器的代码。
Shader "CustomEffects/RedTint"
{
HLSLINCLUDE
#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"
float4 RedTint (Varyings input) : SV_Target
{
float3 color = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord).rgb;
return float4(1, color.gb, 1);
}
float4 SimpleBlit (Varyings input) : SV_Target
{
float3 color = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord).rgb;
return float4(color.rgb, 1);
}
ENDHLSL
SubShader
{
Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "RedTint"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RedTint
ENDHLSL
}
Pass
{
Name "SimpleBlit"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment SimpleBlit
ENDHLSL
}
}
}