屏幕后处理
在渲染完整个场景得到屏幕图像后,再对这个图像进行处理,实现各种特效。在渲染后的屏幕图像,即抓屏,OnRenderImage函数接口可以对该图像进行操作返回最终的图像,利用Graphics.Blit()函数处理图片。默认情况下,OnRenderImage在透明和不透明的pass执行完后被调用。大致的流程:向摄像机添加脚本--》实现OnRenderImage函数--》调用Graphics.Blit()使用特定的shader处理图像--》将最终的图像返回屏幕。注意:使用之前需要检查条件是否满足这样的操作,平台是否支持该操作。
饱和度、亮度、对比度
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]//在编辑模式下能够执行该程序
[RequireComponent(typeof(Camera))]
public class RenderDemo : MonoBehaviour
{
//是否支持屏幕特效
private bool isEnabled;
private void Check()
{
//SystemInfo 基本能够获取运行平台的所有属性信息。
if (SystemInfo.supportsImageEffects==false|| SystemInfo.supportsRenderTextures==false)
{
isEnabled = false;
Debug.LogWarning("不支持屏幕特效或纹理渲染");
}
else
{
isEnabled = true;
}
}
private void Start()
{
Check();
}
protected Material CheckShaderAndCreateMaterial(Shader shader,Material material)
{
if (null ==shader)
{
return null;
}
if (shader.isSupported && material && material.shader==shader)
{
return material;
}
if (!shader.isSupported)
{
return null;
}
else
{
material=new Material(shader);
//hideFlags用于控制对象的破坏,保存和在检查器中的可见性。
//不保存到场景中,加载新场景是不会被销毁。
material.hideFlags = HideFlags.DontSave;
if (material)
{
return material;
}
else
{
return null;
}
}
}
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;
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (material != null) {
material.SetFloat("_Brightness", brightness);
material.SetFloat("_Saturation", saturation);
material.SetFloat("_Contrast", contrast);
Graphics.Blit(src, dest, material);
} else {
Graphics.Blit(src, dest);
}
}
}
Shader "Unlit/First"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Birghtness("Birghtness",Float)=1.0
_Saturation("Saturation",Float)=1.0
_Contrast("Contrast",Float)=1.0
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _Birghtness;
fixed _Saturation;
fixed _Contrast;
struct v2f
{
float4 pos : SV_POSITION;
float2 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 * _Birghtness;
//饱和度
//通过固定的系数算的luminance 亮度
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);
//对比度 像创建对比度为0的颜色值 也就是各个分量为0.5
fixed3 avgColor=fixed3(0.5,0.5,0.5);
finalColor=lerp(avgColor,finalColor,_Contrast);