调整亮度、饱和度和对比度
屏幕后处理效果:指在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列的操作,实现各种屏幕特效。
因此首先需要得到渲染后的屏幕图像,Unity提供了一个方便的接口——OnRenderImage。但在进行屏幕后处理之前,我们需要检测一切条件是否满足,例如当前平台是否支持渲染纹理和屏幕特效,是否支持当前使用的UnityShader等。
因此先创建一个基类用于检测条件:
protected void CheckResources()
{
bool isSupported = CheckSupport();
if (isSupported == false)
{
NotSupported();
}
}
protected bool CheckSupport()
{
if (SystemInfo.supportsImageEffects == false)
{
Debug.LogWarning("This platform does not support image effects.");
return false;
}
return true;
}
protected void NotSupported()
{
enabled = false;
}
protected void Start()
{
CheckResources();
}
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;
}
}
然后创建BrightnessSaturationAndContrast脚本继承上面的类,再挂载到摄像机上:
public Shader briSatConShader;
private Material briSatConMaterial;
public Material material
{
get
{
briSatConMaterial = CheckShaderAndCreateMaterial(briSatConShader, briSatConMaterial);
return briSatConMaterial;
}
}
[Range(0.0f,3.0f)]
public float brightness = 1.0f;
[Range(0.0f, 3.0f)]
public float saturation = 1.0f;
[Range(0.0f, 3.0f)]
public float contrast = 1.0f;
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (material != null)
{
material.SetFloat("_Brightness", brightness);
material.SetFloat("_Saturation", saturation);
material.SetFloat("_Contrast", contrast);
Graphics.Blit(source, destination, material);
}
else
{
Graphics.Blit(source, destination);
}
}
最后编写我们需要的shader:
Shader "myShader/BrightnessSaturationAndContrast"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Brightness("Brightness", Float) = 1
_Saturation("Saturation", Float) = 1
_Contrast("Contrast", Float) = 1
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
half _Brightness;
half _Saturation;
half _Contrast;
struct v2f {
float4 pos : SV_POSITION;
half2 uv: TEXCOORD0;
};
v2f vert(appdata_img v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag(v2f i) :SV_Target{
fixed4 renderTex = tex2D(_MainTex, i.uv);//原屏幕图像的采样结果
fixed3 finalColor = renderTex.rgb * _Brightness; //原颜色乘以亮度系数
//计算像素对应的亮度值
fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
fixed3 luminanceColor = fixed3(luminance, luminance, luminance);
finalColor = lerp(luminanceColor, finalColor, _Saturation);
fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
finalColor = lerp(avgColor, finalColor, _Contrast);
return fixed4(finalColor, 1);
}
ENDCG
}
}
Fallback Off
}
对比调整效果图: