本篇文章整理了URP管线使用中的一些简单的心得记述

1.使用ScriptableRendererFeature自定义渲染特性

在内建(Build-in)管线中可以使用CommandBuffer并添加到摄像机上来实现自定义的特性。在URP管线中,处理方法变成了RendererFeature

RendererFeature不需要绑定到相机;而是挂载到渲染器(如ForwardRenderer)的设置里。

在Project面板点击右键Create/Rendering/Universal Render Pipeline/Renderer Feature可以创建Renderer Feature模板。

模板中Feature带有一个CustomRenderPass的嵌套类;并且在AddRenderPasses函数中被添加进pass队列。

ScriptableRenderPass可以指定需要的渲染步骤,如:

m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;

由于一个效果往往需要多个pass不同阶段处理;这样的方式显然比较友好。

在之前内建的渲染管线中;CommandBuffer只能执行预先设定好的一些步骤,这样多少有些不方便。在自定义管线中CommandBuffer变成了立即执行,

现在可以在ScriptableRenderPass中直接通过context来立即执行CommandBuffer:

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("MyCommandBuffer");
//CommandBuffer的操作
context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd);
}

此外,标记Profiling后,可在FrameDebugger中直接查看标记Profiling的对象:

{
ProfilingSampler mProfilingSampler = new ProfilingSampler("Test1");
CommandBuffer cmd = CommandBufferPool.Get("Test1 Cmd");
using (new ProfilingScope(cmd, mProfilingSampler))
{
MeshRenderer meshRenderer = Resources.Load<MeshRenderer>("TestModel");
cmd.DrawRenderer(meshRenderer, meshRenderer.sharedMaterial);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}

而打开了管线设置中的Debug Level后;可以通过这个参数看见更多的调试信息

如UniversalRenderPipeline.cs的RenderSingleCamera方法里:

static void RenderSingleCamera(...)
{
...
asset.debugLevel >= PipelineDebugLevel.Profiling ? ...

这段代码在勾选这个设置后可以在FrameDebugger内显示不同的相机名。

2.使用DrawRenderers进行大批量绘制

在内建管线中,通常使用CommandBuffer.DrawRenderer来绘制一些指定的对象,

不过绘制对象一多这样做就不太方便。

在URP的自定义pass中可以使用ScriptableRenderContext上下文里的DrawRenderers接口进行批量绘制,

它可以拿到当前相机的剔除结果(CullingResults),通过FilteringSettings参数再进行一次过滤。

FilteringSettings里还可以设置renderingLayerMaskrenderingLayerMask可在MeshRenderer、SkinnedMeshRenderer

等渲染器组件中设置,独立于旧的Layer。

借助传入的DrawingSettingsRenderStateBlock参数可指定是否写入Stencil、是否写深度等信息,最终完成绘制,如:

context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings,
ref m_RenderStateBlock);

如果要绘制的内容第一次相机剔除时没有,也可以再进行一次相机剔除:

context.Cull(...)

使用新的结果来绘制。

以前抓取uGUI的绘制内容较为困难,现在也可以用这种办法把UI分成几部分绘制,并且控制每一部分是否写入指定RT了,

并且还可以通过自定义的Feature和context.DrawRenderers把UI绘制的步骤单独挪出来自行控制(但是Stencil会丢掉,酌情使用)。

还可以先修改RenderTarget再执行context.DrawRenderers绘制,这样就可以把内容批量绘制到指定RT上:

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("tempRt");
int tmpRt = Shader.PropertyToID("_TempRt");
cmd.GetTemporaryRT(tmpRt, mDesc);
cmd.SetRenderTarget(tmpRt);
context.ExecuteCommandBuffer(cmd); context.DrawRenderers(...); CommandBufferPool.Release(cmd);
}

(这里的RenderTexture应该在Configure中绑定)

注意,内建管线中使用CommandBuffer时可以直接填写-1、-2等宽高参数获得1/2,1/3等大小的RenderTexture,在自定义管线中

不再可用。

更多的绘制方法可以参考Render Objects(Runtime/RendererFeatures/RenderObjects.cs)或

DrawObjectsPass.cs(Runtime/Passes/DrawObjectsPass.cs)的做法。

3.相较内建管线的优化

在URP中单个对象支持的最大灯光数量是8盏;光照处理的操作在一个pass中完成。

虽然有数量限制;但这样整个场景的Batches数量得到了控制,这一点体现较为明显。

而阴影方面目前只能支持主光源平行光的阴影和聚光灯的阴影(v7.3.1)。

其次就是SRP Batches等技术,这方面暂未深入了解。

