Unity RenderFeature架构分析

自定义RenderFeature接口流程

在这里插入图片描述

URP内部ScriptableRenderPass分析

public、protected属性

  • renderPassEvent :渲染事件发生的时刻
  • colorAttachments :渲染的颜色纹理列表 m_ColorAttachments
  • colorAttachment :m_ColorAttachments[0];
  • depthAttachment :m_DepthAttachment
  • colorStoreActions: RenderBufferStoreAction[]【Enum】这个 枚举 描述了当GPU完成渲染到渲染目标时应该在渲染目标上做什么。(与MSAA是否存储或解析有关)
  • depthStoreAction :RenderBufferStoreAction【Enum】
  • input :ScriptableRenderPassInput【Enum】
    • None = 0x0,
    • Depth = 0x1,
    • Normal = 0x2,
    • Color = 0x4,
    • Motion = 0x8
  • clearFlag : ClearFlag【Enum】
    • None = 0x0,
    • Color = 0x1,
    • Depth = 0x2,
    • Stencil = 0x4,
    • DepthStencil = 0x6,
    • ColorStencil = 0x5,
    • All = 0x7
  • clearColor :Color m_ClearColor

private 属性

internal 属性(同一命名空间使用)

        internal bool overrideCameraTarget { get; set; }
        internal bool isBlitRenderPass { get; set; }
        internal bool useNativeRenderPass { get; set; }
        internal int renderTargetWidth { get; set; }
        internal int renderTargetHeight { get; set; }
        internal int renderTargetSampleCount { get; set; }
        internal bool depthOnly { get; set; }
        internal bool isLastPass { get; set; }//这个标志每帧更新,以跟踪哪一帧是当前相机的最后一帧
        internal int renderPassQueueIndex { get; set; }//索引来跟踪当前帧中的位置
        internal NativeArray<int> m_ColorAttachmentIndices;
		internal NativeArray<int> m_InputAttachmentIndices;
		internal GraphicsFormat[] renderTargetFormat { get; set; }
		RenderTargetIdentifier[] m_ColorAttachments = new RenderTargetIdentifier[] { BuiltinRenderTextureType.CameraTarget };
		internal RenderTargetIdentifier[] m_InputAttachments = new RenderTargetIdentifier[8];
		internal bool[] m_InputAttachmentIsTransient = new bool[8];
		RenderTargetIdentifier m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
		ScriptableRenderPassInput m_Input = ScriptableRenderPassInput.None;
		ClearFlag m_ClearFlag = ClearFlag.None;
		Color m_ClearColor = Color.black;

URP内部ScriptableRenderer分析

ScriptableRenderer 管理所有的ScriptableRenderFeature以及ScriptableRenderPass

static数据

internal static ScriptableRenderer current = null;
private static bool m_UseOptimizedStoreActions = false;
static RenderTargetIdentifier[] m_ActiveColorAttachments = new RenderTargetIdentifier[] { 0, 0, 0, 0, 0, 0, 0, 0 };
static RenderTargetIdentifier m_ActiveDepthAttachment;
static RenderTargetIdentifier[][] m_TrimmedColorAttachmentCopies = new RenderTargetIdentifier[][]
private static Plane[] s_Planes = new Plane[6];
private static Vector4[] s_VectorPlanes = new Vector4[6];

核心数据

List<ScriptableRenderPass> m_ActiveRenderPassQueue = new List<ScriptableRenderPass>(32);
List<ScriptableRendererFeature> m_RendererFeatures = new List<ScriptableRendererFeature>(10);
RenderTargetIdentifier m_CameraColorTarget;//当前渲染管线上一帧结果的Color纹理
RenderTargetIdentifier m_CameraDepthTarget;
RenderTargetIdentifier m_CameraResolveTarget;

其他数据

private StoreActionsOptimization m_StoreActionsOptimizationSetting = StoreActionsOptimization.Auto;
const int k_RenderPassBlockCount = 4;
bool m_FirstTimeCameraColorTargetIsBound = true; 
bool m_FirstTimeCameraDepthTargetIsBound = true; 
bool m_IsPipelineExecuting = false;
internal bool isCameraColorTargetValid = false;
internal bool disableNativeRenderPassInFeatures = false;
internal bool useRenderPassEnabled = false;
internal bool useDepthPriming { get; set; } = false;
internal bool stripShadowsOffVariants { get; set; } = false;
internal bool stripAdditionalLightOffVariants { get; set; } = false;

