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

这篇具有很好参考价值的文章主要介绍了【Unity】URP屏幕后处理UI模糊效果实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java 这里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;//缓冲区1
        private RenderTargetHandle m_Buffer1;//缓冲区2

        private 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_Buffer0
                m_Buffer1 = tmp;
            }
            cmd.Blit(m_Buffer0.Identifier(), m_Source); //将最终结果渲染到摄像机上
            //执行cmd
            context.ExecuteCommandBuffer(cmd);
            //清空回收cmd
            cmd.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); //创建一个pass
        m_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 //CG
		HLSLINCLUDE
		//#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); //CG
			VertexPositionInputs 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); //CG
			VertexPositionInputs 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然后进行乘以对应的权重累加到sum
			half3 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 //CG
		ENDHLSL

		//上面都是INCLUDE内容即下面Pass都可使用的内容
		//标配写法
		ZTest Always Cull Off ZWrite Off
		//第一个PASS,纵向模糊处理
		Pass
		{
			NAME "GAUSSIAN_BLUR_VERTICAL"

			//CGPROGRAM //CG
			HLSLPROGRAM

			//纵向的顶点着色器
			#pragma vertex vertBlurVertical
			//片元着色器
			#pragma fragment fragBlur

			//ENDCG //CG
			ENDHLSL
		}
		//第二个Pass 横向模糊处理
		Pass
		{
			NAME "GAUSSIAN_BLUR_HORIZONTAL"

			//CGPROGRAM
			HLSLPROGRAM

			//横向的顶点着色器
			#pragma vertex vertBlurHorizontal
			//片元着色器
			#pragma fragment fragBlur

			//ENDCG
			ENDHLSL
		}
	}//完成SubShader
	Fallback Off
}

1个Canvas和2个摄像机

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

【Unity】URP屏幕后处理UI模糊效果实现,Shader,Unity3d,# Shader案例,unity,ui,java

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

TODO!!!文章来源地址https://www.toymoban.com/news/detail-688771.html

到了这里,关于【Unity】URP屏幕后处理UI模糊效果实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何通过代码在Unity设置URP通用渲染管线资源的画质选项、后处理效果、渲染分辨率、抗锯齿效果、Renderer Features等效果并制作一个可以设置它们的UI

       Hello喔 这里是没有鱼的猫先生,本期文章的主题佬们有看到标题了 QWQ    当使用Urp管道项目时,我们需要在一个Urp通用管线资源的项目中修改它的各种效果以玩家自己设置不同的画质需求,那下面这个通用脚本便诞生了,它也许并不适用于所有的场景,但是相信应用过它

    2024年02月09日
    浏览(32)
  • 【unity插件】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件

    一般的shader无法直接使用在UI上,需要在shader中定义特定的面板参数,今天就来推荐github上大佬做的一套开源的一系列UGUI,Shader实现的特效——UIEffect 为 Unity UI 提供视觉效果组件。 https://github.com/Ankh4396/UIEffect 让我们用效果来装饰你的UI!您可以根据需要从脚本和检查器中控

    2024年02月04日
    浏览(35)
  • 【Unity Shader Graph URP渲染管线下的自定义半透明效果_半透明案例分享】

    URP的渲染管线下 在项目设置里找到“Graphic” 找到URP Asset文件 索引到Renderer List文件——“ForwardRenderer” 在这个“ForwardRenderer”文件里找到“Add Renderer Feature” 添加一个渲染对象,类似下图:Render Object (Experimental) 如图设置,将“Event”设置成 AfterRenderingSkybox ,然后“Layer M

    2024年02月09日
    浏览(46)
  • 【游戏开发小技】Unity通过UI全屏图来模糊场景画面(Shader | 模糊 | 滤镜 | Blur)

    一、前言 嗨,大家好,我是新发。 以前我写文章都是很长很长,接下来我会尝试用新的方式来写博客,尽量简短,以实用为主。同时也是作为自己零碎的一些记录,方便查阅。 本文我要说的是在 Unity 中通过 UI 全屏图来模糊场景画面的效果。 二、效果演示 这是没用模糊效果

    2024年02月05日
    浏览(32)
  • unity webgl网页运行后屏幕模糊,UI无响应问题解决

    【记一个莫名其妙的问题】 工具:Unity 2019.4.40f1c1 先前Unity打包apk,设置了最大帧率15 在Project Settings -Quality中设置了Other-VSync Count:Don’t Sync 运行后,帧率稳定在100上下,呵呵 后来在代码中加了一行: 问题解决 今天,准备再打一个webgl包 打包运行后,打开网页,画面停留在

    2024年02月06日
    浏览(29)
  • Unity自定义后处理——模糊效果

      大家好,我是阿赵。   继续介绍后处理的做法,这一期介绍的是模糊效果的做法。 我们还是用这个角色作为背景来实现模糊效果 这是模糊后的效果 根据不同的参数,可以调整不同的模糊程度。   在介绍做法之前,首先要明确一个基本的认知,模糊效果是非常消耗

    2024年02月03日
    浏览(31)
  • 【Unity3d】【相机】透视相机UI转换(3DUI+保持屏幕比例)

    0. 基础知识点 正交相机 : 正交相机的的orthographicSize ,是 二分之一的屏幕高度,即 orthographicSize = H/2。 透视相机 : 相机的aspect为相机的视口的宽高比: aspect = W/H 即: W = H * aspect 透视相机的屏幕高度H 随着相机的中心距离和fov变化。公式为: H = distance * tan(fov*0.5) * 2 相机视

    2024年02月04日
    浏览(79)
  • 【Unity3D小功能】Unity3D中实现UI擦除效果、刮刮卡功能

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 使用Unity3D实现UI的擦拭效果、刮刮卡功能的效果实现方式比较多,比如说用Shader、Texture渲染都是可以

    2024年02月04日
    浏览(201)
  • Unity 引擎做残影效果——2、屏幕后处理方式

    Unity实现残影效果   大家好,我是阿赵。   这里继续介绍Unity里面做残影的方法。之前介绍了BakeMesh的方法做残影,这一期介绍的是用屏幕后处理的方法做残影。   之前的BakeMesh方法,是真的生成了很多个网格模型在场景里面。如果用后处理做,就没有这个过程。   

    2024年01月17日
    浏览(31)
  • Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)

    我们在这篇文章中,了解一下URP中Shader怎么实现菲涅尔效果,同时学习一下URP下怎么获取法线 和 视线向量。 Lambert光照模型公式: Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L)) 实现灯光照射中间亮 周围暗的效果,核心是dot(N,L) Unity中Shader的Lambert光照的实现 光照效果下, 视线单

    2024年02月02日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包