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.mzph.cn/news/166986.shtml

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

相关文章

【网络奇幻之旅】那年我与大数据的邂逅

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;网络奇幻之旅 ⭐每日一句&#xff1a;循梦而行&#xff0c;向阳而生 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 &#x1f4…

windows远程linux或远程虚拟机连接拒绝问题排查

当我们使用MobaXterm远程连接时&#xff0c;报错如下&#xff1a; 1.首先检查该ubuntu防火墙是否关闭&#xff0c;先将防火墙关闭。 1.检查防火墙状态 sudo ufw status 2.开启防火墙 sudo ufw enable 3.关闭防火墙 sudo ufw disable 2.关闭防火墙后&#xff0c;使用ping命令相…

【数据结构/C++】栈和队列_顺序栈

#include<iostream> using namespace std; #define MaxSize 10 // 1. 顺序栈 typedef int ElemType; struct Stack {ElemType data[MaxSize];int top; } SqStack; // 初始化栈 void init(Stack &s) {// 初始化栈顶指针s.top -1; } // 入栈 bool push(Stack &s, …

什么是工业物联网(IOT)?这样的IOT平台你需要吗?——青创智通

物联网(IOT)是指在互联网上为传输和共享数据而嵌入传感器和软件的互联设备的广泛性网络。这允许将从物理对象收集的信息(数据)存储在专用服务器或云中。通过分析这些积累的信息&#xff0c;通过提供最优的设备控制和方法&#xff0c;可以实现一个更安全、更方便的社会。在智能家…

【完美解决】 Python pyecharts Map 地图数据不显示

目录 项目场景问题描述原因分析解决方案完整代码 项目场景 Python数据可视化&#xff0c;使用 Pyecharts.charts 模块中的Map&#xff0c;并导入数据来构建全国疫情热力地图 B站 黑马程序员 Python课程【P106 第一阶段 - 第十一章 - 02全国疫情地图构建】 问题描述 本人在学习…

vue+face-api.js实现前端人脸识别功能

近期做了一个前端vue实现人脸识别的功能&#xff0c;主要功能逻辑包含&#xff1a;人脸识别&#xff0c;人脸验证&#xff0c;唤起摄像头视频流之后从三个事件&#xff08;用户点头、摇头、眨眼睛&#xff09;中随机选中两个事件&#xff0c;待两个事件通过判断后人脸静止不动3…

基于Java+Vue+uniapp微信小程序微信阅读网站平台设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

使用端口扫描工具解决开放端口威胁并增强安全性

从暴露网络漏洞到成为入侵者的通道&#xff0c;开放端口可能会带来多种风险向量&#xff0c;威胁到网络的机密性、完整性和可用性。因此&#xff0c;最佳做法是关闭打开的端口&#xff0c;为了应对开放端口带来的风险&#xff0c;网络管理员依靠端口扫描工具来识别、检查、分析…

ubuntu下配置qtcreator交叉编译环境

文章目录 安装交叉编译工具安装qt creator开发环境配置交叉编译示例demo参考 安装交叉编译工具 安装qt creator开发环境 1 官网 2 填写信息 3 下载 默认没有出现Qt5.15版本 WISONIC\80081001ub16-1001:~$ /opt/Qt/Tools/QtCreator/bin/qtcreator /opt/Qt/Tools/QtCreat…

【PDF.js】2023 最新 PDF.js 在 Vue3 中的使用

因为自己写业务要定制各种 pdf 预览情况&#xff08;可能&#xff09;&#xff0c;所以采用了 pdf.js 而不是各种第三方封装库&#xff0c;主要还是为了更好的自由度。 一、PDF.js 介绍 官方地址 中文文档 PDF.js 是一个使用 HTML5 构建的便携式文档格式查看器。 pdf.js 是社区…

ThreeJs实现简单的动画

上一节实现可用鼠标控制相机的方式实现动态效果&#xff0c;但很多时候是需要场景自己产恒动态效果&#xff0c;而不是通过鼠标拖动&#xff0c;此时引入一个requestAnimationFrame方法&#xff0c;它实际上是通过定时任务的方式&#xff0c;每隔一点时间改变场景中内容后重新渲…

Ant Design Vue 树形表格计算盈收金额

树形表格计算 一、盈收金额计算1、根据需要输入的子级位置&#xff0c;修改数据2、获取兄弟节点数据&#xff0c;并计算兄弟节点的金额合计3、金额合计&#xff0c;遍历给所有的父级 一、盈收金额计算 1、根据需要输入的子级位置&#xff0c;修改数据 2、获取兄弟节点数据&am…

销售管理系统的实用性怎么样?

销售管理系统好用吗&#xff1f;好用&#xff0c;销售管理系统可以管理销售流程、自动化大量重复性工作&#xff0c;让销售人员从琐碎的任务中挣脱出来&#xff0c;投入到客户跟进和维护客户关系之中。那么&#xff0c;CRM系统的好用体现在哪些方面&#xff1f; 1.加速销售流程…

react中的state

没想到hooks中也有state这一说法 看下面的两个案例 1、无state变化不会执行父子函数 2、有state更改执行父子函数

深度学习之六(自编码器--Autoencoder)

概念 自编码器(Autoencoder)是一种神经网络架构,用于无监督学习和数据的降维表示。它由两部分组成:编码器(Encoder)和解码器(Decoder)。 结构: 编码器(Encoder): 接收输入数据并将其压缩为潜在表示(latent representation),通常比输入数据的维度要低。编码器的…

最详细的软件测试面试题整理与分析

前言 时光荏苒&#xff0c;一转眼到了2023年末尾&#xff0c;2024年也快要来了&#xff0c;人员就业市场以往的寒冬也貌似有了转暖的迹象&#xff0c;身边大批的就业人员也开始了紧张的备战之中。 近几周也和多家合作公司的HR进行了沟通&#xff0c;发现虽然岗位就业情况较去年…

vue3中引入svg矢量图

vue3中引入svg矢量图 1、前言2、安装SVG依赖插件3、在vite.config.ts 中配置插件4、main.ts入口文件导入5、使用svg5.1 在src/assets/icons文件夹下引入svg矢量图5.2 在src/components目录下创建一个SvgIcon组件5.3 封装成全局组件&#xff0c;在src文件夹下创建plugin/index.t…

一键创新 | 拓世法宝AI智能直播一体机激发房产自媒体创造力

在数字化时代&#xff0c;房产销售已然不再是传统的模式。随着社交媒体和自媒体的兴起&#xff0c;短视频直播成为房产自媒体营销的新风口。然而&#xff0c;行业也面临着诸多挑战&#xff0c;如何更好地利用新媒体拓展市场&#xff0c;提升自媒体效果成为摆在业内人士面前的难…

JMeter测试报错422 Unprocessable Entity

添加HTTP信息头&#xff1a; ​ HTTP请求-》添加-〉配置元件-》HTTP信息头管理器 ​ 如果需要送json&#xff0c;需要添加Content-Type:application/json&#xff0c;否则会报【422 Unprocessable Entity】

好用的CRM系统到底有多重要?怎么选?

我们都知道&#xff0c;CRM软件可以让企业效率加倍。但如果选错了CRM&#xff0c;企业损失点钱是小&#xff0c;客户转化率下降才是大。下面我们就来说说&#xff0c;市面上有哪些好用的CRM&#xff1f;以及好用的CRM软件的重要性。 好用的CRM软件的重要性&#xff1a; 客户管…