首先,当创建实例Pass时调用父类构造函数

public ScriptableRenderPass()
{
    renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    m_ColorAttachments = new RenderTargetIdentifier[] { BuiltinRenderTextureType.CameraTarget, 0, 0, 0, 0, 0, 0, 0 };
    m_InputAttachments = new RenderTargetIdentifier[] { -1, -1, -1, -1, -1, -1, -1, -1 };
    m_InputAttachmentIsTransient = new bool[] { false, false, false, false, false, false, false, false };
    m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
    m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store, 0, 0, 0, 0, 0, 0, 0 };
    m_DepthStoreAction = RenderBufferStoreAction.Store;
    m_OverriddenColorStoreActions = new bool[] { false, false, false, false, false, false, false, false };
    m_OverriddenDepthStoreAction = false;
    m_ClearFlag = ClearFlag.None;
    m_ClearColor = Color.black;
    overrideCameraTarget = false;
    isBlitRenderPass = false;
    profilingSampler = new ProfilingSampler($"Unnamed_{nameof(ScriptableRenderPass)}");
    useNativeRenderPass = true;
    renderTargetWidth = -1;
    renderTargetHeight = -1;
    renderTargetSampleCount = -1;
    renderPassQueueIndex = -1;
    renderTargetFormat = new GraphicsFormat[]
    {
        GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None,
        GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None
    };
    depthOnly = false;
}

其次、调用AddRenderPasses时,将实例化Pass加入队列

使用函数

renderer.EnqueuePass(_scannerPass);

将该Pass加入到URP Renderer管线中

public void EnqueuePass(ScriptableRenderPass pass)
{
    m_ActiveRenderPassQueue.Add(pass);
    if (disableNativeRenderPassInFeatures)
        pass.useNativeRenderPass = false;
}

之后、调用OnCameraSetup,设置当前Pass的目标纹理

public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
    // 将当前摄像机的cameraColorTarget作为该Pass渲染的目标纹理
    ConfigureTarget(renderingData.cameraData.renderer.cameraColorTarget);
}

最后、调用Execute函数渲染

作为后处理,我们可以通过如下流程

1. 创建着色器属性名称唯一标识符

int tempRT = Shader.PropertyToID("标识符名称,可自定义");

2. 根据当前摄像机的目标纹理设置,创建新的临时纹理

cmd.GetTemporaryRT(tempRT, renderingData.cameraData.cameraTargetDescriptor);

RenderTextureDescriptor这个结构体包含了创建RenderTexture所需的所有信息。即renderingData.cameraData.cameraTargetDescriptor返回的值

3. 对一个纹理做后处理

后处理材质为_material,使用Pass 0;并保存到下一个纹理中。

cmd.Blit(colorAttachment, tempRT, _material, 0);

Blit意思为位块传送,即将colorAttachment的所有数据,复制到tempRT中。

而这里,Unity不仅仅做位块传输,而是 使用着色器 将纹理中的像素数据复制到渲染纹理中。

public void Blit(RenderTargetIdentifier source, RenderTargetIdentifier dest, Material mat, int pass)
{
	// 设置描述如何执行命令缓冲区的意图的标志。
    ValidateAgainstExecutionFlags(CommandBufferExecutionFlags.None, CommandBufferExecutionFlags.AsyncCompute);
    // 位块传输   allSlices---所有位块
    Blit_Identifier(ref source, ref dest, mat, pass, new Vector2(1f, 1f), new Vector2(0f, 0f), Texture2DArray.allSlices, 0);
}

内部代码被封装,不可见!

4. 将临时纹理复制给目标

如果不使用自己的material,则使用Unity默认的mat,即只复制结果。

cmd.Blit(tempRT, colorAttachment);

5. 提交命令,释放命令池

