后处理 - 亮度,饱和度,对比度

效果

 

c#代码

using UnityEngine;

public class MyBrightnessSaturationAndContrast : MonoBehaviour
{

    public Shader m_Shader;
    public Material m_Material;

    [Range(0.0f, 3.0f)]
    public float m_brightness = 1.0f;

    [Range(0.0f, 3.0f)]
    public float m_saturation = 1.0f;

    [Range(0.0f, 3.0f)]
    public float m_contrast = 1.0f;

    void Start()
    {
        if (false == SystemInfo.supportsImageEffects)
        {
            Debug.LogWarning("This platform does not support image effects or render textures.");
            this.enabled = false;
            return;
        }

        if (null == m_Material)
        {
            if (null != m_Shader && m_Shader.isSupported)
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
        }
        else if (m_Material.shader != m_Shader)
        {
            if (m_Shader.isSupported) //优先shader
            {
                m_Material = new Material(m_Shader);
                m_Material.hideFlags = HideFlags.DontSave;
            }
        }
    }

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (null != m_Material)
        {
            m_Material.SetFloat("_Brightness", m_brightness);
            m_Material.SetFloat("_Saturation", m_saturation);
            m_Material.SetFloat("_Contrast", m_contrast);

            Graphics.Blit(src, dest, m_Material);
        }
        else
        {
            Graphics.Blit(src, dest);
        }
    }

}

 

shader

Shader "My/PostEff/BrightnessSaturationAndContrast"
{
	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white" {} //主贴图
		_Brightness("Brightness", Float) = 1 //亮度
		_Saturation("Saturation", Float) = 1 //饱和度
		_Contrast("Contrast", Float) = 1 //对比度
	}

	SubShader
	{
		Tags { "RenderType" = "Opaque" }
		LOD 100

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

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float4 _MainTex_ST;

			half _Brightness;
			half _Saturation;
			half _Contrast;

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			v2f vert(appdata v) //顶点着色器
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target //片段着色器(逐像素)
			{
				fixed4 renderTex = tex2D(_MainTex, i.uv);

				//亮度计算直接叠加
				fixed3 finalColor = renderTex.rgb * _Brightness;

				//饱和度和灰度有关,先计算最低灰度系数下的图像,随后对原始的图像进行插值操作
				fixed3 gray = fixed3(0.2125, 0.7154, 0.0721);
				//点积得到最低灰度值,构成最低灰度图像
				fixed minGray = dot(gray, col.rgb); //即: gray.x * renderTex.r + gray.y * renderTex.g + gray.z * renderTex.b
				fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
				fixed3 luminanceColor = fixed3(minGray, minGray, minGray); //饱和度为0的颜色值
				//对灰度图像和原始图像插值操作以得到最终系数的显示图像
				finalColor = lerp(luminanceColor, finalColor, _Saturation);

				//对比度效果类似,先计算最低对比度图像,即(0.5,0.5,0.5),随后插值操作
				fixed3 minContrast = fixed3(0.5, 0.5, 0.5); //对比度为0的颜色值
				finalColor = lerp(minContrast, finalColor, _Contrast);

				return fixed4(finalColor, renderTex.a);
			}
			ENDCG
		}
	}

	Fallback Off
}

 

参考

《shader入门精要》12.2

 Unity Shader 屏幕后效果——颜色校正 - 汐夜 - 博客园 (cnblogs.com)

posted @ 2024-03-27 22:32  yanghui01  阅读(6)  评论(0编辑  收藏  举报