#ifndef URP_FUNCTION
#define URP_FUNCTION
#define FTNN_DEGREE_TO_RADIAN_FACTOR 0.01745329f
#define FTNN_EPSILON (1e-3)
half _Weight;
half _HueShift;
half _Sat;
half _Val;

//#define USE_FAST_HSV_COMPUTED 1

#ifdef USE_FAST_HSV_COMPUTED
half _preComputedValue[36];
#endif

#ifdef USE_FAST_HSV_COMPUTED
inline float3 hsv_shift_rgb_fast(float3 RGB, uint startIndex)
{
	float3 RESULT = float3(RGB);

	RESULT.x = _preComputedValue[startIndex] * RGB.x + _preComputedValue[startIndex + 1] * RGB.y + _preComputedValue[startIndex + 2] * RGB.z;
	RESULT.y = _preComputedValue[startIndex + 3] * RGB.x + _preComputedValue[startIndex + 4] * RGB.y + _preComputedValue[startIndex + 5] * RGB.z;
	RESULT.z = _preComputedValue[startIndex + 6] * RGB.x + _preComputedValue[startIndex + 7] * RGB.y + _preComputedValue[startIndex + 8] * RGB.z;

	return RESULT;
}

half3 replace_color_with_hsv_fast(half3 col, uint startIndex, uint startIndex1)
{
	col = half3(hsv_shift_rgb_fast(col, startIndex));
	col.r *= half(_preComputedValue[startIndex1]);
	col.g *= half(_preComputedValue[startIndex1 + 1]);
	col.b *= half(_preComputedValue[startIndex1 + 2]);
	return col;
}
#endif	

inline float3 hsv_shift_rgb(float3 RGB, float3 shift)
{
	float3 RESULT = float3(RGB);
	float VSU = shift.z*shift.y*cos(shift.x*FTNN_DEGREE_TO_RADIAN_FACTOR);
	float VSW = shift.z*shift.y*sin(shift.x*FTNN_DEGREE_TO_RADIAN_FACTOR);

	RESULT.x = (.299*shift.z+.701*VSU+.168*VSW)*RGB.x
			+ (.587*shift.z-.587*VSU+.330*VSW)*RGB.y
			+ (.114*shift.z-.114*VSU-.497*VSW)*RGB.z;

	RESULT.y = (.299*shift.z-.299*VSU-.328*VSW)*RGB.x
			+ (.587*shift.z+.413*VSU+.035*VSW)*RGB.y
			+ (.114*shift.z-.114*VSU+.292*VSW)*RGB.z;

	RESULT.z = (.299*shift.z-.3*VSU+1.25*VSW)*RGB.x
			+ (.587*shift.z-.588*VSU-1.05*VSW)*RGB.y
			+ (.114*shift.z+.886*VSU-.203*VSW)*RGB.z;
	
	return (RESULT);
}
inline half3 replace_color_with_hsv (half3 col, half hsvRef, float hueShift, float satMultiplier, float valMultiplier, half3 additiveColor) 
{             
float3 shift = float3(hueShift * hsvRef, 
					1 - (1 - satMultiplier) * hsvRef, 
					1 - (0.5 - valMultiplier) * hsvRef  
					);
col = half3(hsv_shift_rgb(col, shift));   
col.r *= saturate(1 - hsvRef * (1 - additiveColor.r * 2) );
col.g *= saturate(1 - hsvRef * (1 - additiveColor.g * 2) );
col.b *= saturate(1 - hsvRef * (1 - additiveColor.b * 2) );
return col;
}

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);
} 

Light MainLight(half3 positionWS)
{
Light light;
#ifdef _MAIN_LIGHT_SHADOWS
	#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
		float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
	#else
			float4 shadowCoord = float4(0, 0, 0, 0);
	#endif
#if _UNIQUE_SHADOW
			float4 uniqueShadowCoord = TransformWorldToUniqueShadowCoord(positionWS);
			light = GetMainLight();
			light.shadowAttenuation = MainLightRealtimeShadow(shadowCoord, uniqueShadowCoord);
#else
			light = GetMainLight(shadowCoord);
#endif
#else
		light = GetMainLight();
#endif
return light;
}

struct ShadowInputData
{
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
	float3 positionWS;
#endif 

#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
	float4 shadowCoord;
#endif
};

Light MainLight(ShadowInputData input)
{
    Light light;
	
#ifdef _MAIN_LIGHT_SHADOWS
	
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
		float4 shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
		float4 shadowCoord = TransformWorldToShadowCoord(input.positionWS);
#else
		float4 shadowCoord = float4(0, 0, 0, 0);
#endif
	light = GetMainLight(shadowCoord);
#else
    light = GetMainLight();
#endif
    return light;
}

#endif