首页 > 其他分享 >后处理 - 泛光Bloom

后处理 - 泛光Bloom

时间:2024-03-29 22:45:35浏览次数:15  
标签:RenderTexture TempRT1 后处理 source private BlurMat 泛光 Bloom public

原理

泛光其实就是让图片变亮,看着有种自身在发光的感觉。

那怎么做呢?简单点,就是图片模糊处理后,再与原来的颜色值相加,就能使整体颜色变亮,但直接这样做可能会让颜色太亮而过曝,所以可以在图片模糊前做下颜色值的控制,防止相加后直接成为白色。

 

效果

 

c#代码

using UnityEngine;

public class BloomEff : MonoBehaviour
{
    public Shader m_BlurShader;
    public Material m_BlurMat;

    [Range(-3, 3)]
    public float m_BlurOffset = 1;

    public bool m_DoubleBlur; //是否启用双重模糊

    private int m_SrcRTWidth;
    private int m_SrcRTHeight;

    private RenderTexture m_RTHalfSize; //一半大小
    private RenderTexture m_RTQuarterSize; //1/4大小

    public Shader m_BloomBrightShader;
    public Material m_BloomBrightMat;
    [Range(0, 1)]
    public float m_BrightCut = 0.5f;

    public Shader m_BloomShader;
    public Material m_BloomMat;

    private RenderTexture m_TempRT1;
    private RenderTexture m_BlurRT;

    void Start()
    {
        if (false == SystemInfo.supportsImageEffects)
        {
            Debug.LogWarning("This platform does not support image effects or render textures.");
            this.enabled = false;
            return;
        }
        InitMaterial(ref m_BlurShader, ref m_BlurMat);
        if (null != m_BlurMat)
            m_BlurMat.SetFloat("_BlurOffset", m_BlurOffset);
        InitMaterial(ref m_BloomBrightShader, ref m_BloomBrightMat);
        InitMaterial(ref m_BloomShader, ref m_BloomMat);
    }

    private static void InitMaterial(ref Shader s, ref Material mat)
    {
        if (null == mat)
        {
            if (null != s && s.isSupported)
            {
                mat = new Material(s);
                mat.hideFlags = HideFlags.DontSave;
            }
        }
        else if (null != s && mat.shader != s)
        {
            if (s.isSupported) //优先shader
            {
                mat = new Material(s);
                mat.hideFlags = HideFlags.DontSave;
            }
            else
            {
                mat = null;
            }
        }
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (null == m_BlurMat)
        {
            Graphics.Blit(source, destination);
        }
        else
        {
            if (null == m_TempRT1 || m_TempRT1.width != source.width || m_TempRT1.height != source.height)
            {
                m_TempRT1 = RenderTexture.GetTemporary(source.width, source.height);
                m_BlurRT = RenderTexture.GetTemporary(source.width, source.height);
            }
#if UNITY_EDITOR
            m_BlurMat.SetFloat("_BlurOffset", m_BlurOffset);
            m_BloomBrightMat.SetFloat("_BrightCut", m_BrightCut);
#endif
            Graphics.Blit(source, m_TempRT1, m_BloomBrightMat); //图片模糊前控制下颜色值
            if (m_DoubleBlur)
                DoubleBlur(m_TempRT1, m_BlurRT);
            else
                Graphics.Blit(m_TempRT1, m_BlurRT, m_BlurMat, 0); //图片模糊

            m_BloomMat.SetTexture("_brightTex", m_BlurRT);

            Graphics.Blit(source, destination, m_BloomMat);
        }

    }

    private void DoubleBlur(RenderTexture source, RenderTexture destination)
    {
        if (m_SrcRTWidth != source.width || m_SrcRTHeight != source.height)
        {
            m_SrcRTWidth = source.width;
            m_SrcRTHeight = source.height;
            m_RTHalfSize = RenderTexture.GetTemporary((int)(m_SrcRTWidth * 0.5f), (int)(m_SrcRTHeight * 0.5f));
            m_RTQuarterSize = RenderTexture.GetTemporary((int)(m_SrcRTWidth * 0.25f), (int)(m_SrcRTHeight * 0.25f));
        }

        //降采样
        Graphics.Blit(source, m_RTHalfSize, m_BlurMat, 0);
        Graphics.Blit(m_RTHalfSize, m_RTQuarterSize, m_BlurMat, 1);

        //升采样
        Graphics.Blit(m_RTQuarterSize, m_RTHalfSize, m_BlurMat, 0);
        Graphics.Blit(m_RTHalfSize, destination, m_BlurMat, 1);
    }

    void OnDestroy()
    {
        if (null != m_TempRT1)
        {
            RenderTexture.ReleaseTemporary(m_TempRT1);
            m_TempRT1 = null;
        }
    }

}

 

BloomBright.shader

Shader "My/PostEff/BloomBright" //控制要叠加图片的像素值, 防止过量
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {} //主贴图
		_BrightCut("LightVal", Range(0, 1)) = 0.5 //降低要叠加图片的颜色值, 防止相加后过亮
	}

	SubShader
	{
		Cull Off //剔除: 关
		ZWrite Off //深度缓冲buff写入: 关
		ZTest Always //深度测试: 开

		Pass
		{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag

			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float _BrightCut;

			fixed4 frag(v2f_img i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				float br = max(max(col.r, col.g), col.b); //取rgb中颜色值最大的
				br = max(0, (br - _BrightCut)) / max(br, 0.00001);
				col.rgb *= br;
				return col;
			}
			ENDCG
		}
	}
}

 