//上下文执行这个CommandBuffer
context.ExecuteCommandBuffer(cmd);
//释放这个临时纹理
cmd.ReleaseTemporaryRT(tempRT);
//CommandBuffer池释放这个cmd
CommandBufferPool.Release(cmd);

Shader中的数据

复制的数据将作为_MainTex录入。

Properties
{
	_MainTex("MainTex",2D)= "white"{}
}
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);

深度图需要在UniversalRenderPipelineAsset中勾选Depth Texture。
但是如果未勾选,如果内部渲染有使用到DepthTexture,也可能会生成DepthTexture。

TEXTURE2D(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【解决方案】基于边缘计算技术的安科瑞综合管廊能效管理平台

平台背景 综合管廊一般是建于城市地下用于容纳两类及以上城市工程管线的构筑物及附属设施&#xff0c;将电力、自来水、热力、煤气、电信、网络等市政公用管线根据规划要求集中敷设在同一个构建物内&#xff0c;实施统一设计、施工、管理的市政公用隧道空间&#xff0c;并且还…

在Linux环境如何启动和redis数据库?

Linux中连接redis数据库&#xff1a; 前台启动&#xff1a; 第一步&#xff1a;redis-server:服务器启动命令 当我们启动改窗口后&#xff0c;出现如下所示&#xff1a; 该窗口就不能关闭&#xff0c;否则会出现redis无法使用的情况&#xff0c;重新打开一个窗口&#xff0c…

云服务器哪家便宜?亚马逊AWS等免费云服务器推荐

在这数字化的时代&#xff0c;云计算技术越来越广泛应用于各种场景&#xff0c;尤其是云服务器&#xff0c;作为一种全新的服务器架构正在逐渐取代传统的物理服务器&#xff0c;“云服务器哪家便宜”等用户相关问题也受到越来越多的关注。自从亚马逊最早推出了首个云计算服务—…

PBR纹理转换简明教程

在这个教程中&#xff0c;我将演示如何将为传统着色器创建的内容转换到 PBR 着色器&#xff0c;如何将内容从一种 PBR 工作流程转换为另一种&#xff0c;并解释现代工作流程中的各种差异。 本教程面向中级到高级用户&#xff0c;因此请务必阅读 Jeff Russell 和我编写的前两篇 …

k8s安装步骤

环境&#xff1a; 操作系统&#xff1a;win10 虚拟机&#xff1a;VMware linux发行版&#xff1a;CentOS7.9 CentOS镜像&#xff1a;CentOS-7-x86_64-DVD-2009 master和node节点通信的ip(master)&#xff1a; 192.168.29.164 0.检查配置 本次搭建的集群共三个节点&#xff0c;…

力扣:239. 滑动窗口最大值

题目&#xff1a; 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 提示&#xff1a; 1 < nums.length < 10^5-10^4 < n…

ESP32-Web-Server编程-JS 基础 1

ESP32-Web-Server编程-JS 基础 1 概述 前述分别在 HTML 基础 和 CSS 基础 中介绍了 HTML、CSS 的基本内容。HTML 定义了网页中包含哪些对象&#xff0c;CSS 定义了对象的显示样式。JavaScript(LiveScript)是一种运行于客户端的解释性脚本语言&#xff0c;使 HTML 页面更具动态…

【MySql】悲观锁和乐观锁的介绍

一、并发控制 当程序中可能出现并发的情况时&#xff0c;就需要保证在并发情况下数据的准确性&#xff0c;以此确保当前用户和其他用户一起操作时&#xff0c;所得到的结果和他单独操作时的结果是一样的。这就叫做并发控制。并发控制的目的是保证一个用户的工作不会对另一个用…

数据安全:专业服务与您共同对抗.faust数字勒索的威胁

引言&#xff1a; 在数字世界的幕后&#xff0c;一股黑暗势力悄然崛起。.faust勒索病毒&#xff0c;如同数码时代的黑手党&#xff0c;通过其高度精密的加密技术&#xff0c;正在肆虐用户和组织的数据。本文将深入挖掘.faust的狡猾手法&#xff0c;为您揭示其隐藏在数字背后的…

居家适老化设计第三十三条---卫生间之暖风

居家适老化是指为了满足老年人居住需求而进行的住房改造&#xff0c;以提供更加安全、舒适、便利的居住环境。在居家适老化中&#xff0c;暖风系统是一个重要的考虑因素。暖风系统可以提供温暖舒适的室内温度&#xff0c;对老年人来说尤为重要。老年人常常身体机能下降&#xf…

浅谈基于EIoT能源物联网的工厂智能照明系统应用改造

【摘要】&#xff1a;随着物联网技术的发展&#xff0c;许多场所针对照明合理应用物联网照明系统&#xff0c;照明作为工厂的重要能耗之一&#xff0c;工厂的照明智能化控制&#xff0c;如何优化控制、提高能源的利用率&#xff0c;达到节约能源的目的。将互联网的技术应用到工…

PPSSPP (PSP游戏模拟器)最新版安装使用教程

PPSSPP优势 1、目前唯一的也是最好的psp模拟器 可运行绝大多数psp游戏且运行高速&#xff0c;即使是低配手机也能游玩经典大作。 2、支持自定义调节虚拟手柄和实体手柄连接 ppsspp模拟器支持使用虚拟手柄或者连接实体手柄游玩&#xff0c;同时还可以自定义调节按键选项。 …

mac电脑下载Netflix Mac(奈飞客户端)安装教程

Netflix Mac&#xff0c;奈飞官方客户端&#xff0c;带给您无限的电影和剧集体验&#xff01;与朋友分享最新热门剧集、电影&#xff0c;与家人一起享受高品质的流媒体内容。 通过Netflix Mac&#xff0c;您可以轻松地搜索、浏览和观看各种类型的影片&#xff0c;包括剧情片、…

Leetcode刷题之设计循环队列(C语言版)

Leetcode刷题之设计循环队列&#xff08;C语言版&#xff09; 一、题目描述二、题目示例三、题目解析Ⅰ、typedef structⅡ、MyCircularQueue* myCircularQueueCreate(int k)Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)Ⅳ、bool myCircularQueueIsFull(MyCircularQ…

老师怎样处理校园欺凌

校园欺凌是一个让人痛心又不可忽视的问题。作为老师&#xff0c;该如何处理这种问题&#xff0c;既能够保护受欺凌的学生&#xff0c;又能够让施暴者得到应有的教训呢&#xff1f; 及时发现并介入 经常关注学生的动态&#xff0c;一旦发现有校园欺凌的苗头&#xff0c;就要及时…

如何轻松将 4K 转换为 1080p 高清视频

由于某些原因&#xff0c;你可能有一些 4K 视频&#xff0c;与1080p、1080i、720p、720i等高清视频相比&#xff0c;4K 视频具有更高的分辨率&#xff0c;可以给您带来更多的视觉和听觉享受。但是&#xff0c;播放4k 视频是不太容易的&#xff0c;因为超高清电视没有高清电视那…

医疗器械企业升级路:直连客户盘活存量,布局出海寻求增量

随着随着医疗各领域VBP&#xff08;带量采购&#xff09;的稳步推进以及医疗机构DRG/DIP&#xff08;按疾病诊断相关分组/病种分值支付&#xff09;的深化应用&#xff0c;降本增效和精细化管理已经成为医院管理者的头等大事。 这也在倒逼医疗器械厂商提升管理水平和营销效率。…

FFA 2023|字节跳动 7 项议题入选

Flink Forward 是由 Apache 官方授权的 Apache Flink 社区官方技术大会&#xff0c;作为最受 Apache Flink 社区开发者期盼的年度峰会之一&#xff0c;FFA 2023 将持续集结行业最佳实践以及 Flink 最新技术动态&#xff0c;是中国 Flink 开发者和使用者不可错过的的技术盛宴。 …

竞赛选题 题目:基于机器视觉的图像矫正 (以车牌识别为例) - 图像畸变校正

文章目录 0 简介1 思路简介1.1 车牌定位1.2 畸变校正 2 代码实现2.1 车牌定位2.1.1 通过颜色特征选定可疑区域2.1.2 寻找车牌外围轮廓2.1.3 车牌区域定位 2.2 畸变校正2.2.1 畸变后车牌顶点定位2.2.2 校正 7 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享…