此页面上的示例描述了如何创建一个自定义渲染器功能,该功能执行全屏 blit“位块传输”的简称。Blit 操作是将内存中的一块数据传输到另一块内存的过程。
请参阅 术语表.
注意:Unity 不再开发或改进不使用 渲染图 API 的渲染路径。在开发新的图形功能时,请使用渲染图 API。要使用此页面上的说明,请在 URP 图形设置中启用兼容模式(渲染图禁用)(项目设置 > 图形)。
此示例实现了以下解决方案
该 渲染通道 将不透明纹理 Blit 到当前渲染器的 相机颜色目标。渲染通道使用命令缓冲区为两只眼睛绘制全屏 网格Unity 中的主要图形基元。网格构成了 3D 世界的很大一部分。Unity 支持三角形或四边形多边形网格。Nurbs、Nurms、Subdiv 表面必须转换为多边形。 更多信息
请参阅 术语表.
该示例包括 着色器,它执行渲染的 GPU 侧。该 着色器在 GPU 上运行的程序。 更多信息
请参阅 术语表 使用 XR一个涵盖虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用程序的总称。支持这些形式的交互式应用程序的设备被称为 XR 设备。 更多信息
请参阅 术语表 采样器宏对颜色缓冲区进行采样。
此示例需要以下内容
要遵循此示例中的步骤,请创建一个包含以下 游戏对象Unity 场景中的基本对象,可以代表角色、道具、场景、相机、航路点等。游戏对象的功能由附加到它的组件定义。 更多信息
请参阅 术语表 的新 场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,您放置环境、障碍物和装饰,本质上是分块设计和构建您的游戏。 更多信息
请参阅 术语表
现在您拥有遵循此示例中步骤所需的场景。
本节假设您已创建了如 创建示例场景和游戏对象 一节中所述的场景。
请遵循以下步骤创建一个具有自定义 渲染通道 的 自定义渲染器功能。
创建一个新的 C# 脚本。将其命名为ColorBlitRendererFeature.cs
。此脚本实现自定义渲染器功能。
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
internal class ColorBlitRendererFeature : ScriptableRendererFeature
{
public Shader shader;
[Range(0f, 1f)] public float intensity = 1f;
Material m_Material;
ColorBlitPass m_RenderPass;
// Use this method to add one or more Render Passes into the rendering sequence of the renderer with the EnqueuePass method.
public override void AddRenderPasses(ScriptableRenderer renderer,
ref RenderingData renderingData)
{
if (m_Material == null)
return;
if (renderingData.cameraData.cameraType != CameraType.Game)
return;
m_RenderPass.SetIntensity(intensity);
renderer.EnqueuePass(m_RenderPass);
}
// Use the Create method to initialize the resources. This method only runs in the first frame.
// Use the Dispose method to clean up the resources before the renderer feature is disabled.
public override void Create()
{
m_Material = CoreUtils.CreateEngineMaterial(shader);
m_RenderPass = new ColorBlitPass(m_Material);
}
protected override void Dispose(bool disposing)
{
CoreUtils.Destroy(m_Material);
}
}
创建一个新的 C# 脚本。将其命名为ColorBlitPass.cs
。此脚本实现执行自定义 Blit 绘制调用的自定义渲染通道。
此渲染通道使用 AddBlitPass 执行 Blit 操作。
注意:不要在 URP XR 项目中使用
cmd.Blit
方法,因为该方法与 URP XR 集成存在兼容性问题。使用cmd.Blit
可能会隐式启用或禁用 XR 着色器关键字,从而破坏 XR SPI 渲染。
using UnityEngine;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule.Util;
public class ColorBlitPass : ScriptableRenderPass
{
private const string k_PassName = "ColorBlitPass";
private Material m_Material;
private float m_Intensity;
private static readonly int k_IntensityID = Shader.PropertyToID("_Intensity");
public ColorBlitPass(Material mat)
{
m_Material = mat;
renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
}
public void SetIntensity(float intensity)
{
m_Intensity = intensity;
}
// Use the RecordRenderGraph method to configure the input and output parameters for the AddBlitPass method and execute the AddBlitPass method.
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
var resourceData = frameData.Get<UniversalResourceData>();
// The following line ensures that the render pass doesn't blit
// from the back buffer.
if (resourceData.isActiveTargetBackBuffer)
{
Debug.LogError($"Skipping render pass. ColorBlitRendererFeature requires an intermediate ColorTexture, we can't use the BackBuffer as a texture input.");
return;
}
var source = resourceData.activeColorTexture;
// Define the texture descriptor for creating the destination render graph texture.
var destinationDesc = renderGraph.GetTextureDesc(source);
destinationDesc.name = $"CameraColor-{k_PassName}";
destinationDesc.clearBuffer = false;
destinationDesc.depthBufferBits = 0;
// Create the texture.
TextureHandle destination = renderGraph.CreateTexture(destinationDesc);
// The AddBlitPass method adds the render graph pass that blits from the source to the destination texture.
RenderGraphUtils.BlitMaterialParameters para = new(source, destination, m_Material, 0);
para.material.SetFloat(k_IntensityID, m_Intensity);
renderGraph.AddBlitPass(para, passName: k_PassName);
// Use the destination texture as the camera texture to avoid the extra blit from the destination texture back to the camera texture.
resourceData.cameraColor = destination;
}
}
创建执行 Blit 操作的着色器。将着色器文件命名为ColorBlit.shader
。顶点函数输出全屏四边形位置。片段函数对颜色缓冲区进行采样,并将color * float4(0, _Intensity, 0, 1)
值返回到渲染目标。
Shader "ColorBlit"
{
SubShader
{
Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
ZWrite Off Cull Off
Pass
{
Name "ColorBlitPass"
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#pragma vertex Vert
#pragma fragment Frag
float _Intensity;
float4 Frag(Varyings input) : SV_Target
{
// This function handles the different ways XR platforms handle texture arrays.
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// Sample the texture using the SAMPLE_TEXTURE2D_X_LOD function
float2 uv = input.texcoord.xy;
half4 color = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearRepeat, uv, _BlitMipLevel);
// Modify the sampled color
return half4(0, _Intensity, 0, 1) * color;
}
ENDHLSL
}
}
}
将ColorBlitRendererFeature
添加到通用渲染器资源。
有关如何添加渲染器功能的信息,请参阅页面 如何将渲染器功能添加到渲染器。
对于此示例,将强度属性设置为 1.5。
Unity 显示以下视图
注意:要在 XR 中可视化示例,请将项目配置为使用 XR SDK。 将 MockHMD XR 插件添加到项目。将渲染模式属性设置为单通道实例化。
示例已完成。
有关在兼容模式下执行 Blit 操作的更多信息,请参阅 URP 14(Unity 2022)文档中的使用纹理部分。