【Unity】URP屏幕后处理UI模糊效果实现

 这里Canvas(1)设置为Overlay能渲染出指定UI高清,其他UI模糊,然而这做法非常不好,如果此时再打开UI 以及 关闭模糊效果 要将这些置顶UI 恢复到原本Canvas里,也就是要管理2套Canvas

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;public class Blur : ScriptableRendererFeature
{[Serializable] //序列化 会在ForwardRenderer下创建Blur时看到m_Data就是它public class BlurData{//blur材质public Material material;public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;//渲染次数,次数越大图像会越模糊[Range(0, 4)]public int iterations = 3;//模糊采样间距,越大越模糊[Range(0.2f, 3.0f)]public float blurSpread = 0.6f;//缩小比例(2代表缩小1/2) 越大越模糊,性能越好,但是会逐渐像素化![Range(1, 8)]public int downSample = 2;}public class BlurRenderPass : ScriptableRenderPass{private BlurData m_Data; //ForwardRenderer下Blur(ScriptableRendererFeature)资源的序列化参数数据private RenderTargetIdentifier m_Source;//屏幕图private RenderTargetHandle m_Buffer0;//缓冲区1private RenderTargetHandle m_Buffer1;//缓冲区2private int m_BlurSize = Shader.PropertyToID("_BlurSize");public BlurRenderPass(BlurData data){this.m_Data = data;}public void Setup(RenderTargetIdentifier cameraColorTarget){m_Buffer0.Init("_Buffer0");m_Buffer1.Init("_Buffer1");this.m_Source = cameraColorTarget;//该pass所在管线 ForwardRenderer 所处的摄像机主纹理}public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor){var width = cameraTextureDescriptor.width / m_Data.downSample;var height = cameraTextureDescriptor.height / m_Data.downSample;cmd.GetTemporaryRT(m_Buffer0.id, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);cmd.GetTemporaryRT(m_Buffer1.id, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);}public override void FrameCleanup(CommandBuffer cmd){cmd.ReleaseTemporaryRT(m_Buffer0.id);cmd.ReleaseTemporaryRT(m_Buffer1.id);}public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){var mat = m_Data.material;if (mat == null) return;//renderingData.cameraData.camera 可获取摄像机判定哪个摄像机才进行处理渲染(每个摄像机都会进一遍pass 如果摄像机有多个且都有这个Blur(ScriptableRendererFeature资源)CommandBuffer cmd = CommandBufferPool.Get("MyBlurCmd"); //从池获取一个cmd 命名为MyBlurCmd 能在FrameDebugger看到cmd.Blit(m_Source, m_Buffer0.Identifier());//将摄像机图渲染至buffer0//开始iterations次渲染,每次都会进行2次Pass操作:横向、纵向(谁先谁后都无所谓for (int i = 0; i < m_Data.iterations; i++){mat.SetFloat(m_BlurSize, 1.0f + i * m_Data.blurSpread);//指定采样间距,逐级递增的形式cmd.Blit(m_Buffer0.Identifier(), m_Buffer1.Identifier(), mat, 0);var tmp = m_Buffer0;m_Buffer0 = m_Buffer1; //注意最终都会将渲染结果输出到m_Buffer0m_Buffer1 = tmp;}cmd.Blit(m_Buffer0.Identifier(), m_Source); //将最终结果渲染到摄像机上//执行cmdcontext.ExecuteCommandBuffer(cmd);//清空回收cmdcmd.Clear();CommandBufferPool.Release(cmd);}}public BlurData data = new BlurData();private BlurRenderPass m_Pass;public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData){var src = renderer.cameraColorTarget;m_Pass.Setup(src); //设置摄像机输出的颜色纹理renderer.EnqueuePass(m_Pass); //入队渲染pass}public override void Create(){m_Pass = new BlurRenderPass(data); //创建一个passm_Pass.renderPassEvent = data.renderPassEvent; //设置pass的渲染时机在某个节点后(导致问题,无法类似grab一样在某一个UI渲染时进行渲染 而必须等到所有UI渲染完成才进行渲染。。//无法做到置顶UI高清,底下UI模糊的效果.//所以下一步是思考如何实现这个吧..}
}

Shader代码实现模糊 

