屏幕后期处理-调整屏幕亮度、饱和度、对比度
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视图中查看效果。