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);

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

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

相关文章

希宝猫罐头怎么样?专业人士告诉你什么牌子的猫罐头好

而作为一个开猫咖5年的老板&#xff0c;对于猫咪吃的健康我一直很重视&#xff0c;毕竟健康的猫咪是决定我店铺生意红火的重要原因。我有必要给大家分享一下这些年我喂养猫罐头的经验&#xff0c;并推荐我觉得可以的猫罐头。那么希宝猫罐头表现怎么样呢&#xff1f; 希宝猫罐头…

Python开源项目之人工智能老照片修复算法学习

文章目录 前言项目环境搭建conda虚拟环境创建激活环境Pytorch安装Synchronized-BatchNorm-PyTorch repository安装Global目录Synchronized-BatchNorm-PyTorch项目部署检测预处理模型下载下载脸部增强模型文件下载依赖完整部署后项目结构 项目使用验证一下总结关于Python技术储备…

Android Tombstone 与Debuggerd 原理浅谈

一、前言 Android系统类问题主要有stability、performance、power、security。Android集成一个守护进程tombstoned是android平台的一个守护进程&#xff0c;它注册成3个socket服务端&#xff0c;客户端封装在crash_dump和debuggerd_client。 crash_dump用于跟踪定位C crash&am…

万宾科技可燃气体监测仪的功能有哪些?

随着城市人口的持续增长和智慧城市不断发展&#xff0c;燃气作为一种重要的能源供应方式&#xff0c;已经广泛地应用于居民生活和工业生产的各个领域。然而燃气泄漏和安全事故的风险也随之增加&#xff0c;对城市的安全和社会的稳定构成了潜在的威胁。我国燃气管道安全事故的频…

mac 修改 hosts 文件

打开 hosts 所在文件夹 command shift G 快捷键 输入&#xff1a;“/private/etc/hosts” 后回车 如下所示 进入 hosts 文件所在位置&#xff0c;找到 hosts 文件&#xff0c;双击打开 修改 hosts 文件 将所需要的配置信息追加到hosts 文件中&#xff0c;或者修改需要改…

智慧楼宇可视化视频综合管理系统,助力楼宇高效安全运行

随着互联网技术的进步和发展&#xff0c;智能化的楼宇建设也逐步成为人们选择办公场所是否方便的一个重要衡量因素。在智能化楼宇中&#xff0c;安全管理也是重要的一个模块。得益于互联网新兴技术的进步&#xff0c;安防视频监控技术也得到了快速发展并应用在楼宇的安全管理中…

burp抓取雷电模拟器的数据包

文章目录 一、从burp中导出证书二、雷电模拟器的相关设置三、将burp的证书添加到模拟器的系统证书下四、安装ProxyDroid 所需软件 雷电模拟器版本&#xff1a;4.0.83Burp Suite Community Edition v2023.10.3.6ProxyDroid 起因&#xff1a;常规方法&#xff08;wifi处添加代理…

满满干货!搭建智能视频监控系统如何挑选前端设备?

在此前的文章中&#xff0c;小编也和大家讨论过如何选择适合场景需求又性价比高的摄像头。除了摄像头以外&#xff0c;智能监控系统的组成也少不了前端设备&#xff0c;今天就给大家介绍一下几大前端设备的区别与应用场景吧。 在智能视频监控中&#xff0c;前端设备一般分为四类…

C语言众数问题(ZZULIOJ1201:众数问题)

题目描述 给定含有n个元素的多重集合S&#xff0c;每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。 例如&#xff0c;S{1&#xff0c;2&#xff0c;2&#xff0c;2&#xff0c;3&#xff0c;5}。多重集S的众数是2&#xff0c;其重数为3。 编程任务…

保姆级连接FusionInsight MRS kerberos Hive

数新网络&#xff0c;让每个人享受数据的价值https://xie.infoq.cn/link?targethttps%3A%2F%2Fwww.datacyber.com%2F 概述 本文将介绍在华为云 FusionInsight MRS&#xff08;Managed Relational Service&#xff09;的Kerberos环境中&#xff0c;如何使用Java和DBeaver实现远…

深眸科技聚焦AI机器视觉检测,驱动3C电子行业集成创新实现新需求

随着消费的升级及国家政策的助推&#xff0c;国内3C电子市场不断扩大&#xff0c;行业实现高速发展。近年来&#xff0c;3C电子产品持续迭代&#xff0c;生产工艺也逐渐复杂化&#xff0c;相关生产线定位组装、零部件检测、整机产品检测等环节&#xff0c;亟需使用具备较强适应…

电源控制系统架构(PCSA)之电源状态层级

目录 5.2 电源状态层级 5.2.1 Core电源状态 5.2.2 Cluster的电源状态 5.2.3 设备电源状态 5.2.4 SOC电源状态 5.2 电源状态层级 电源状态可以组织为电源状态表的层次结构。每个电源状态表描述在其层次结构级别上可用的电源状态。 从系统级电源控制的角度来看&#xff0c…