屏幕后处理——亮度.饱和度.对比度
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了屏幕后处理——亮度.饱和度.对比度相关的知识,希望对你有一定的参考价值。
先上图:
亮度调整
饱和度调整
对比度
代码主要分成3部分主程
1.PostEffectsBase 在进行屏幕处理之前,我们需要检查一系列条件是否满足,例如当前平台是否支持渲染文理和屏幕特效,是否支持当前使用的unity Shader等。为此,我们创建了一个用于屏幕后处理效果的基类,在实现
各种屏幕特效时,我们只需要继承自该基类,再实现派生类中不同的操作即可。
PostEffectsBase 代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; //在编辑器状态下可执行该脚本来查看效果 [ExecuteInEditMode] //屏幕后处理特效一般需要绑定在摄像机上 [RequireComponent(typeof(Camera))] public class PostEffectsBase : MonoBehaviour { void Start () { CheckResources(); } protected void CheckResources() { bool isSupported = CheckSupport(); //如果显卡检测 返回false if (isSupported == false) { //NotSupported()方法,即不显示 NotSupported(); } } //检查显卡是否支持 protected bool CheckSupport() { //如果显卡不支持图像后期处理 if (SystemInfo.supportsImageEffects == false) { //返回false return false; } //如果支持图像后处理,返回true return true; } //图像不显示 protected void NotSupported() { enabled = false; } //CheckShaderAndCreateMaterial函数接受两个参数,第一个参数指定了改特效需要使用的Shader //第二个参数则是用于后期处理的材质。该函数首先检查Shader的可用性,检查通过后就返回一个使 //用了该shader的材质,否则返回null. protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) { //如果shader为空 if (shader == null) { return null; } //shader.isSupported:能在终端用户的图形卡上运行这个着色器&& 并且存在material 他的shader是我们输入的shader if (shader.isSupported && material && material.shader == shader) { return material; } if (!shader.isSupported) { return null; } //上面都不满足的话,重新创建新的材质球 else { material = new Material(shader); //hideFlags:控制对象销毁的位掩码 //HideFlags.DontSave对象不会保存到场景中。加载新场景时不会被破坏。 material.hideFlags = HideFlags.DontSave; return material; } } }
2.调整屏幕的亮度、饱和度、对比度
代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class BrightnessSaturationAndContrast : PostEffectsBase { //亮度 对比度 饱和度 参数 //亮度 [Range(0.0f, 3.0f)] public float brightness = 1.0f; //饱和度 [Range(0.0f, 3f)] public float saturation = 1.0f; //对比度 [Range(0.0f, 3f)] public float contrast = 1.0f; //可以拖入shader public Shader m_shader; //自定义生成material private Material m_material; //根据基类写的方法生成material public Material material { get { m_material = CheckShaderAndCreateMaterial(m_shader, m_material); return m_material; } } //定义OnRenderImage函数来进特效处理 //当OnRenderImage函数被调用的时候,他会检查材质球是否可用。如果可用,就把参数传递给材质, //再调用Graphics.Blit进行处理;否则,直接把原图像显示到屏幕上,不做任何处理。 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); } } }
3.shader的代码如下:
Shader "Unlit/NewUnlitShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _brightness("brightness",float) = 1 _saturation("saturation",float) = 1 _contrast("contrast",float) =1 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { ZTest Always Cull Off ZWrite Off 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; //饱和度 fixed Luminance = 0.215 * 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,renderTex.a); } ENDCG } } }
知识点:
public static void Blit(Texture source, RenderTexture dest); public static void Blit(Texture source, RenderTexture dest, Material mat, int pass = -1); public static void Blit(Texture source, Material mat, int pass = -1);
src: 原纹理 ,当前屏幕的文理,也是传给材质球的_MainTex的图
dest :目标文理,经过shader返回的图 。如果他的值为null就会直接将结果显示在屏幕上
met:材质球
pass:默认为-1,表示将依次调用shader内的pass。否则只会调用给定索引的Pass
以上是关于屏幕后处理——亮度.饱和度.对比度的主要内容,如果未能解决你的问题,请参考以下文章
Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)
Unity Shader 颜色处理(亮度,饱和度 ,对比度)