Unity默认管线移动端AR画质提升

适用于低性能处理器,没法使用post插件的替代方案,也适用web端;

Shader "Custom/Guassian"
{
    Properties {
        //定义贴图材质 2D
        //_Bloom值 2D
        //亮度阙值,float
        //模糊尺寸 Float
        //辉光强度
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Bloom ("Bloom (RGB)", 2D) = "black" {}
        _LuminanceThreshold ("Luminance Threshold", Float) = 0.5
        _BlurSize ("Blur Size", Float) = 1.0
        _BloomPow("辉光强度",Float)=1
        _Contrast("对比度",Float)=1
        _Brightness("亮度",Float)=1
    }
    SubShader {

        CGINCLUDE

        #include "UnityCG.cginc"

        sampler2D _MainTex;
        half4 _MainTex_TexelSize;
        sampler2D _Bloom;
        float _LuminanceThreshold;
        float _BlurSize;
        float _BloomPow,_Contrast,_Saturation,_Brightness,_Temperature,_Tint;
        //定义v2f
        ///pos
        ///uv
        struct v2f {
            float4 pos : SV_POSITION; 
            half2 uv : TEXCOORD0;
        };  
        //提取亮度的顶点着色器,appdata_img
        ///顶点转换,uv赋值
        v2f vertExtractBright(appdata_img v) {
            v2f o;      
            o.pos = UnityObjectToClipPos(v.vertex);     
            o.uv = v.texcoord;               
            return o;
        }

        fixed luminance(fixed4 color) {
            return  0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; 
        }
        //提取亮度的片元着色器
        ///先进行纹理采样
        ///进行亮度提取,采样得到的亮度值减去阙值,并截取到0-1中
        ///得到的值和原像素值相乘,得到提取后的亮部区域
        fixed4 fragExtractBright(v2f i) : SV_Target {
            fixed4 c = tex2D(_MainTex, i.uv);
            fixed val = clamp(luminance(c) - _LuminanceThreshold, 0.0, 1.0);

            return c * val;
        }

            //白平衡
            float3 WhiteBalance(float3 In, float Temperature, float Tint)
            {
                float t1 = Temperature * 10 / 6;
                float t2 = Tint * 10 / 6;
                float x = 0.31271 - t1 * (t1 < 0 ? 0.1: 0.05);
                float standardIlluminantY = 2.87 * x - 3 * x * x - 0.27509507;
                float y = standardIlluminantY + t2 * 0.05;
                float3 w1 = float3(0.949237, 1.03542, 1.08728);
                float Y = 1;
                float X = Y * x / y;
                float Z = Y * (1 - x - y) / y;
                float L = 0.7328 * X + 0.4296 * Y - 0.1624 * Z;
                float M = -0.7036 * X + 1.6975 * Y + 0.0061 * Z;
                float S = 0.0030 * X + 0.0136 * Y + 0.9834 * Z;
                float3 w2 = float3(L, M, S);
                float3 balance = float3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z);
                float3x3 LIN_2_LMS_MAT = {
                    3.90405e-1, 5.49941e-1, 8.92632e-3,
                    7.08416e-2, 9.63172e-1, 1.35775e-3,
                    2.31082e-2, 1.28021e-1, 9.36245e-1
                };
                float3x3 LMS_2_LIN_MAT = {
                    2.85847, -1.62879, -2.48910e-2,
                    - 2.10182e-1, 1.15820, 3.24281e-4,
                    - 4.18120e-2, -1.18169e-1, 1.06867
                };
                float3 lms = mul(LIN_2_LMS_MAT, In);
                lms *= balance;
                float3 Out = mul(LMS_2_LIN_MAT, lms);
                return Out;
            }

        //-----------高斯模糊----------------//
        struct v2fGaussian {
            float4 pos : SV_POSITION;
            half2 uv[5]: TEXCOORD0;
        };

        v2fGaussian vertBlurVertical(appdata_img v) {
            v2fGaussian o;
            o.pos = UnityObjectToClipPos(v.vertex);

            half2 uv = v.texcoord;

            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;
        }

        v2fGaussian vertBlurHorizontal(appdata_img v) {
            v2fGaussian o;
            o.pos = UnityObjectToClipPos(v.vertex);

            half2 uv = v.texcoord;

            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;
        }

        fixed4 fragBlur(v2fGaussian i) : SV_Target {
            float weight[3] = {0.4026, 0.2442, 0.0545};         
            fixed3 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 fixed4(sum, 1.0);
        }
        ///--------混合亮部图像和原图像-----------
        ///pos和uv,这里的uv是四维xy:_MainTex zw:_Bloom
        struct v2fBloom {
            float4 pos : SV_POSITION; 
            half4 uv : TEXCOORD0;
        };
        //顶点着色器
        v2fBloom vertBloom(appdata_img v) {
            v2fBloom o;     
            o.pos = UnityObjectToClipPos (v.vertex);
            o.uv.xy = v.texcoord;       
            o.uv.zw = v.texcoord;  //zw是_Bloom,即模糊后的较亮区域的纹理坐标
            //平台差异化处理
            #if UNITY_UV_STARTS_AT_TOP          
            if (_MainTex_TexelSize.y < 0.0)
                o.uv.w = 1.0 - o.uv.w;
            #endif                      
            return o; 
        }

        fixed4 fragBloom(v2fBloom i) : SV_Target {
            fixed4 TexCol = tex2D(_MainTex, i.uv.xy);
            fixed4 BlurCol = tex2D(_Bloom, i.uv.zw)*_BloomPow;
            fixed4 Result = TexCol + BlurCol;

            //对比度调整
		    fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
		    Result.rgb = lerp(avgColor, Result.rgb, _Contrast);

			//饱和度调整
			fixed luminance = 0.2125 * TexCol.r + 0.7154 * TexCol.g + 0.0721 * TexCol.b;
			fixed3 luminanceColor = fixed3(luminance, luminance, luminance); 
            Result.rgb = lerp(luminanceColor, Result.rgb, _Saturation);

			//亮度调整
			Result.rgb = Result.rgb * _Brightness; 

            //白平衡
            Result.rgb = WhiteBalance(Result.rgb, _Temperature, _Tint);

            return Result;
        } 
        ENDCG

        //关闭ZTest ,剔除,深度写入      
        ZTest Always Cull Off ZWrite Off

        Pass {  
            CGPROGRAM  
            #pragma vertex vertExtractBright  
            #pragma fragment fragExtractBright  

            ENDCG  
        }
        //use pass 的名字会转换成大写字母,使用时要用大写
        //usepass in GAUSSIAN_BLUR_VERTICAL
        //usepass in GAUSSIAN_BLUR_HORIZONTAL
        Pass {
            NAME "GAUSSIAN_BLUR_VERTICAL"

            CGPROGRAM

            #pragma vertex vertBlurVertical  
            #pragma fragment fragBlur

            ENDCG  
        }

        Pass {  
            NAME "GAUSSIAN_BLUR_HORIZONTAL"

            CGPROGRAM  

            #pragma vertex vertBlurHorizontal  
            #pragma fragment fragBlur

            ENDCG
        }

        Pass {  
            CGPROGRAM  
            #pragma vertex vertBloom  
            #pragma fragment fragBloom  

            ENDCG  
        }


    }
    FallBack Off
}

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