//注意 注释掉的CGINCLUDE CDEND UnityCG.cginc 等一系列带cg或注释的方法都是传统CG管线的内容
// 新内容会是HLSLxxx字眼形式出现 (目的是演示如何将CG代码改为URP管线代码)
Shader "MilkShader/Twently/G_GaussianBlur"
{Properties{_MainTex("Texture", 2D) = "white" {}//采样间距系数_BlurSize("Blur Size", Float) = 1.0}SubShader{Tags { "RenderType" = "Opaque" }LOD 100//CGINCLUDE ... ENDCG 是一种组织结构,放在它里面的方法可以被任意Pass直接使用..相当于所有Pass都会有这些内容//CGINCLUDE //CGHLSLINCLUDE//#include "UnityCG.cginc" //CG#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"sampler2D _MainTex;half4 _MainTex_TexelSize;float _BlurSize;//URP下没有appdata_img结构 要自定义struct a2v{float4 vertex : POSITION;float2 texcoord : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;half2 uv[5] : TEXCOORD0;};//我们只需要appdata_img内置结构的数据传入即可(有顶点、纹理坐标)v2f vertBlurVertical(a2v v) {v2f o;//o.pos = UnityObjectToClipPos(v.vertex); //CGVertexPositionInputs vertexInputs = GetVertexPositionInputs(v.vertex.xyz);o.pos = vertexInputs.positionCS;half2 uv = v.texcoord;//纵向的5个像素点纹理坐标o.uv[0] = uv;o.uv[1] = uv + float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[2] = uv - float2(0.0, _MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[3] = uv + float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;o.uv[4] = uv - float2(0.0, _MainTex_TexelSize.y * 2.0) * _BlurSize;return o;}v2f vertBlurHorizontal(a2v v) {v2f o;//o.pos = UnityObjectToClipPos(v.vertex); //CGVertexPositionInputs vertexInputs = GetVertexPositionInputs(v.vertex.xyz);o.pos = vertexInputs.positionCS;half2 uv = v.texcoord;//横向的5个像素点纹理坐标o.uv[0] = uv;o.uv[1] = uv + float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;o.uv[2] = uv - float2(_MainTex_TexelSize.x * 1.0, 0.0) * _BlurSize;o.uv[3] = uv + float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;o.uv[4] = uv - float2(_MainTex_TexelSize.x * 2.0, 0.0) * _BlurSize;return o;}//无论是纵向还是横向,它们都会使用这个片元着色器,处理手法一样half4 fragBlur(v2f i) : SV_Target{float weight[3] = {0.4026, 0.2442, 0.0545};//采样RGB然后进行乘以对应的权重累加到sumhalf3 sum = tex2D(_MainTex, i.uv[0]).rgb * weight[0];for (int it = 1; it < 3; it++) {sum += tex2D(_MainTex, i.uv[it * 2 - 1]).rgb * weight[it];sum += tex2D(_MainTex, i.uv[it * 2]).rgb * weight[it];}//是的这样就完成了,模糊。。。。return half4(sum, 1.0);}//ENDCG //CGENDHLSL//上面都是INCLUDE内容即下面Pass都可使用的内容//标配写法ZTest Always Cull Off ZWrite Off//第一个PASS,纵向模糊处理Pass{NAME "GAUSSIAN_BLUR_VERTICAL"//CGPROGRAM //CGHLSLPROGRAM//纵向的顶点着色器#pragma vertex vertBlurVertical//片元着色器#pragma fragment fragBlur//ENDCG //CGENDHLSL}//第二个Pass 横向模糊处理Pass{NAME "GAUSSIAN_BLUR_HORIZONTAL"//CGPROGRAMHLSLPROGRAM//横向的顶点着色器#pragma vertex vertBlurHorizontal//片元着色器#pragma fragment fragBlur//ENDCGENDHLSL}}//完成SubShaderFallback Off
}

1个Canvas和2个摄像机

主要以上内容,实际上就是因为Render Pass Event是只能After Rendering Transpanrets在透明物体渲染完成后进行屏幕后处理模糊,导致无法实现置顶UI高清,底下UI模糊的需求,如果可以控制这个后处理时机是在置顶UI渲染之前进行后处理,等后处理完成后再渲染指定UI 那就可以,然而...

TODO!!!

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

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

相关文章

统一使用某一个包管理工具,比如yarn pnpm

原因&#xff1a;前端每个人的习性不一样&#xff0c;有人用npm 有人用yarn等包管理工具&#xff0c;混合下载插件容易出bug&#xff0c;就用个小工具锁住就行了&#xff0c;只能使用yarn或者pnpm反向下载依赖和下载插件。不然就报错 1.在项目主目录下创建preinstall.js // 如…

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测 目录 分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测分类效果基本介绍模型描述预测过程程序设计参考资料分类效果 基本介绍 MATLAB实现GRNN广义回归神经网络多特

Mybatis学习|多对一、一对多

有多个学生&#xff0c;没个学生都对应&#xff08;关联&#xff09;了一个老师&#xff0c;这叫&#xff08;多对一&#xff09; 对于每个老师而言&#xff0c;每个老师都有N个学生&#xff08;学生集合&#xff09;&#xff0c;这叫&#xff08;一对多&#xff09; 测试环境…

【小沐学Unity3d】3ds Max 骨骼动画制作(Physique 修改器)

文章目录 1、简介2、Physique 工作流程3、Physique 对象类型4、Physique 增加骨骼5、Physique 应用和初始化6、Physique 顶点子对象7、Physique 封套子对象8、设置关键点和自动关键点模式的区别8.1 自动关键点8.2 设置关键点 结语 1、简介 官方网址&#xff1a; https://help.…

Python Opencv实践 - 轮廓检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/map.jpg") print(img.shape) plt.imshow(img[:,:,::-1])#Canny边缘检测 edges cv.Canny(img, 127, 255, 0) plt.imshow(edges, cmapplt.cm.gray)#查找轮廓 #c…

AI助乡行——点燃乡村振兴新引擎

随着数字化浪潮的袭来&#xff0c;乡村振兴战略的推进离不开数字化、智慧化等现代化治理能力和方式&#xff0c;人工智能等高新技术正不断与农村经济、社会、治理等加速融合。在智慧农业的背景下&#xff0c;我们可以解决一系列困扰农民的问题&#xff0c;包括如何增加经济作物…

【jvm】运行时数据区

目录 一、运行时数据区一、作用二、说明三、线程共用与私有区域 一、运行时数据区 一、作用 1.内存是非常重要的系统资源&#xff0c;是硬盘和CPU 的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策…

基于Gin框架的HTTP接口限速实践

在当今的微服务架构和RESTful API主导的时代&#xff0c;HTTP接口在各个业务模块之间扮演着重要的角色。随着业务规模的不断扩大&#xff0c;接口的访问频率和负载也随之增加。为了确保系统的稳定性和性能&#xff0c;接口限速成了一个重要的话题。 1 接口限速的使用场景 接口…

GA遗传算法

储备知识 GA算法主要解决数学模型中最优化的搜索算法&#xff0c;是进化算法中的一种&#xff0c;基因算法借鉴了自然界基因的遗传的主要现象&#xff0c;分别为遗传&#xff0c;变异&#xff0c;自然选择&#xff0c;杂交等。 GA算法参数 GA算法的参数如下所示。 种群规模…

通义千问部署搭建

文章目录 一、部署11.1 打开通义千问-7B-预训练-模型库-选择资源1.2 使用Netbook2.1 运行2.2 复制脚本2.2.1 问题1 &#xff1a;ImportError: This modeling file requires the following packages that were not found in your environment: transformers_stream_generator. R…

【请求报错:javax.net.ssl.SSLHandshakeException: No appropriate protocol】

1、问题描述 在请求服务时报错说SSL握手异常协议禁用啥的&#xff0c;而且我的连接数据库的url也加了useSSLfalse javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)2、解决方法 在网上查找了方法…

【C++笔记】C++内存管理

【C笔记】C内存管理 一、C中动态内存申请的方式二、new和delete的实现原理2.1、operator new和operator delete函数 一、C中动态内存申请的方式 在C语言中我们需要动态申请空间的时候我们通常都是用malloc函数&#xff0c;但是malloc函数对自定义类型是没什么问题的&#xff0…

Jenkins清理构建(自动)

需求背景实现方法 Dashboard-->Project-->配置-->General-->Discard old builds # 注意&#xff1a;自动清理构建历史将在下次构建时进行

【校招VIP】产品面试之职业规划

考点介绍&#xff1a; 对于刚入行的产品同学&#xff0c;由于行业知识和经验不足&#xff0c;只能执行上层的产品策略&#xff0c;但是与团队的沟通是非常重要的&#xff0c;产品经理就是沙丁鱼中的鲶鱼&#xff0c;必须要能够把控整个团队的开发节奏&#xff0c;知道如何最大化…

个微机器人开发接口

请求URL&#xff1a; http://域名地址/member/login域名地址开发者账号密码:后台系统自助开通 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/json 参数&#xff1a; 参数名必选类型说明account是string开发者账号password…

Swift 技术 视频播放器滚动条(源码)

一直觉得自己写的不是技术&#xff0c;而是情怀&#xff0c;一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的&#xff0c;希望我的这条路能让你们少走弯路&#xff0c;希望我能帮你们抹去知识的蒙尘&#xff0c;希望我能帮你们理清知识的脉络&#xff0…

core dump管理在linux中的前世今生

目录 一、什么是core dump&#xff1f; 二、coredump是怎么来的&#xff1f; 三、怎么限制coredump文件的产生&#xff1f; ulimit 半永久限制 永久限制 四、从源码分析如何对coredump文件的名字和路径管理 命名 管理 一些问题的答案 1、为什么新的ubuntu不能产生c…

一百六十九、Hadoop——Hadoop退出NameNode安全模式与查看磁盘空间详情(踩坑,附截图)

一、目的 在海豚跑定时跑kettle的从Kafka到HDFS的任务时&#xff0c;由于Linux服务器的某个文件磁盘空间满了&#xff0c;导致Hadoop的NodeName进入安全模式&#xff0c;此时光执行hdfs dfsadmin -safemode leave命令语句没有效果&#xff08;虽然显示Safe mode is OFF&#x…

HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。

HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。 HashMap相关问题 1、你用过HashMap吗&#xff1f;什么是HashMap&#xff1f;你为什么用到它&#xff1f;用过&#xff0c;HashMap是基于哈希表的Map接口的非同步实现&#xff0c; 它允许null键…

测试开发【Mock平台】09开发:项目管理(五)搜索、删除和Table优化

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;大奇一个专注测试技术干货原创与分享的家伙。 Mock平台系统项目基本…