《unityshader入门精要》学习笔记-屏幕后期处理-调整屏幕亮度、饱和度、对比度

时间:2021-11-05 10:22:58

 

屏幕后期处理-调整屏幕亮度、饱和度、对比度

《unityshader入门精要》学习笔记-屏幕后期处理-调整屏幕亮度、饱和度、对比度

1、场景创建

1.1 hierarchy视图包含:一个main camera、一个directional light、一个sprite(一个texture type为Sprite(2D and UI))

1.2 project 视图中新建:

一个C#脚本命名为PostEffectsBase,用于建立基本的屏幕后期处理系统。代码如下:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]   

public class PostEffectsBase : MonoBehaviour {

    // Use this for initialization
    void Start () {
        CheckResources ();
    }

    //检查资源是否符合标准
    protected void CheckResources()
    {
        bool isSupported = CheckSupport();
        
        if (isSupported == false)
            NotSupported ();
    }
    
    
    protected bool CheckSupport()
     {
         if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false) {
               Debug.LogWarning("This platform does not support image effects or render textures");
               return false;
            }
         return true;
     }

    protected void NotSupported()
    {
        enabled = false;
    }

    //指定一个shader来创建一个用于处理渲染纹理的材质
    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;
        }
    }
}

 

再创建一个C#脚本命名为BrightnessSaturationAndContrast,继承上面的基类,提供调整亮度、饱和度、对比度的参数。将此脚本t添加到main camera上。

using UnityEngine;
using System.Collections;

public class BrightnessSaturationAndContrast : PostEffectsBase {

    public Shader briSatConShader;
    public Material briSatConMaterial;
    public Material material{
        get {
            //调用基类中的方法可创建与shader对应的材质球
            briSatConMaterial = CheckShaderAndCreateMaterial(briSatConShader,briSatConMaterial);
            return briSatConMaterial;
        }
    }

    [Range(0,3.0f)]
    public float brightness =1.0f;
    [Range(0,3.0f)]
    public float saturation =1.0f;
    [Range(0,3.0f)]
    public float contrast =1.0f;

    //定义OnRenderImage函数来进行特效处理,当前渲染的图像存储在第一个参数对应的源纹理中,
    //通过函数中的一系列操作后第二个参数的纹理显示到屏幕上。
    void OnRenderImage(RenderTexture src,RenderTexture  dest)
    {
        if (material != null) {
            material.SetFloat ("_Brightness", brightness);
            material.SetFloat ("_Saturation", saturation);
            material.SetFloat ("_Contrast", contrast);
           //Graphics.Blit使用特定的unity shader来对当前图像进行处理,再把返回的渲染纹理显示到屏幕
            Graphics.Blit (src, dest, material);  //参数src传递给shader中名为_Maintex的纹理属性
        } else
            Graphics.Blit (src, dest);                //图像直接显示到屏幕上不做任何处理
    }
}

 

创建一个shader命名为BriSatAndCon,一个材质球命名为Render。将Render的shader为BriSatAndCon

Shader "LT/BriSatAndCon" {
    Properties {
        _MainTex ("Base (RGB)"2D) = "white" {}
        _Brightness ("Brightness"Float) = 1        // 亮度系数  值由C#脚本传递
        _Saturation ("Saturation"Float) = 1        // 饱和度系数  值由C#脚本传递
        _Contrast ("Contrast"Float) = 1            // 对比度系数  值由C#脚本传递
        
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        
        pass{
        ZTest Always 
        Cull off
        Zwrite off
        
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        sampler2D _MainTex;
        float _Brightness;
        float _Saturation;
        float _Contrast;

        struct v2f {
            half2 uv : TEXCOORD0;
            float4 pos : POSITION;
        };

        v2f vert (appdata_img v) {
            v2f o;
            o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
            o.uv = v.vertex;
            return o;
        }
        
        fixed4 frag(v2f i): SV_Target
        {
            fixed4 renderTex = tex2D(_MainTex,i.uv);
            
            //apply brightnees亮度=原颜色*亮度系数
            fixed3 finalColor = renderTex.rgb * _Brightness;
             
            //apply saturation饱和度 ,计算该像素对应的亮度值:对每一个颜色分量*待定系数相加。
            fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.721 * renderTex.b;
            //创建一个饱和度为0的颜色值
            fixed3 luminaceColor = luminance;
            finalColor = lerp(luminaceColor,finalColor,_Saturation);
            
            //apply Contrast对比度
            fixed3 avgColor = fixed3(0.5,0.5,0.5);                //创建一个对比度为0的颜色
            finalColor = lerp(avgColor,finalColor,_Contrast);
            return fixed4(finalColor,renderTex.a);
        }
        ENDCG
        }
    } 
    FallBack off
}

将此shader手动拖拽到main camera上BrightnessSaturationAndContrast中的briSatConShader。调节其他参数在game视图中查看效果。