public class SimpleBloom : BloomPostEffectsBase
{

    public Shader GaussianShader;
    private Material GaussianMat = null;
    // Blur iterations - larger number means more blur.
    [Range(0,4)]
    public int iterations = 1;
    //控制渲染纹理的大小
    [Range(1,8)]
    public int downSample = 2;
    [Range(0.0f, 4.0f)]
    public float luminanceThreshold = 0.6f;
    [Range(0.2f, 3.0f)]
    public float blurSpread = 0.6f;
    [Range(0.0f, 3.0f)]
    public float BloomPower = 1f;

    [Range(0.0f, 3.0f)]
    public float Contrast = 1f;

    [Range(0.0f, 2.0f)]
    public float Saturation = 1f;

    [Range(0.0f, 3.0f)]
    public float Brightness = 1f;

    public float Temperature = 1f;
    public float Tint = 1f;
    public Material material
    {
        get
        {
            GaussianMat = CheckShaderAndCreateMaterial(GaussianShader, GaussianMat);
            return GaussianMat;
        }
    }
    protected void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material != null) {
            //设置亮度阙值
            material.SetFloat("_LuminanceThreshold", luminanceThreshold);
            //定义长宽高
            int rtW = source.width / downSample;
            int rtH = source.height / downSample;
            //定义buffer0缓冲区的大小,设置buffer0的过滤设置,并存储buffer0
            RenderTexture buffer0 = RenderTexture.GetTemporary(rtW,rtH,0);
            buffer0.filterMode = FilterMode.Bilinear;
            Graphics.Blit(source, buffer0, material, 0);
            //for循环,iteration次数
            for (int i = 0; i < iterations; i++)
            {
                ///for:
                ///设置blurSize
                ///新定义RenderTexture buffer1
                ///Render the vertical pass
                ///release buffer0
                ///buffer1赋值给buffer0
                ///re-define buffer1
                ///Render the horizontal pass
                ///释放buffer0
                ///buffer1赋值给buffer0
                material.SetFloat("_BlurSize",1.0f + blurSpread*i);
                RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
                Graphics.Blit(buffer0,buffer1,material,1);
                RenderTexture.ReleaseTemporary(buffer0);
                buffer0 = buffer1;
                buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);
                Graphics.Blit(buffer0, buffer1, material, 2);
                RenderTexture.ReleaseTemporary(buffer0);
                buffer0 = buffer1;
            }
            //mat中将buffer0赋予给_Bloom
            material.SetTexture("_Bloom",buffer0);
            //发光强度
            material.SetFloat("_BloomPow",BloomPower);

            //对比度
            material.SetFloat("_Contrast",Contrast);
            //饱和度
            material.SetFloat("_Saturation",Saturation);
            //亮度
            material.SetFloat("_Brightness",Brightness);
            //
            material.SetFloat("_Temperature",Temperature);
            material.SetFloat("_Tint",Tint);
            //渲染图像到des上
            Graphics.Blit(source,destination,material,3);
            //释放buffer0
            RenderTexture.ReleaseTemporary(buffer0);
        }
        else
        {
            Graphics.Blit(source,destination);
        }
    }
}
using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
public class BloomPostEffectsBase : MonoBehaviour
{
	/// <summary>
	/// 用指定shader生成一个材质
	/// </summary>
	/// <param name="shader"></param>
	/// <param name="material"></param>
	/// <returns></returns>
	protected Material CheckShaderAndCreateMaterial(Shader shader, Material material)
	{
		if (shader == null) return null;
		if (shader.isSupported && material && material.shader == shader) return material;

		if (!shader.isSupported)
		{
			return null;
		}
		else
		{
			material = new Material(shader);
			material.hideFlags = HideFlags.DontSave;
			if (material)return material;
			else return null;
		}
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃斋的和尚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值