一、效果
二、参数设置
Brightness:亮度
Saturation:饱和度
Contrast:对比度
成员属性:
Is Loop Change:是否循环变化(渐变)
Duration:渐变的时间
CurValue:当前值
MaxValue:最大值,只有当Is Loop Change选中时才有效
MinValue:最小值,只有当Is Loop Change选中时才有效
三、脚本
C#脚本:(注意引用DoTween)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
[System.Serializable]
public struct ColorAdjustShaderData
{
public bool IsLoopChange;
public float Duration;
public float CurValue;
public float MaxValue;
public float MinValue;
}
public class ColorAdjust : MonoBehaviour
{
public ColorAdjustShaderData Brightness; //调整亮度
public ColorAdjustShaderData Saturation;//调整饱和度
public ColorAdjustShaderData Contrast; //调整对比度
private MaskableGraphic maskableGraphic;
void Awake()
{
maskableGraphic = GetComponent<MaskableGraphic>();
if (maskableGraphic)
{
Image image = maskableGraphic as Image;
if (image)
{
image.material = new Material(Shader.Find("Custom/ColorAdjustEffect"));
}
}
if (Brightness.IsLoopChange)
{
DOTween.To(x => Brightness.CurValue = x, Brightness.MinValue, Brightness.MaxValue, Brightness.Duration).SetLoops(-1,LoopType.Yoyo);
}
if (Saturation.IsLoopChange)
{
DOTween.To(x => Saturation.CurValue = x, Saturation.MinValue, Saturation.MaxValue, Saturation.Duration).SetLoops(-1, LoopType.Yoyo);
}
if (Contrast.IsLoopChange)
{
DOTween.To(x => Contrast.CurValue = x, Contrast.MinValue, Contrast.MaxValue, Contrast.Duration).SetLoops(-1, LoopType.Yoyo);
}
}
void Update()
{
if (Brightness.IsLoopChange)
{
maskableGraphic.material.SetFloat("_Brightness", Brightness.CurValue);
}
if (Saturation.IsLoopChange)
{
maskableGraphic.material.SetFloat("_Saturation", Brightness.CurValue);
}
if (Contrast.IsLoopChange)
{
maskableGraphic.material.SetFloat("_Contrast", Brightness.CurValue);
}
}
void Start()
{
SetShader();
}
public void SetShader()
{
maskableGraphic.material.SetFloat("_Brightness", Brightness.CurValue);
maskableGraphic.material.SetFloat("_Saturation", Saturation.CurValue);
maskableGraphic.material.SetFloat("_Contrast", Contrast.CurValue);
}
}
Shader脚本(本人并不会Shader,这是网上一位兄弟写的)
Shader "Custom/ColorAdjustEffect"
{
Properties
{
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Brightness("Brightness", Float) = 1 //调整亮度
_Saturation("Saturation", Float) = 1 //调整饱和度
_Contrast("Contrast", Float) = 1 //调整对比度
}
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
sampler2D _MainTex;
half _Brightness;
half _Saturation;
half _Contrast;
//vert和frag函数
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
struct appdata_t
{
float4 vertex : POSITION;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
//从vertex shader传入pixel shader的参数
struct v2f
{
float4 pos : SV_POSITION; //顶点位置
half2 uv : TEXCOORD0; //UV坐标
half4 color : COLOR;
};
//vertex shader
v2f vert(appdata_t v)
{
v2f o;
//从自身空间转向投影空间
o.pos = UnityObjectToClipPos(v.vertex);
o.color = v.color;
//uv坐标赋值给output
o.uv = v.texcoord;
return o;
}
//fragment shader
fixed4 frag(v2f i) : COLOR
{
//从_MainTex中根据uv坐标进行采样
fixed4 renderTex = tex2D(_MainTex, i.uv)*i.color;
//brigtness亮度直接乘以一个系数,也就是RGB整体缩放,调整亮度
fixed3 finalColor = renderTex * _Brightness;
//saturation饱和度:首先根据公式计算同等亮度情况下饱和度最低的值:
fixed gray = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
fixed3 grayColor = fixed3(gray, gray, gray);
//根据Saturation在饱和度最低的图像和原图之间差值
finalColor = lerp(grayColor, finalColor, _Saturation);
//contrast对比度:首先计算对比度最低的值
fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
//根据Contrast在对比度最低的图像和原图之间差值
finalColor = lerp(avgColor, finalColor, _Contrast);
//返回结果,alpha通道不变
return fixed4(finalColor, renderTex.a);
}
ENDCG
}
}
//防止shader失效的保障措施
FallBack Off
}