HDRP图形入门:RTHandle未知问题

      正好电脑看奥本海默,全程尿点十足,就一边看一边把之前整合HDRP遇到的问题说一下。
      那就是RTHandle的未知问题,这是官方对RTHandle的说明:
      unity RTHandle
      源代码如下:

using System.Collections.Generic;
using UnityEngine.Rendering;

namespace UnityEngine.Rendering
{
    /// <summary>
    /// A RTHandle is a RenderTexture that scales automatically with the camera size.
    /// This allows proper reutilization of RenderTexture memory when different cameras with various sizes are used during rendering.
    /// <seealso cref="RTHandleSystem"/>
    /// </summary>
    public class RTHandle
    {
        internal RTHandleSystem m_Owner;
        internal RenderTexture m_RT;
        internal Texture m_ExternalTexture;
        internal RenderTargetIdentifier m_NameID;
        internal bool m_EnableMSAA = false;
        internal bool m_EnableRandomWrite = false;
        internal bool m_EnableHWDynamicScale = false;
        internal string m_Name;

        internal bool m_UseCustomHandleScales = false;
        internal RTHandleProperties m_CustomHandleProperties;

        /// <summary>
        /// By default, rtHandleProperties gets the global state of scalers against the global reference mode.
        /// This method lets the current RTHandle use a local custom RTHandleProperties. This function is being used
        /// by scalers such as TAAU and DLSS, which require to have a different resolution for color (independent of the RTHandleSystem).
        /// </summary>
        /// <param name="properties">Properties to set.</param>
        public void SetCustomHandleProperties(in RTHandleProperties properties)
        {
            m_UseCustomHandleScales = true;
            m_CustomHandleProperties = properties;
        }

        /// <summary>
        /// Method that clears any custom handle property being set.
        /// </summary>
        public void ClearCustomHandleProperties()
        {
            m_UseCustomHandleScales = false;
        }

        /// <summary>
        /// Scale factor applied to the RTHandle reference size.
        /// </summary>
        public Vector2 scaleFactor { get; internal set; }
        internal ScaleFunc scaleFunc;

        /// <summary>
        /// Returns true if the RTHandle uses automatic scaling.
        /// </summary>
        public bool useScaling { get; internal set; }
        /// <summary>
        /// Reference size of the RTHandle System associated with the RTHandle
        /// </summary>
        public Vector2Int referenceSize { get; internal set; }
        /// <summary>
        /// Current properties of the RTHandle System. If a custom property has been set through SetCustomHandleProperties method, it will be used that one instead.
        /// </summary>
        public RTHandleProperties rtHandleProperties { get { return m_UseCustomHandleScales ? m_CustomHandleProperties : m_Owner.rtHandleProperties; } }
        /// <summary>
        /// RenderTexture associated with the RTHandle
        /// </summary>
        public RenderTexture rt { get { return m_RT; } }
        /// <summary>
        /// RenderTargetIdentifier associated with the RTHandle
        /// </summary>
        public RenderTargetIdentifier nameID { get { return m_NameID; } }
        /// <summary>
        /// Name of the RTHandle
        /// </summary>
        public string name { get { return m_Name; } }

        /// <summary>
        /// Returns true is MSAA is enabled, false otherwise.
        /// </summary>
        public bool isMSAAEnabled { get { return m_EnableMSAA; } }

        // Keep constructor private
        internal RTHandle(RTHandleSystem owner)
        {
            m_Owner = owner;
        }

        /// <summary>
        /// Implicit conversion operator to RenderTargetIdentifier
        /// </summary>
        /// <param name="handle">Input RTHandle</param>
        /// <returns>RenderTargetIdentifier representation of the RTHandle.</returns>
        public static implicit operator RenderTargetIdentifier(RTHandle handle)
        {
            return handle != null ? handle.nameID : default(RenderTargetIdentifier);
        }

        /// <summary>
        /// Implicit conversion operator to Texture
        /// </summary>
        /// <param name="handle">Input RTHandle</param>
        /// <returns>Texture representation of the RTHandle.</returns>
        public static implicit operator Texture(RTHandle handle)
        {
            // If RTHandle is null then conversion should give a null Texture
            if (handle == null)
                return null;

            Debug.Assert(handle.m_ExternalTexture != null || handle.rt != null);
            return (handle.rt != null) ? handle.rt : handle.m_ExternalTexture;
        }

        /// <summary>
        /// Implicit conversion operator to RenderTexture
        /// </summary>
        /// <param name="handle">Input RTHandle</param>
        /// <returns>RenderTexture representation of the RTHandle.</returns>
        public static implicit operator RenderTexture(RTHandle handle)
        {
            // If RTHandle is null then conversion should give a null RenderTexture
            if (handle == null)
                return null;

            Debug.Assert(handle.rt != null, "RTHandle was created using a regular Texture and is used as a RenderTexture");
            return handle.rt;
        }

        internal void SetRenderTexture(RenderTexture rt)
        {
            m_RT = rt;
            m_ExternalTexture = null;
            m_NameID = new RenderTargetIdentifier(rt);
        }

        internal void SetTexture(Texture tex)
        {
            m_RT = null;
            m_ExternalTexture = tex;
            m_NameID = new RenderTargetIdentifier(tex);
        }

        internal void SetTexture(RenderTargetIdentifier tex)
        {
            m_RT = null;
            m_ExternalTexture = null;
            m_NameID = tex;
        }

        /// <summary>
        /// Get the Instance ID of the RTHandle.
        /// </summary>
        /// <returns>The RTHandle Instance ID.</returns>
        public int GetInstanceID()
        {
            if (m_RT != null)
                return m_RT.GetInstanceID();
            else if (m_ExternalTexture != null)
                return m_ExternalTexture.GetInstanceID();
            else
                return m_NameID.GetHashCode(); // No instance ID so we return the hash code.
        }

        /// <summary>
        /// Release the RTHandle
        /// </summary>
        public void Release()
        {
            m_Owner.Remove(this);
            CoreUtils.Destroy(m_RT);
            m_NameID = BuiltinRenderTextureType.None;
            m_RT = null;
            m_ExternalTexture = null;
        }

        /// <summary>
        /// Return the input size, scaled by the RTHandle scale factor.
        /// </summary>
        /// <param name="refSize">Input size</param>
        /// <returns>Input size scaled by the RTHandle scale factor.</returns>
        public Vector2Int GetScaledSize(Vector2Int refSize)
        {
            if (!useScaling)
                return refSize;

            if (scaleFunc != null)
            {
                return scaleFunc(refSize);
            }
            else
            {
                return new Vector2Int(
                    x: Mathf.RoundToInt(scaleFactor.x * refSize.x),
                    y: Mathf.RoundToInt(scaleFactor.y * refSize.y)
                );
            }
        }

        /// <summary>
        /// Return the scaled size of the RTHandle.
        /// </summary>
        /// <returns>The scaled size of the RTHandle.</returns>
        public Vector2Int GetScaledSize()
        {
            if (scaleFunc != null)
            {
                return scaleFunc(referenceSize);
            }
            else
            {
                return new Vector2Int(
                    x: Mathf.RoundToInt(scaleFactor.x * referenceSize.x),
                    y: Mathf.RoundToInt(scaleFactor.y * referenceSize.y)
                );
            }
        }

#if UNITY_2020_2_OR_NEWER
        /// <summary>
        /// Switch the render target to fast memory on platform that have it.
        /// </summary>
        /// <param name="cmd">Command buffer used for rendering.</param>
        /// <param name="residencyFraction">How much of the render target is to be switched into fast memory (between 0 and 1).</param>
        /// <param name="flags">Flag to determine what parts of the render target is spilled if not fully resident in fast memory.</param>
        /// <param name="copyContents">Whether the content of render target are copied or not when switching to fast memory.</param>

        public void SwitchToFastMemory(CommandBuffer cmd,
            float residencyFraction = 1.0f,
            FastMemoryFlags flags = FastMemoryFlags.SpillTop,
            bool copyContents = false
        )
        {
            residencyFraction = Mathf.Clamp01(residencyFraction);
            cmd.SwitchIntoFastMemory(m_RT, flags, residencyFraction, copyContents);
        }

        /// <summary>
        /// Switch the render target to fast memory on platform that have it and copies the content.
        /// </summary>
        /// <param name="cmd">Command buffer used for rendering.</param>
        /// <param name="residencyFraction">How much of the render target is to be switched into fast memory (between 0 and 1).</param>
        /// <param name="flags">Flag to determine what parts of the render target is spilled if not fully resident in fast memory.</param>
        public void CopyToFastMemory(CommandBuffer cmd,
            float residencyFraction = 1.0f,
            FastMemoryFlags flags = FastMemoryFlags.SpillTop
        )
        {
            SwitchToFastMemory(cmd, residencyFraction, flags, copyContents: true);
        }

        /// <summary>
        /// Switch out the render target from fast memory back to main memory on platforms that have fast memory.
        /// </summary>
        /// <param name="cmd">Command buffer used for rendering.</param>
        /// <param name="copyContents">Whether the content of render target are copied or not when switching out fast memory.</param>
        public void SwitchOutFastMemory(CommandBuffer cmd, bool copyContents = true)
        {
            cmd.SwitchOutOfFastMemory(m_RT, copyContents);
        }

#endif
    }
}

      我自己把它理解为一个动态的RT,和RT一样的使用,当然写代码用起来很容易。却碰到一个问题,以多迭代高斯滤波为例,使用RTHandle会造成纹理“发黄”,如下:
在这里插入图片描述      当时没感觉有问题,后面同事说这效果好奇怪,好黄?!我就感觉确实。起初我以为我shader颜色计算出问题了,查了半天不是。我百度google查了仅有不多有关RTHandle的帖子,并没找到相关问题,不过有个博主说复制一份RTHandle使用,我尝试做了一下,果然ok了。

//复制一份原始纹理
private RTHandle copySource;

public override void Setup()
{
    if (Shader.Find(shaderName) != null)
    {
        mat = new Material(Shader.Find(shaderName));

        copySource = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Bilinear, dimension: TextureDimension.Tex2DArray);
    }
    else
        Debug.LogError($"Unable to find shader '{shaderName}'. Post Process Volume GuassBlurPostProcessVolume is unable to load.");
}

public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination)
{
    if (mat == null || !isBlur.value)
    {
        return;
    }

    mat.SetFloat("_Brightness", brightness.value);

    //复制一份纹理
    //注意:由原始的纹理数组传递到单纹理,原始的纹理数组封装了多种平台下纹理集合
    HDUtils.BlitCameraTexture(cmd, source, copySource);

    //使用复制RTH还是原始RTH
    RenderTexture rtinput = isCopyRT.value ? copySource : source;

    int rtwid = rtinput.width / downSample.value;
    int rthei = rtinput.height / downSample.value;

    mat.SetTexture("_InputTex", rtinput);

    //对pass0进行迭代,增加高斯滤波次数和效果
    for (float it = 0; it < iterations.value; it += 0.2f)
    {
        mat.SetFloat("_BlurSpread", 1.0f + it * blurSpread.value);

        //滤波采样一次
        RenderTexture rt1 = RenderTexture.GetTemporary(rtwid, rthei, 0);

        cmd.Blit(rtinput, rt1, mat, 0);
        //叠加滤波
        cmd.Blit(rt1, rtinput);

        RenderTexture.ReleaseTemporary(rt1);
    }

    //采样迭代后的纹理
    mat.SetTexture("_IterTex", rtinput);

    cmd.Blit(rtinput, destination, mat, 1);
}

public override void Cleanup()
{
    CoreUtils.Destroy(mat);
    RTHandles.Release(copySource);
}

      虽然不明白为什么会这样,但确实解决了问题,如下:
