Unity6升级SRP到RenderGraph URP17

2024.12 补充提示,BUG和踩坑:

  1. BUG:换场景有的时候Blitter的生命周期会乱掉导致报空错误,解决方案如下
   if (!Application.isPlaying)
   {
       UnityEditor.SceneManagement.EditorSceneManager.sceneOpened += OnEditorSceneChanged;
   }
   
   public void OnEditorSceneChanged(UnityEngine.SceneManagement.Scene scene, UnityEditor.SceneManagement.OpenSceneMode mode)
   {
       Blitter.Cleanup();
       Blitter.Initialize(Shader.Find("Hidden/Universal/CoreBlit"), Shader.Find("Hidden/Universal/CoreBlitColorAndDepth"));
   }
  1. 踩坑:运行时Unity会根据VolumeProfile中的全部VolumeComponent另实例化新的VolumeComponent用于运行,实例化VolumeComponent参数与VolumeProfile中的参数不一致,化分为两个对象后,从VolumeManager.instance.stack获取的是运行时实例化的新组件,从profile.TryGet获取的是原始组件
  2. 踩坑:VolumeComponent自带参数间差值的方法Override(VolumeComponent state, float interpFactor),是对传入的state组件的参数进行覆写,在Override方法外无法对运行时实例化的VolumeComponent的全部VolumeParameter做任何修改

CommandBuffer、Blitter、RTHandle、RenderPass更新
官方文档:

https://docs.unity3d.com/Manual/urp/upgrade-guide-unity-6.html

RenderPass大更新,取消OnCameraSetup和Execute方法,换成了新版api方法RecordRenderGraph。
  • 官方案例:

https://docs.unity3d.com/Manual/urp/renderer-features/create-custom-renderer-feature.html#code-render-pass

  • RTHandle换成了TextureHandle,TextureHandle不需要手动释放。
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
    // 获取临时TextureHandle
	var descriptor = frameData.Get<UniversalCameraData>().cameraTargetDescriptor;
	descriptor.depthBufferBits = 0;
	var tempTex = UniversalRenderer.CreateRenderGraphTexture(renderGraph, descriptor, "_RT_NAME", false);
	// 外部RTHandle转TextureHandle,需要手动释放RTHandles.Alloc创建的RT
	var whiteTex = renderGraph.ImportTexture(RTHandles.Alloc(Texture2D.whiteTexture))
}
  • 获取Camera
frameData.Get<UniversalCameraData>().camera
  • ScriptableRenderer.cameraColorTargetHandle换成了
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
    var colTex = frameData.Get<UniversalResourceData>().activeColorTexture;
}
  • 在RecordRenderGraph方法中使用CommandBuffer
    • 无法直接获取CommandBuffer,需要再套一层RenderGraphBuilder。
    • 泛型为 class PassData {} 就可以
using (var builder = renderGraph.AddRasterRenderPass<PassData>("pass name", out var passData))
{
    builder.AllowPassCulling(false);
    builder.AllowGlobalStateModification(true);
    // 获取屏幕颜色输入
    var src = frameData.Get<UniversalResourceData>().activeColorTexture;
    // 创建输出的目标图片
    var dst = UniversalRenderer.CreateRenderGraphTexture(renderGraph, descriptor, "__DST", false);
    // 设置pass中用到的图片
    builder.UseTexture(src);
    // 在这里设置相当于之前Blit的dst渲染目标
    builder.SetRenderAttachment(dst, 0);
    builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
    {
        RasterCommandBuffer cmd = context.cmd;
        // 拿到cmd后和之前类似,但有些功能缺失,比如DispatchCompute只能在renderGraph.AddComputePass的context中获取
        cmd.SetGlobalTexture("tex_src", src);
        // 相当于之前的Blitter.BlitCameraTexture(cmd, src, dst, material, 0);
        Blitter.BlitTexture(cmd, src, new Vector4(1, 1, 0, 0), material, 0);
    });
}
  • 在RenderGraph中使用ComputeShader
using (var builder = renderGraph.AddComputePass<PassData>("xxx compute", out var passData))
{   
    // 设置pass中用到的图片
    builder.UseTexture(src);
    builder.AllowPassCulling(false);
    builder.AllowGlobalStateModification(true);
    builder.SetRenderFunc<PassData>((data, context) =>
    {
        ComputeCommandBuffer cmd = context.cmd;
        // set shader props ...
        cmd.DispatchCompute(compute, 0, groupsX, groupsY, groupsZ);
        // cmd.DispatchCompute(compute1, 0, groupsX, groupsY, groupsZ);
		// ...
    });
}
  • 复制TextureHandle到另一个TextureHandle,以及不用builder直接Blit方法
// 复制
renderGraph.AddBlitPass(src, dst, Vector2.one, Vector2.zero);
// 直接Blit
renderGraph.AddBlitPass(new(src, dst, upscaleMaterial, 0));
  • 在renderGraph添加多个pass后不用做其他操作,在RecordRenderGraph方法结束后会按顺序调用全部添加的pass。

知乎大佬写的例子:https://zhuanlan.zhihu.com/p/721313939

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值