1.简介

随着Unity6的发布,URP17也已经可以上手使用,相对旧的版本改动较大的是加入了

RenderGraph、STP、Foveated rendering、GPU Resident Drawer等功能,部分功能只需要开关参数即可使用,

而GRD更像是Gpu driven管线下的SRP Batches升级,RenderGraph相较于HDRP之前使用的版本换了一套API。

最大的不同是,使用URP17编写Feature时,必须依赖于RenderGraph进行编写,接下来就来介绍一下。

1.1 相关Demo

目前URP17比较容易找到的学习Demo如下:

2.RenderGraph

打开任意URP的示例场景查看,RenderGraphView上各图标含义如下:

  1. 说明这是一个外部置入的RenderTexture
  2. 红色方块说明存在写入操作
  3. 绿色方块指存在读取操作(红绿方块说明读写操作)
  4. 该图标说明标记了全局RenderTexture

而顶部表明当前渲染一帧的各个Pass,左侧是各类RT。

URP17同时保留了旧的Feature逻辑与RenderGraph逻辑(随便打开一个pass为例):

public class DistortTunnelPass_Tunnel : ScriptableRenderPass
{
class PassData
{
public Renderer tunnelObject;
public Material tunnelMaterial;
} #pragma warning disable 618, 672 // Type or member is obsolete, Member overrides obsolete member // Unity calls the Configure method in the Compatibility mode (non-RenderGraph path)
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescripor)
{
} // Unity calls the Execute method in the Compatibility mode
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
} #pragma warning restore 618, 672 // Unity calls the RecordRenderGraph method to add and configure one or more render passes in the render graph system.
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
}
}

参考时忽略掉Configure和Execute的逻辑,执行逻辑关注RecordRenderGraph函数。

2.1 操作方式的改变

在RenderGraph中,之前的RTHandle由于不在该系统中托管,进入RenderGraph的材质都需要调用API进行转换,

转换为RendeGraph的RT后,无需考虑释放操作:

RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
TextureHandle textureHandle = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "My texture", false);

相关文档:

https://docs.unity3d.com/Manual/urp/render-graph-create-a-texture.html

此外RenderGraph对于空调用的pass,也会剔除进行优化,使用者需要手动标记以防止被剔除。

2.1 RecordRenderGraph

在该函数内可组织渲染逻辑,pass相关的逻辑需放在对应的代码块中,例如:

using (var builder = renderGraph.AddRasterRenderPass<PassData>(passName, out _))
{
builder.UseTexture(rt1);
builder.SetRenderAttachment(resourceData.activeColorTexture, 0); builder.SetRenderFunc<PassData>((data, context) =>
{
MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
materialPropertyBlock.SetTexture("_BlitTexture", rt1);
materialPropertyBlock.SetVector("_BlitScaleBias", new Vector4(1, 1, 0, 0)); context.cmd.DrawProcedural(Matrix4x4.identity, material, 0, MeshTopology.Triangles, 3, 1, materialPropertyBlock);
});
}

URP提供了多种RenderPass,例如处理光栅化相关逻辑使用RasterRenderPass组织相关逻辑。

在RenderPass的代码块中可使用builder对象配置RenderTarget、标记材质的读写等

而具体的pass绘制逻辑则在SetRenderFunc代码块中。

RecordRenderGraph内可以调用多次AddRenderPass,但URP并没有整理旧API的代码和相关工具类,

以至于容易使用旧的API导致报错,这点需要注意。

3.编写Feature

3.1 Blit与SetTarget

从前有句俗话“切RT的性能消耗相当于半个pass”,Unity SRP在几个版本的升级都在逐渐强调不切RenderTarget直接绘制,

如Cockpit Demo的屏幕空间描边。

3.2 屏幕模糊Demo

下面通过屏幕模糊Demo案例,演示URP17下pass的编写。

通过外部EnqueuePass的方式,在场景中通过控制器脚本添加该Pass,

MyBlurSceneController.cs:

using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering; public class MyBlurSceneController : MonoBehaviour
{
public Material material;
[Range(2, 15)] public int blurPasses = 3;
[Range(0, 4)] public int downSample = 0;
[Range(0.0f, 10f)] public float offset = 0.2f; public RenderPassEvent injectionPoint = RenderPassEvent.BeforeRenderingPostProcessing;
public int injectionPointOffset = 0;
public ScriptableRenderPassInput inputRequirements = ScriptableRenderPassInput.Color;
public CameraType cameraType = CameraType.Game; private MyBlurPass mMyBlurPass; private void OnEnable()
{
SetupPass(); RenderPipelineManager.beginCameraRendering += OnBeginCamera;
} private void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
} public virtual void SetupPass()
{
mMyBlurPass = new MyBlurPass(); mMyBlurPass.renderPassEvent = injectionPoint + injectionPointOffset;
mMyBlurPass.material = material; mMyBlurPass.ConfigureInput(inputRequirements);
} public virtual void OnBeginCamera(ScriptableRenderContext ctx, Camera cam)
{
if (mMyBlurPass == null || material == null)
return; if ((cam.cameraType & cameraType) == 0) return; mMyBlurPass.blurPasses = blurPasses;
mMyBlurPass.downSample = downSample;
mMyBlurPass.offset = offset; cam.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(mMyBlurPass);
}
}

MyBlurPass.cs:

using UnityEngine;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule.Util; public class MyBlurPass : ScriptableRenderPass
{
public class PassData
{
public TextureHandle tempRt1;
public TextureHandle tempRt2;
} public Material material;
[Range(2, 15)] public int blurPasses = 3;
[Range(1, 4)] public int downSample = 1;
[Range(0.0f, 10f)] public float offset = 0.2f; public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
var resourceData = frameData.Get<UniversalResourceData>();
var passData = new PassData(); var w = Screen.width >> downSample;
var h = Screen.height >> downSample; RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(w, h, RenderTextureFormat.Default, 0);
passData.tempRt1 = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "MyBlurPassTempRt1", false); textureProperties = new RenderTextureDescriptor(w, h, RenderTextureFormat.Default, 0);
passData.tempRt2 = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "MyBlurPassTempRt2", false); var rt1 = passData.tempRt1;
var rt2 = passData.tempRt2; //将屏幕RT Blit到rt1上
var para = new RenderGraphUtils.BlitMaterialParameters(resourceData.activeColorTexture, rt1, material, 0);
renderGraph.AddBlitPass(para, "MyBlurPassBlitFirst"); material.SetFloat("_SampleOffset", offset); //模糊迭代
for (int i = 0; i < blurPasses - 1; ++i)
{
para = new RenderGraphUtils.BlitMaterialParameters(rt1, rt2, material, 0);
renderGraph.AddBlitPass(para, $"MyBlurPassBlit_{i}"); var tmp = rt1;
rt1 = rt2;
rt2 = tmp;
} //通过直接绘制的方式,将模糊RT绘制到屏幕上
using (var builder = renderGraph.AddRasterRenderPass<PassData>(passName, out _))
{
builder.UseTexture(rt1);
builder.SetRenderAttachment(resourceData.activeColorTexture, 0); builder.SetRenderFunc<PassData>((data, context) =>
{
MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
materialPropertyBlock.SetTexture("_BlitTexture", rt1);
materialPropertyBlock.SetVector("_BlitScaleBias", new Vector4(1, 1, 0, 0)); context.cmd.DrawProcedural(Matrix4x4.identity, material, 0, MeshTopology.Triangles, 3, 1, materialPropertyBlock);
});
}
}
}

最后在ShaderGraph中连出模糊的逻辑,注意Blit对应的参数_BlitTexture、_BlitScaleBias:

最后在场景中挂载控制器以及材质球,即可使用该模糊Pass。

Unity6 URP17使用初探的更多相关文章

  1. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  2. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  3. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  4. JavaScript学习(一) —— 环境搭建与JavaScript初探

    1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...

  5. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  6. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

  7. 【手把手教你全文检索】Apache Lucene初探

    PS: 苦学一周全文检索,由原来的搜索小白,到初次涉猎,感觉每门技术都博大精深,其中精髓亦是不可一日而语.那小博猪就简单介绍一下这一周的学习历程,仅供各位程序猿们参考,这其中不涉及任何私密话题,因此也 ...

  8. Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用

    一.高可用的Session服务器场景简介 1.1 应用服务器的无状态特性 应用层服务器(这里一般指Web服务器)处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性. PS:提到无状态特性 ...

  9. NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例

    一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...

  10. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

随机推荐

  1. SMU Summer 2023 Contest Round 11(2022-2023 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2022))

    SMU Summer 2023 Contest Round 11(2022-2023 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2022 ...

  2. csv导入导出组件jcsv

    jcsv 介绍 jcsv一个简单的.轻量级的csv导入.导出库,相对于opencsv与javacsv,jcsv侧重于导入导出,包括导入校验.导出模板等. 源代码地址:https://gitee.com ...

  3. P4823 [TJOI2013] 拯救小矮人

    感觉这个题的操作很新奇,做个记录. P4823 [TJOI2013] 拯救小矮人 大概题面: 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决 定搭一个人梯.即:一个小矮人站在另一小矮人 ...

  4. 学习redis问题记录

    2024年5月25日 倒腾了很长时间 突然发现的问题 ide提示改为toList() 我顺便就改过去了 但是实际业务中redis序列化会产生无法反序列化的问题 造成缓存挂壁 业务直接G collect ...

  5. Centos7.9安装Docker和Docker compose

    什么是docker环境 Docker环境是指在计算机中安装和配置了Docker引擎的运行环境.Docker是一种容器化平台,它提供了一种轻量级的虚拟化技术,能够将应用程序及其依赖项打包成一个独立的容器 ...

  6. Vue.js 异步组件传参

    本文主要展示一下如何给异步组件进行参数传递: 通过 h 函数就可以啦 versions: vue@3.2.13 子组件 Async.vue <template> <div> & ...

  7. 【倒计时3天】“CSIG企业行”走进合合信息,大咖解密智能文档处理背后的底层技术及AI未来展望

    3月18日,由中国图象图形学会(CSIG)主办,合合信息.CSIG文档图像分析与识别专业委员会联合承办的"CSIG企业行"系列活动将正式举办,通过搭建学术界与企业交流合作平台,为企 ...

  8. 实战合集 | I/O 2021 Flutter 研讨会

    2021 年的 Google I/O 大会已圆满闭幕,本次大会带来了诸多关于各项谷歌开发技术产品的最新更新.在此次 I/O,Flutter 发布了 2.2 版本,包括 Web 版的增强.更多 Mate ...

  9. 第43天:WEB攻防-PHP应用&SQL注入&符号拼接&请求方法&HTTP头&JSON&编码类

    #PHP-MYSQL-数据请求类型 SQL语句由于在黑盒中是无法预知写法的,SQL注入能发成功是需要拼接原SQL语句,大部分黑盒能做的就是分析后各种尝试去判断,所以有可能有注入但可能出现无法注入成功的 ...

  10. 【赵渝强老师】什么是PL/SQL?

    一.什么是PL/SQL? PL/SQL(Procedure Language/SQL)是oracle在标准的sql语言上的扩展.ql/sql不仅允许嵌入sql语言,还可以定义变量和常量,允许私用条件语 ...