在这里插入图片描述      如果大家写渲染功能,碰到类似的问题,不妨Copy一份RTHandle。

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

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

相关文章

04-快速掌握Redis,了解Redis中常见的结构类型及其应用场景

Redis快速入门 Remote Dctionary Server Redis是用C语言开发的一个开源的、基于内存的(高性能)键值对(key-value)结构化NoSql数据库,每秒内查询次数可以达到100000的QPS 键值型: Redis中存储的数据都是以key、value对的形式存储&#xff0c;而value的形式多种多样(如字符串、…

2023年第九届数维杯国际大学生数学建模挑战赛A题

2023年第九届数维杯国际大学生数学建模挑战赛正在火热进行&#xff0c;小云学长又在第一时间给大家带来最全最完整的思路代码解析&#xff01;&#xff01;&#xff01; A题思路解析如下&#xff1a; 完整版解题过程及代码&#xff0c;稍后继续给大家分享~ 更多题目完整解析点…

SpringCloud微服务:Nacos的集群、负载均衡、环境隔离

目录 集群 在user-service的yml文件配置集群 启动服务 负载均衡 order-service配置集群 设置负载均衡 当本地集群的服务挂掉时 访问权重 环境隔离 1、Nacos服务分级存储模型 一级是服务&#xff0c;例如userservice 二级是集群&#xff0c;例如杭州或上海 …

【AI视野·今日Sound 声学论文速览 第三十三期】Wed, 25 Oct 2023

AI视野今日CS.Sound 声学论文速览 Wed, 25 Oct 2023 Totally 8 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers CDSD: Chinese Dysarthria Speech Database Authors Mengyi Sun, Ming Gao, Xinchen Kang, Shiru Wang, Jun Du, Dengfeng Yao, Su Jing W…

jQuery【事件处理器、鼠标事件、表单事件、键盘事件、浏览器事件、事件对象、jQuery遍历】(三)-全面详解(学习总结---从入门到深化)

