Shader "Bloodborne/Colorize"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "black" {}
        _Hue ("Hue", Range(0, 360)) = 0
        _Saturation("Saturation", Range(0, 100)) = 100
        _Value("Value", Range(0, 100)) = 100
        _Contrast ("Contrast", Float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            float _Hue;
            float _Saturation;
            float _Value;
            float _Contrast;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            float3 Hue(float3 color, float hue)
            {
                float angle = radians(hue);
                float3 k = float3(0.57735, 0.57735, 0.57735);
                float cosAngle = cos(angle);
                return color * cosAngle + cross(k, color) * sin(angle) + k * dot(k, color) * (1 - cosAngle);
            }

            float3 Saturation(float3 color, float saturation)
            {
                float3 intensity = dot(color, float3(0.299, 0.587, 0.114));
                return lerp(intensity, color, saturation);
            }

            float3 Contrast(float3 color, float contrast)
            {
                float midpoint = pow(0.2, 2.2);
                return (color - midpoint) * contrast + midpoint;
            }

            float4 HSV(float4 color)
            {
                color.rgb = Hue(color.rgb, _Hue);
                color.rgb = Saturation(color.rgb, (_Saturation / 100));
                color.rgb = color.rgb * (_Value / 100);
                color.rgb = Contrast(color.rgb, _Contrast);
                return color;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float4 color = tex2D(_MainTex, i.uv);
                float4 hsbColor = HSV(color);
                return hsbColor;
            }
            ENDCG
        }
    }
    Fallback off
}
