Unity自定义后处理——校色

Unity自定义校色后处理

  大家好,我是阿赵。
  之前介绍了一些后处理的做法,包括了PostProcessing和CommandBuffer。其实如果我们只是实现一些比较单一的全屏效果,也没必要搞那么复杂,直接在OnRenderImage里面写Graphics.Blit就可以了。接下来的几篇文章都会介绍这种简单直接的后处理实现方式。
  这一期先来讲最简单的校色。我还是拿这个模型作为原始画面。
Unity自定义后处理——校色_第1张图片

一、饱和度

  实现饱和度的调整,原理其实是先取一个灰度颜色,然后再用这个灰度的颜色和当前的颜色做lerp插值。

		//饱和度
float lumin = dot(col, float3(0.22f, 0.707f, 0.071f));
col = lerp(lumin, col, _Saturation);

  其中 float3(0.22f, 0.707f, 0.071f)这个灰度可以根据你自己的需要去调整。然后声明一个_Saturation变量,用于控制饱和度的插值。
Unity自定义后处理——校色_第2张图片

_Saturation默认是1,即是画面的原始颜色。当我们增大_Saturation,让_Saturation大于1时,可以看到画面的饱和度变高了。
Unity自定义后处理——校色_第3张图片

当我们减少_Saturation值,让它接近0时,画面就变成了灰度。
Unity自定义后处理——校色_第4张图片

原则上_Saturation应该是大于等于0的,但如果我们把_Saturation的可调范围包含负数时,负数的效果就会变成反色了。

二、对比度

  对比度的原理和饱和度有点类似,但它不再是那灰度作为0插值时的颜色,而是用一个中间色

		//对比度
		float3 midPoint = float3(0.5, 0.5, 0.5);
	col.rgb = lerp(midPoint, col.rgb, _Contrast);
  其中的_Contrast变量是控制对比度的值。

Unity自定义后处理——校色_第5张图片当_Contrast值变大时,对比度就变大了。
Unity自定义后处理——校色_第6张图片

由于后处理是作用在整个画面的,所以当我们调整_Contrast时,连着背景的颜色一起,整个画面的对比度就变低。
Unity自定义后处理——校色_第7张图片

和饱和度一样,假如我们把_Contrast的取值范围包含负数,就可以做这种反相的效果。

三、色调

  要调整颜色的色调,我们要转换一下,把RGB颜色转换成HSV颜色模型。然后再对其中的Hue进行调整,调整完之后,再调整回到RGB颜色。
RGB和HSV的转换

float3 HSVToRGB(float3 c)
{
	float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
	float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
	return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}


float3 RGBToHSV(float3 c)
{
	float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
	float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
	float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
	float d = q.x - min(q.w, q.y);
	float e = 1.0e-10;
	return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

调整色调

//色调
float3 hsvCol = RGBToHSV(col.rgb);
hsvCol.x = hsvCol.x + _HueShift;
col.rgb = HSVToRGB(hsvCol);

其中_HueShift变量是控制色调的变化
Unity自定义后处理——校色_第8张图片
Unity自定义后处理——校色_第9张图片

调整_HueShift,可以看到画面的色调在改变。

四、明度

  明度调整是最简单的了,直接RGB颜色乘以一个变量就行

//明度
col.rgb *= _Light;

Unity自定义后处理——校色_第10张图片

由于后处理针对的是整个画面,所以调整明度,会整个画面一起变化。
Unity自定义后处理——校色_第11张图片

用Photoshop时,我们很喜欢亮度和对比度一起调整,这里的各种效果都是可以互相配合使用的。亮度和对比度一起调整,就变成这种效果。
Unity自定义后处理——校色_第12张图片

五、完整代码

1、C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AdjustColor : MonoBehaviour
{
    private Material colorMat;
    [Range(-5, 5)]
    public float saturation = 1;
    [Range(-5, 5)]
    public float contrast = 1;
    [Range(0, 1)]
    public float hueShift = 0;
    [Range(0, 5)]
    public float lightVal = 1;
    void Start()
    {
        

    }

    void Update()
    {
        
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        AjustColor(source, destination);        
    }

    private bool AjustColor(RenderTexture source, RenderTexture destination)
    {
        if (colorMat == null)
        {
            colorMat = new Material(Shader.Find("Hidden/AzhaoAjustColor"));
        }
        if (colorMat == null || colorMat.shader == null || colorMat.shader.isSupported == false)
        {
            return false;
        }
        colorMat.SetFloat("_Saturation", saturation);
        colorMat.SetFloat("_Contrast", contrast);
        colorMat.SetFloat("_HueShift", hueShift);
        colorMat.SetFloat("_Light", lightVal);

        Graphics.Blit(source, destination, colorMat, 0);
        return true;
    }
}

2、Shader

Shader "Hidden/AzhaoAjustColor"
{
	CGINCLUDE
#include "UnityCG.cginc"

	sampler2D _MainTex;
	float4 _MainTex_TexelSize;
	float _Saturation;
	float _Contrast;
	float _HueShift;
	float _Light;
	float3 HSVToRGB(float3 c)
	{
		float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
		float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
		return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
	}


	float3 RGBToHSV(float3 c)
	{
		float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
		float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
		float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
		float d = q.x - min(q.w, q.y);
		float e = 1.0e-10;
		return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
	}

	half4 fragColorAjust(v2f_img i) : SV_Target
	{
		half4 col = tex2D(_MainTex, i.uv);
		//饱和度
		float lumin = dot(col, float3(0.22f, 0.707f, 0.071f));
		col = lerp(lumin, col, _Saturation);

		//对比度
		float3 midPoint = float3(0.5, 0.5, 0.5);
		col.rgb = lerp(midPoint, col.rgb, _Contrast);

		//色调
		float3 hsvCol = RGBToHSV(col.rgb);
		hsvCol.x = hsvCol.x + _HueShift;
		col.rgb = HSVToRGB(hsvCol);

		//明度
		col.rgb *= _Light;

		return col;
	}


	ENDCG
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_Saturation("Saturation",Range(-5,5)) = 1
		_Contrast("Contrast",Range(-5,5)) = 1
		_HueShift("HueShift",Range(0,1)) = 0
		_Light("Light",Range(0,5)) = 1
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always
		//0校色
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment fragColorAjust            

            
            ENDCG
        }
    }
}

你可能感兴趣的:(Unity引擎Shader效果,unity,游戏引擎,后处理,校色)