目录 事件之绑定事件处理器 事件之鼠标事件 事件之表单事件 事件之键盘事件 事件之浏览器事件 事件对象 jQuery遍历 事件之绑定事件处理器 1、 .on() 在选定的元素上绑定一个或多个事件处理函数 $("#button").on("click", function(event){console…

Android---网络编程优化

网络请求操作是一个 App 的重要组成部分&#xff0c;程序大多数问题都是和网络请求有关。使用 OkHttp 框架后&#xff0c;可以通过 EventListener 来查看一次网络请求的详细情况。一次完整的网络请求会包含以下几个步骤。 也就是说&#xff0c;一次网络请求的操作是从 DNS 解析…

第四代智能井盖传感器:万宾科技智能井盖位移监测方式一览

现在城市化水平不断提高&#xff0c;每个城市的井盖遍布在城市的街道上&#xff0c;是否能够实现常态化和系统化的管理&#xff0c;反映了一个城市治理现代化水平。而且近些年来住建部曾多次要求全国各个城市加强相关的井盖管理工作&#xff0c;作为基础设施重要的一个组成部分…

Python windows安装Python3环境

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

Vue3 自定义hook函数

这个hook函数并不是Vue3 自带的&#xff0c;而是为了方便我们书写和复用代码。 当我们在setup函数中写了很多内容过后&#xff0c;就会变得很乱&#xff0c;所以我们将实现相同功能的数据、方法和生命周期等等打包单独放在一个文件中&#xff0c;就会整洁很多。 例如&#xf…

Linux友人帐之网络编程基础邮件服务器与DHCP服务器

一、邮件服务器概述 1.1邮件服务基础 邮件服务器是一种计算机程序&#xff0c;它通过电子邮件协议接收、存储、处理和发送电子邮件。邮件服务器可以与电子邮件客户端程序&#xff08;如Outlook、Thunderbird等&#xff09;或Web邮件界面&#xff08;如Gmail、Outlook.com等&am…

操作系统OS/存储管理/内存管理/内存管理的主要功能_基本原理_要求

基本概念 内存管理的主要功能/基本原理/要求 **内存管理的主要功能&#xff1a; ** 内存空间的分配与回收。由操作系统完成主存储器空间的分配和管理&#xff0c;使程序员摆脱存储分配的麻烦&#xff0c;提高编程效率。地址转换。在多道程序环境下&#xff0c;程序中的逻辑地…

数字档案室建设评价

数字档案室建设评价应考虑以下几个方面&#xff1a; 1. 安全性&#xff1a;数字档案室的主要目的是确保档案资料的安全性。评价应考虑数字档案室的物理安全性、防火措施、保密措施、网络安全等方面。 2. 可访问性&#xff1a;数字档案室应该易于访问和使用。评价应考虑数字档案…

OCC教学:预备基础

预备基础&#xff1a;1.概览 什么是Open CASCADE Technology&#xff1f; Open CASCADE Technology (OCCT) 是一个功能强大的开源 C 库&#xff0c;由数千个类组 成&#xff0c;并提供以下领域的解决方案&#xff1a; 表面和实体建模&#xff1a;对任何对象进行建模。3D 和 …

制造业数据标准化的优势分析

之前我们介绍过>>数据驱动工作效率提升的5个层次——以PreMaint设备数字化平台为例&#xff0c;这次我们将深入分析数据标准化在制造业中的优势。 从持续的供应链中断和疯狂的通货膨胀&#xff0c;到日益昂贵和难以采购的原材料&#xff0c;制造企业正面对越来越多的挑战…

APM/PX4/betaflight/inav开源飞控之IMU方向

APM/PX4/betaflight/inav开源飞控之IMU方向 1. 源由2. 坐标系2.1 APM/PX4&#xff1a;机体坐标 右手系规则2.2 betaflight/inav&#xff1a;xEast-yNorth-zUp yaw反向 右手系规则 3. 转向定义3.1 APM/PX43.2 betaflight/inav 4. 实例4.1 I C M 42688 P ICM42688P ICM42688P…

把jar包打到本地仓库然后上传到私服

1.首先把需要打成maven的包放到本地 2.然后本地配置maven的环境变量 没有配置的话可以看看下面这个&#xff0c;教程很详细 Windows系统配置maven环境_windows配置maven环境变量-CSDN博客 3.WinR cmd 输入如下的指令&#xff1a; mvn install:install-file -Dfile.\device…

unity shaderGraph实例-扫描效果

文章目录 效果展示整体结构各区域内容区域1区域2区域3区域4区域5区域6GraphSetttings注意事项使用方法 效果展示 整体结构 各区域内容 区域1 用场景深度减去顶点的View空间的视野深度&#xff08;Z值&#xff09;&#xff0c;这里Z值需要乘-1是因为从相机看到的物体顶点的视野…

Kontakt Factory Library 2(Kontakt原厂音色库2)

Kontakt Factory Library 2是一款由Native Instruments开发的音乐采样库。它是Kontakt采样器软件的官方库之一&#xff0c;提供了丰富的音色和音乐资源&#xff0c;可用于制作各种类型的音乐。 Kontakt Factory Library 2包含了数千个高质量的乐器采样&#xff0c;涵盖了各种乐…

不会英语能学编程吗?0基础学编程什么软件好?

不会英语能学编程吗&#xff1f;0基础学编程什么软件好&#xff1f; 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件&#xff0c;象如图这个…

【数据分享】1961—2022年全国范围的逐日降水栅格数据

降水数据是我们在各项研究中最常用的气象指标之一&#xff01;之前我们给大家分享过来源于国家青藏高原科学数据中心发布的1901-2022年1km分辨率逐月降水栅格数据以及1901-2022年1km分辨率逐年降水栅格数据&#xff08;均可戳我跳转&#xff09;&#xff01;很多小伙伴拿到数据…