Unity Shader:校色

2023-10-23  本文已影响0人  全新的饭

原文

Unity Shader学习:校色(Color Grading)

用法

制作Mat(选择Shader为ColorGrading),将代码组件ColorGradingHelper拖到主相机上。
可调整其提供的参数。

用途

全屏变灰
全屏变黑(白)
调整显示色调

代码

ColorGradingHelper.cs

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;


/// <summary>
/// 挂在主相机上,用于调整校色相关的参数
/// </summary>
public class ColorGradingHelper : MonoBehaviour
{
    [SerializeField]
    private Material _mat;
    [SerializeField, Range(0, 1f)]
    private float _hue = 0;
    [SerializeField, Range(0, 3f)]
    private float _saturation = 1;
    [SerializeField, Range(0, 3f)]
    private float _value = 1;
    [SerializeField, Range(0, 1f)]
    private float _grayAmount = 0f;
    [SerializeField]
    private bool _invertColor = false;
    [SerializeField]
    private bool _useRampTex = false;

    private void Start()
    {
        Init();
    }

    private void Update()
    {
        MyUpdate();
    }

    private void OnDestroy()
    {
        MyDestroy();
    }

    private void Init()
    {

    }

    private void MyUpdate()
    {

    }

    private void MyDestroy()
    {

    }

    // 将参数传递到mat(shader)中,将源RT经过mat处理后,再输出到目标RT
    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (_mat == null)
        {
            Graphics.Blit(src, dest);
            return;
        }

        _mat.SetFloat("_Hue", _hue);
        _mat.SetFloat("_Saturation", _saturation);
        _mat.SetFloat("_Value", _value);
        _mat.SetFloat("_GrayAmount", _grayAmount);

        if (_invertColor)
        {
            _mat.EnableKeyword("INVERT_COLOR");
        }
        else
        {
            _mat.DisableKeyword("INVERT_COLOR");
        }

        if (_useRampTex)
        {
            _mat.EnableKeyword("USE_RAMP_TEXTURE");
        }
        else
        {
            _mat.DisableKeyword("USE_RAMP_TEXTURE");
        }

        Graphics.Blit(src, dest, _mat);

    }
}

ColorGrading.shader

Shader "Fan/ColorGrading"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _Hue ("Hue", Range(0,1)) = 0
        _Saturation ("Saturation", Range(0,3)) = 1
        _Value ("Value", Range(0,3)) = 1
        _GrayAmount ("Gray Amount", Range(0,1)) = 0
        _RampTex ("Ramp Texture", 2D) = "white" {}
    }
    SubShader
    {

        // Tags { "RenderType"="Opaque" }
        // LOD 100
        Pass
        {
            ZTest Always Cull Off ZWrite Off

            Tags { "RenderType"="Opaque" }
            Name "ColorGrading"

            CGPROGRAM

            #pragma vertex vert_img
            #pragma fragment frag

            #pragma shader_feature __ INVERT_COLOR USE_RAMP_TEXTURE

            sampler2D _MainTex;
            float _Hue;
            float _Saturation;
            float _Value;
            float _GrayAmount;
            sampler2D _RampTex;

            #include "UnityCG.cginc"
            float3 rgb2hsv(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 hsv2rgb(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, clamp(p - k.xxx, 0.0, 1.0), c.y);
            }

            fixed4 frag(v2f_img i) : SV_TARGET
            {
                fixed4 renderTex = tex2D(_MainTex, i.uv);

                //Gray
                fixed lumiance = 0.3 * renderTex.r + 0.59 * renderTex.g + 0.11 * renderTex.b;
                //fixed lumiance = 0.2125 * renderTex.r + 0.07154 * renderTex.g + 0.721 * renderTex.b;
                fixed3 finalColor = renderTex.rgb;
                #ifdef USE_RAMP_TEXTURE
                    //fixed2 rampUV = fixed2(lumiance, lumiance);
                    //finalColor = tex2D(_RampTex, rampUV);
                    fixed2 rampUV;
                    rampUV.x = finalColor.r;
                    rampUV.y = 0;
                    finalColor = tex2D(_RampTex, rampUV) * renderTex.rgb;
                #else
                    fixed3 lumianceColor = fixed3(lumiance, lumiance, lumiance);
                    finalColor = lerp(renderTex.rgb, lumianceColor, _GrayAmount);
                #endif
                //HSV
                float3 hsv = rgb2hsv(finalColor);
                hsv.x += _Hue;
                hsv.y *= _Saturation;
                hsv.z *= _Value;
                finalColor = hsv2rgb(hsv);

                #ifdef INVERT_COLOR
                    finalColor.r = 1.0 - finalColor.r;
                    finalColor.g = 1.0 - finalColor.g;
                    finalColor.b = 1.0 - finalColor.b;
                #endif

                return fixed4(finalColor, renderTex.a);
            }
            ENDCG
        }

    }
    FallBack "Diffuse"
}
上一篇 下一篇

猜你喜欢

热点阅读