URP(Universal Render Pipeline)渲染管线在使用中的一些分享的更多相关文章

  1. 1.3:Render Pipeline and GPU Pipeline

    文章著作权归作者所有.转载请联系作者,并在文中注明出处,给出原文链接. 本系列原更新于作者的github博客,这里给出链接. 在学习SubShader之前,我们有必要对 Render Pipeline ...

  2. 1.5:Unity Render Pipeline

    文章著作权归作者所有.转载请联系作者,并在文中注明出处,给出原文链接. 本系列原更新于作者的github博客,这里给出链接. 这一节主要是为上一节中没有提到的一些概念作补充. 上一节提到了Unity中 ...

  3. Lightweight Render Pipeline

    (翻译) Lightweight Render Pipeline (LWRP),轻量级渲染管线,是一个Unity预制的Scriptable Render Pipeline (SRP).LWRP可以为移 ...

  4. Scriptable Render Pipeline

    Scriptable Render Pipeline SRP的核心是一堆API集合,使得整个渲染过程及相关配置暴露给用户,使得用户可以精确地控制项目的渲染流程. SRP API为原有的Unity构件提 ...

  5. [Unity] Shader Graph Error 当前渲染管道与此主节点不兼容(The current render pipeline is not compatible with this master node)

    Shader Graph Error  : The current render pipeline is not compatible with this master node 问题产生环境: Un ...

  6. 可编程渲染管线(Scriptable Render Pipeline, SRP)

    原文链接 可编程渲染管线处理数据的流程可分为以下3大阶段 1. 应用阶段 这个阶段大概会由CPU处理4件事情.首先会对模型数据进行可见性判断.模型数据由顶点位置.法线方向.顶点颜色.纹理坐标等构成.然 ...

  7. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  8. Scriptable render pipeline unity

    https://www.youtube.com/watch?v=zbjkEQMEShM LWRP https://blogs.unity3d.com/cn/2018/02/21/the-lightwe ...

  9. unity render pipeline

    post process v2 GUI temp8->TaregtPool0->temp8       tem8                      temp8->backbu ...

  10. 改写画质、突破性能, Unity 全面升级!

    技术变革,时代更迭.从<神庙逃亡>.<暗影之枪>等主流手游到独立联网的大型游戏,从绚丽多彩的影视动画到具备极致体验的运输建筑制造行业,从传统的2D 到立体3D 乃至沉浸式的VR ...

随机推荐

  1. #轮廓线dp,模型转换#洛谷 3226 [HNOI2012]集合选数

    题目 问有多少个集合 \(S\) 是 \([1,n]\) 的子集, 并且 \(\forall a,b\in S,a|b\),满足 \(\frac{b}{a}\neq \{2,3\}\) 分析 可以发现 ...

  2. #状压dp#洛谷 3959 [NOIP2017 提高组] 宝藏

    题目 选定一个起点 \(S\),找到一棵生成树,最小化 \[\sum_{i=1}^n dep_i\times dis_i \] \(n\leq 12\) 分析 设 \(dp[d][S]\) 表示当前树 ...

  3. Jetty的bytebufferpool模块

    bytebufferpool模块用于配置Jetty的ByteBuffer对象的对象池. 通过对象池的方式来管理ByteBuffer对象的使用和生命周期,期望降低Jetty进程内存的使用,同时降低JVM ...

  4. HuffmanTree,哈夫曼树的原理和c++实现

    目录 一.什么是哈夫曼树 二.构造哈夫曼树 三.路径.编码.解码 四.代码 一.什么是哈夫曼树 哈夫曼树又称为最优树. 通过权值来构造树,权值越大,离根节点越近 经常用于无损压缩算法 用于需要优化存储 ...

  5. CentOS 6.4(64位)上安装错误libstdc++.so.6(GLIBCXX_3.4.14)解决办法

    CentOS 6.4(64位)上安装错误libstdc++.so.6(GLIBCXX_3.4.14)解决办法 (2013-07-29 13:18:01) 转载▼ 分类:linux系统 引用地址: ht ...

  6. 不常用的技能-【手动编译java类】

    jdk版本:1.7 冒号分割jar包,1.8 分号分割jar包 javac -classpath fastjson-1.2.24.jar:jedis-2.9.0.jar Test.javajava - ...

  7. C内存操作API的实现原理

    我们在编写C代码时,会使用两种类型的内存,一种是栈内存,另外一种是堆内存,其中栈内存的申请和释放是由编译器来隐式管理的,我们也称为自动内存,这种变量是最简单而且最常用的,然后就是堆内存,堆的申请和释放 ...

  8. ASP.NET Core Web API下基于Keycloak的多租户用户授权的实现

    在上文<Keycloak中授权的实现>中,以一个实际案例介绍了Keycloak中用户授权的设置方法.现在回顾一下这个案例: 服务供应商(Service Provider)发布/Weathe ...

  9. 【笔记】Java相关大杂烩②

    [笔记]Java相关大杂烩② if单分支情况下,如果没有加 {},那么默认只包含第一条语句. if 和 else 分支后面如果包含多条语句,那么需要使用 {} 括起来. 不能随意地使用数学上的表达方式 ...

  10. 力扣454(java&python)-四数相加 II(中等)

    题目: 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, j, k, l &l ...