Bloom.shader

Shader "My/PossEff/Bloom"
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {} //主贴图
		_brightTex("BrightTex",2D) = "black" //要叠加的贴图
	}
	
	SubShader
	{
		Cull Off //剔除: 关
		ZWrite Off //深度缓冲buff写入: 关
		ZTest Always //深度测试: 开

		Pass
		{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag

			#include "UnityCG.cginc"

			sampler2D _MainTex;
			sampler2D _brightTex;

			half4 frag(v2f_img i) : SV_Target //片元着色器
			{
				half4 col = tex2D(_MainTex, i.uv);
				half4 brightCol = tex2D(_brightTex, i.uv);
				col.rgb += brightCol.rgb; //颜色相加就能让颜色更亮了
				return col;
			}
			ENDCG
		}
	}

}

 

参考

Unity自定义后处理——Bloom效果_unity 3d bloom效果-CSDN博客

 

标签:RenderTexture,TempRT1,后处理,source,private,BlurMat,泛光,Bloom,public
From: https://www.cnblogs.com/sailJs/p/18103464

相关文章

  • 后处理 - 高斯模糊
    原理采样5x5范围的像素(即25个像素),然后按中间往外减少的权重值,计算出最终颜色值。 效果 c#代码usingUnityEngine;publicclassGaussianBlurEff:MonoBehaviour{publicShaderm_Shader;publicMaterialm_Material;[Range(-3,3)]publicfloa......
  • 后处理 - 均值模糊
    原理就是取自身以及该像素周围的8个像素的颜色值相加,然后除9取个平均值,得到最终颜色值 效果因为模糊后会出现一些方形的像素效果,模糊效果不是很平均,所以均值模糊也叫做盒状模糊。 c#代码usingUnityEngine;publicclassBoxBlurEff:MonoBehaviour{publicSha......
  • 后处理 - 色调映射
    就是将颜色值通过映射公式得到另一种颜色值,比如:将颜色值*0.8也算是映射公式但这边介绍的映射公式可以得到一种电影校色的效果,至于原理,一般都是经验公式。 效果 c#代码usingUnityEngine;publicclassTonemappingEff:MonoBehaviour{publicShaderm_Shader;......
  • 后处理 - 亮度,饱和度,对比度
    效果 c#代码usingUnityEngine;publicclassMyBrightnessSaturationAndContrast:MonoBehaviour{publicShaderm_Shader;publicMaterialm_Material;[Range(0.0f,3.0f)]publicfloatm_brightness=1.0f;[Range(0.0f,3.0f)]publ......
  • bloom 算法
    该文章翻译自(https://www.enjoyalgorithms.com/blog/bloom-filter/)[https://www.enjoyalgorithms.com/blog/bloom-filter/]Bloom过滤器是一种空间效率高的概率数据结构,它能告诉我们某个元素可能在某个集合中,或者肯定不在某个集合中。如果我们在Bloom过滤器中查找一个项,可以......
  • MK Glow - Bloom & Lens & Glare
    MKGlow(Ultimate)是一种使用简单、功能丰富且效果超级迅速的后处理效果,可以模拟明亮表面的光照散射。除了散光效果之外,还提供一些高度自定义的特效,比如镜头表面、镜头眩光和强光。该着色器兼容传统、轻便、通用和高分辨率渲染管线。两大直观工作流程:阈值:根据像素亮度、阈值和......
  • 什么是布隆过滤器(Bloom Filter)?以及布隆过滤器的详细说明。
    什么是布隆过滤器(BloomFilter)?以及布隆过滤器的详细说明。布隆过滤器(BloomFilter):​ 是一种空间效率高、时间复杂度低的数据结构,用于判断一个元素是否属于一个集合。它通过使用多个哈希函数和位数组来实现快速的成员存在性检测,但有一定的误判率。结构:位数组(BitArray):布隆过......
  • CF1583E Moment of Bloom 题解
    题意:给定一张\(n\)个点\(m\)条边无向连通图,以及\(q\)个点对\((a,b)\),出事每条边权值为\(0\)。对于每个点对我们需要找一条从一个点到另一个点的简单路径,将所有边的权值加一。要求构造一种方案使得每条边权值都是偶数。如果不行,输出最少还要几个点对才能满足要求。\(n,m......
  • 关于URP14绘制全屏Blit后处理的改动
    最近用回URP,发现RendererFeature这部分改动很大,启用了之前HDRP的RTHandle,RTHandle的设计类似于优化版本的RenderTexture,可以统一控制缩放或者并非一对一的RT内存申请。并且Blit的方式变成了先SetTarget后做一次绘制,也是和HDRP对齐。 在新的URP中实现全屏后处理效果可以走Stac......
  • 【ABAQUS脚本】后处理快速出图
    效果图:#-*-coding:utf-8-*-#Donotdeletethefollowingimportlinesfromabaqusimport*fromabaqusConstantsimport*import__main__fromodbAccessimport*#odbnameodbName='Job-case1.odb'myodb=session.odbs[odbName]stepName='S......