Unity6 URP17使用初探

news/2025/1/13 13:43:20/文章来源:https://www.cnblogs.com/hont/p/18515153

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如下:

  • URP17 Package内自带的Samples
  • Fantasy Kingdom (https://assetstore.unity.com/packages/essentials/tutorial-projects/fantasy-kingdom-in-unity-6-urp-298128)
  • 在Unity Hub可以直接下载的Universal 3D sample(包含3个场景)

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 modepublic 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。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/825159.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20222410 2024-2025-1 《网络与系统攻防技术》实验四实验报告

1.实验内容 1.1 2.实验过程 2.1 恶意代码文件类型标识、脱壳与字符串提取 2.1.1 使用文件格式和类型识别工具,给出rada恶意代码样本的文件格式、运行平台和加壳工具 kali虚拟机通过file 命令查看文件类型,这是微软 Windows平台、英特尔80386处理器的一个32位PE文件,并且是GU…

驱动开发目标测试机器设置

设置系统为测试模式 关闭驱动程序强制签名 设置调试消息筛选器掩码一、系统要求需要管理员权限,开启部分功能需要管理员权限 不能使用教育版或者家庭版操作系统,可以使用专业版、企业版、旗舰版什么的。部分功能在家庭版中无法开启。二、开启测试模式 直接执行命令: bcdedit…

网关和路由器的区别

本文将深入探讨网络领域中两个关键概念——网关和路由器之间的区别。通过比较它们的:1.功能;2.作用范围;3.工作方式;4.用途,读者将能够更清晰地理解这两者在网络架构中的不同角色和应用场景。1.功能 网关:网关是一种设备或软件,用于连接两个不同的网络,充当数据传输的中…

Nuxt.js 应用中的 components:extend 事件钩子详解

title: Nuxt.js 应用中的 components:extend 事件钩子详解 date: 2024/11/1 updated: 2024/11/1 author: cmdragon excerpt: components:extend 是 Nuxt.js 中的一个生命周期钩子,允许开发者扩展新的组件到项目中。通过这个钩子,开发者可以动态地添加额外的组件,从而增强…

不敢相信,Nginx 还能这么玩?

或许你会想:“Nginx 不就是用来部署网站的服务器嘛?这有何难?” 但其实这不过是九牛一毛罢了,Nginx 的实用操作和使用技巧还多着呢,下面这篇文章,就带大家轻松入门 Nginx、并且循序渐进地学习 Nginx 真正的用法!大家好,我是程序员鱼皮。今天来聊聊 Nginx 技术,这是一个…

24小时搜书官网及zlibrary中文网址/客户端app

24小时搜书 (24hBook store):一个免费电子书下载网站,支持通过书名、作者、出版社和ISBN编号等方式搜索和下载电子书。网站操作简单,直接下载无需多余步骤,支持azw3、mobi、epub、pdf等多种格式筛选。无论是通过书名、作者、出版社还是ISBN编号进行搜索。以下是一些使用这个…

flaks 钩子函数 | 中间件 | 内置对象 | Flask类视图和RESTfu

什么是钩子(中间件Middleware)钩子或叫钩子函数,是指在执行函数和目标函数之间挂载的函数,框架开发者给调用方提供一个point-挂载点,是一种AOP切面编程思想,常用的钩子函数before_first_request:   处理第一次请求之前执行,before_request:  在每次请求之前执行,通常…

为什么神经网络loss值很小但实际预测结果差很大

当我们使用神经网络进行训练时,可能会遇到loss值很小但实际预测效果很差的情况。这可能是由:1.过拟合;2.不合适的数据分割;3.评估指标选择不当;4.模型结构或参数设置不当;5.数据问题导致的标签错误等原因造成的。1.过拟合 过拟合是神经网络训练中常见的问题,意味着模型在…

用H5开发APP和用原生代码开发APP有什么区别

使用H5开发APP和使用原生代码开发APP的区别主要体现在:1.开发过程不同;2.性能与效率不同;3.用户体验不同;4.兼容性问题不同;5.维护和更新方式不同。总的来说,H5开发更侧重于跨平台兼容和快速开发,而原生开发则注重应用性能和优异的用户体验。1.开发过程不同 H5开发,即使…

Golang 开源库分享:anko - 给 Go 加点“脚本魔法”

GitHub 仓库链接:https://github.com/mattn/anko 1. anko 是干嘛用的? anko 是一个可以让 Go 项目支持脚本语言的小工具。换句话说,就是我们可以给 Go 项目加点“脚本魔法”,在程序跑起来之后还能动态地改代码逻辑。比如,你在写一个应用,想让用户可以随时调整设置或控制程…

历史性突破:独立开发 .net core 在线客服系统累计处理聊天消息 48 万余条!

业余时间用 .net core 写了一个在线客服系统。今天我查了下在线使用环境的数据库,累计的处理消息条数居然达到了创纪录的 489933 条!! 48 万余条!!业余时间用 .net core 写了一个在线客服系统。我把这款业余时间写的小系统丢在网上,陆续有人找我要私有化版本,我都给了,…

mybatis - [10] 三剑客generatorpagehelper$mybatis-plus

题记部分 一、mybatis-generator 1.1、概述 mybatis-generator是一个能快速生成xml、dao接口、实体类、注解类的代码生成器。 官网地址:https://mybatis.org/generator/index.html 1.2、配置方式-1 引入Maven插件依赖 <build><plugins><plugin><groupI…