#T#PoiMatcapProperties
// First Matcap
[HideInInspector] m_start_matcap ("Matcap 0--{reference_property:_MatcapEnable}", Float) = 0
[HideInInspector][ThryToggle(POI_MATCAP0)]_MatcapEnable ("Enable Matcap", Float) = 0
[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2)] _MatcapUVMode ("UV Mode", Int) = 1
_MatcapColor ("Color--{reference_property:_MatcapColorThemeIndex}", Color) = (1, 1, 1, 1)
[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _MatcapColorThemeIndex ("", Int) = 0
[TextureNoSO]_Matcap ("Matcap", 2D) = "white" { }
_MatcapBorder ("Border", Range(0, .5)) = 0.43
_MatcapMask ("Mask--{reference_properties:[_MatcapMaskPan, _MatcapMaskUV, _MatcapMaskInvert]}", 2D) = "white" { }
[HideInInspector][Vector2]_MatcapMaskPan ("Panning", Vector) = (0, 0, 0, 0)
[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7)] _MatcapMaskUV ("UV", Int) = 0
[HideInInspector][ToggleUI]_MatcapMaskInvert ("Invert", Float) = 0
_MatcapEmissionStrength ("Emission Strength", Range(0, 20)) = 0
_MatcapIntensity ("Intensity", Range(0, 5)) = 1
_MatcapLightMask ("Hide in Shadow", Range(0, 1)) = 0
_MatcapReplace ("Replace Blend", Range(0, 1)) = 1
_MatcapMultiply ("Multiply Blend", Range(0, 1)) = 0
_MatcapAdd ("Add Blend", Range(0, 1)) = 0
_MatcapMixed ("Mixed Blend", Range(0, 1)) = 0
_MatcapAddToLight ("Add To Light", Range(0, 1)) = 0
_MatcapAlphaOverride ("Override Alpha", Range(0, 1)) = 0
[Enum(Vertex, 0, Pixel, 1)] _MatcapNormal ("Normal to use", Int) = 1
[ThryToggle(POI_MATCAP0_CUSTOM_NORMAL, true)] _Matcap0CustomNormal ("<size=13><b>  Custom Normal</b></size>", Float) = 0
[Normal]_Matcap0NormalMap ("Normal Map--{reference_properties:[_Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale], condition_showS:(_Matcap0CustomNormal==1)}", 2D) = "bump" { }
[HideInInspector][Vector2]_Matcap0NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7)] _Matcap0NormalMapUV ("UV", Int) = 0
[HideInInspector]_Matcap0NormalMapScale ("Intensity", Range(0, 10)) = 1
[ThryToggleUI(true)] _MatcapHueShiftEnabled ("<size=13><b>  Hue Shift</b></size>", Float) = 0
_MatcapHueShiftSpeed ("Shift Speed--{condition_showS:(_MatcapHueShiftEnabled==1)}", Float) = 0
_MatcapHueShift ("Hue Shift--{condition_showS:(_MatcapHueShiftEnabled==1)}", Range(0, 1)) = 0
[ThryToggleUI(true)] _MatcapTPSDepthEnabled ("<size=13><b>  TPS Depth Mask Enabled</b></size>", Float) = 0
_MatcapTPSMaskStrength ("TPS Mask Strength--{condition_showS:(_MatcapTPSDepthEnabled==1)}", Range(0, 1)) = 1
[HideInInspector] m_end_matcap ("Matcap--{condition_showS:(_MatcapHueShiftEnabled==1)}", Float) = 0

// Second Matcap
[HideInInspector] m_start_Matcap2 ("Matcap 1--{reference_property:_Matcap2Enable}", Float) = 0
[HideInInspector][ThryToggle(COLOR_GRADING_HDR_3D)]_Matcap2Enable ("Enable Matcap 2", Float) = 0
[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2)] _Matcap2UVMode ("UV Mode", Int) = 1
_Matcap2Color ("Color--{reference_property:_Matcap2ColorThemeIndex}", Color) = (1, 1, 1, 1)
[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Matcap2ColorThemeIndex ("", Int) = 0
[TextureNoSO]_Matcap2 ("Matcap", 2D) = "white" { }
_Matcap2Border ("Border", Range(0, .5)) = 0.43
_Matcap2Mask ("Mask--{reference_properties:[_Matcap2MaskPan, _Matcap2MaskUV, _Matcap2MaskInvert]}", 2D) = "white" { }
[HideInInspector][Vector2]_Matcap2MaskPan ("Panning", Vector) = (0, 0, 0, 0)
[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7)] _Matcap2MaskUV ("UV", Int) = 0
[HideInInspector][ToggleUI]_Matcap2MaskInvert ("Invert", Float) = 0
_Matcap2EmissionStrength ("Emission Strength", Range(0, 20)) = 0
_Matcap2Intensity ("Intensity", Range(0, 5)) = 1
_Matcap2LightMask ("Hide in Shadow", Range(0, 1)) = 0
_Matcap2Replace ("Replace Blend", Range(0, 1)) = 0
_Matcap2Multiply ("Multiply Blend", Range(0, 1)) = 0
_Matcap2Add ("Add Blend", Range(0, 1)) = 0
_Matcap2Mixed ("Mixed Blend", Range(0, 1)) = 0
_Matcap2AddToLight ("Add To Light", Range(0, 1)) = 0
_Matcap2AlphaOverride ("Override Alpha", Range(0, 1)) = 0
[Enum(Vertex, 0, Pixel, 1)] _Matcap2Normal ("Normal to use", Int) = 1
[ThryToggle(POI_MATCAP1_CUSTOM_NORMAL, true)] _Matcap1CustomNormal ("<size=13><b>  Custom Normal</b></size>", Float) = 0
[ThryToggle()]_Matcap1CustomNormal ("Custom Normal", Float) = 0
[Normal]_Matcap1NormalMap ("Normal Map--{reference_properties:[_Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale], condition_showS:(_Matcap1CustomNormal==1)}", 2D) = "bump" { }
[HideInInspector][Vector2]_Matcap1NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7)] _Matcap1NormalMapUV ("UV", Int) = 0
[HideInInspector]_Matcap1NormalMapScale ("Intensity", Range(0, 10)) = 1
[ThryToggleUI(true)] _Matcap2HueShiftEnabled ("<size=13><b>  Hue Shift</b></size>", Float) = 0
_Matcap2HueShiftSpeed ("Shift Speed--{condition_showS:(_Matcap2HueShiftEnabled==1)}", Float) = 0
_Matcap2HueShift ("Hue Shift--{condition_showS:(_Matcap2HueShiftEnabled==1)}", Range(0, 1)) = 0
[ThryToggleUI(true)] _Matcap2TPSDepthEnabled ("<size=13><b>  TPS Depth Mask Enabled</b></size>", Float) = 0
_Matcap2TPSMaskStrength ("TPS Mask Strength--{condition_showS:(_Matcap2TPSDepthEnabled==1)}", Range(0, 1)) = 1
[HideInInspector] m_end_Matcap2 ("Matcap 2--{condition_showS:(_Matcap2HueShiftEnabled==1)}", Float) = 0

#T#PoiMatcapKeywords
#pragma shader_feature COLOR_GRADING_HDR_3D
#pragma shader_feature_local POI_MATCAP0
#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL

#T#PoiMatcapVariables
#ifdef POI_MATCAP0
	#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
		Texture2D _Matcap;
		float4 _Matcap_ST;
		float2 _MatcapPan;
		float _MatcapUV;
	#endif
	#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
		Texture2D _MatcapMask;
		float4 _MatcapMask_ST;
		float2 _MatcapMaskPan;
		float _MatcapMaskUV;
	#endif
	#ifdef POI_MATCAP0_CUSTOM_NORMAL
		#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap0NormalMap;
		#endif
		float4 _Matcap0NormalMap_ST;
		float2 _Matcap0NormalMapPan;
		float _Matcap0NormalMapUV;
		float _Matcap0NormalMapScale;
	#endif
	float _MatcapUVMode;
	float _MatcapMaskInvert;
	float _MatcapBorder;
	float4 _MatcapColor;
	float _MatcapColorThemeIndex;
	float _MatcapIntensity;
	float _MatcapReplace;
	float _MatcapMultiply;
	float _MatcapAdd;
	float _MatcapAddToLight;
	float _MatcapMixed;
	float _MatcapAlphaOverride;
	float _MatcapEnable;
	float _MatcapLightMask;
	float _MatcapEmissionStrength;
	float _MatcapNormal;
	float _MatcapHueShiftEnabled;
	float _MatcapHueShiftSpeed;
	float _MatcapHueShift;
	float _MatcapTPSDepthEnabled;
	float _MatcapTPSMaskStrength;
#endif

#ifdef COLOR_GRADING_HDR_3D
	#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
		Texture2D _Matcap2;
		float4 _Matcap2_ST;
		float2 _Matcap2Pan;
		float _Matcap2UV;
	#endif
	#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
		Texture2D _Matcap2Mask;
		float4 _Matcap2Mask_ST;
		float2 _Matcap2MaskPan;
		float _Matcap2MaskUV;
	#endif
	#ifdef POI_MATCAP1_CUSTOM_NORMAL
		#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap1NormalMap;
		#endif
		float4 _Matcap1NormalMap_ST;
		float2 _Matcap1NormalMapPan;
		float _Matcap1NormalMapUV;
		float _Matcap1NormalMapScale;
	#endif
	float _Matcap2UVMode;
	float _Matcap2MaskInvert;
	float _Matcap2Border;
	float4 _Matcap2Color;
	float _Matcap2ColorThemeIndex;
	float _Matcap2Intensity;
	float _Matcap2Replace;
	float _Matcap2Multiply;
	float _Matcap2Add;
	float _Matcap2AddToLight;
	float _Matcap2Mixed;
	float _Matcap2AlphaOverride;
	float _Matcap2Enable;
	float _Matcap2LightMask;
	float _Matcap2EmissionStrength;
	float _Matcap2Normal;
	float _Matcap2HueShiftEnabled;
	float _Matcap2HueShiftSpeed;
	float _Matcap2HueShift;
	float _Matcap2TPSDepthEnabled;
	float _Matcap2TPSMaskStrength;
#endif

#T#PoiMatcapFunctions
void blendMatcap(inout PoiLight poiLight, inout PoiFragData poiFragData, float add, float lightAdd, float multiply, float replace, float mixed, float4 matcapColor, float matcapMask, float emissionStrength, float matcapLightMask
#ifdef POI_BLACKLIGHT
	, uint blackLightMaskIndex
#endif
)
{
	if (matcapLightMask)
	{
		matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
	}
	#ifdef POI_BLACKLIGHT
		if (blackLightMaskIndex != 4)
		{
			matcapMask *= blackLightMask[blackLightMaskIndex];
		}
	#endif
	
	poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
	poiFragData.baseColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
	poiFragData.baseColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
	poiLight.finalLightAdd += matcapColor.rgb * lightAdd * matcapMask * matcapColor.a;
	poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * matcapColor.rgb, mixed * matcapMask * matcapColor.a);
	poiFragData.emission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
}

#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D)
	void applyMatcap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiMods poiMods)
	{
		float4 matcap = 0;
		float matcapMask = 0;
		float4 matcap2 = 0;
		float matcap2Mask = 0;
		float2 matcapUV = 0;


		// Matcap 1
		#ifdef POI_MATCAP0
			float3 normal0 = poiMesh.normals[_MatcapNormal];
			#ifdef POI_MATCAP0_CUSTOM_NORMAL
				#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
					normal0 = calculateNormal(poiMesh.normals[_MatcapNormal], poiMesh, _Matcap0NormalMap, _Matcap0NormalMap_ST, _Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale);
				#endif
			#endif

			switch(_MatcapUVMode)
			{
				// Normal / UTS
				case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal0, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * _MatcapBorder + 0.5;
						break;
				}
				// Top Pinch
				case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal0), dot(worldViewUp, normal0)) * _MatcapBorder + 0.5;
						break;
				}
				// Custom Double Sided
				case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal0);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * _MatcapBorder + 0.5;
						break;
				}
			}
			if (IsInMirror())
			{
				matcapUV.x = 1 - matcapUV.x;
			}

			#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
				matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
			#else
				matcap = float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
			#endif

			matcap.rgb *= _MatcapIntensity;
			#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
				matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan);
			#else
				matcapMask = 1;
			#endif

			if (_MatcapMaskInvert)
			{
				matcapMask = 1 - matcapMask;
			}

			#ifdef TPS_Penetrator
				if (_MatcapTPSDepthEnabled)
				{
					matcapMask = lerp(0, matcapMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _MatcapTPSMaskStrength);
				}
			#endif
			
			poiFragData.alpha *= lerp(1, matcap.a, matcapMask * _MatcapAlphaOverride);

			//UNITY_BRANCH
			if (_MatcapHueShiftEnabled)
			{
				matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
			}
			
			blendMatcap(poiLight, poiFragData, _MatcapAdd, _MatcapAddToLight, _MatcapMultiply, _MatcapReplace, _MatcapMixed, matcap, matcapMask, _MatcapEmissionStrength, _MatcapLightMask
			#ifdef POI_BLACKLIGHT
				, _BlackLightMaskMatcap
			#endif
			);
		#endif
		
		// Matcap 2
		#ifdef COLOR_GRADING_HDR_3D

			float3 normal1 = poiMesh.normals[_Matcap2Normal];
			#ifdef POI_MATCAP1_CUSTOM_NORMAL
				#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
					normal1 = calculateNormal(poiMesh.normals[_Matcap2Normal], poiMesh, _Matcap1NormalMap, _Matcap1NormalMap_ST, _Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale);
				#endif
			#endif

			matcapUV = 0;

			switch(_Matcap2UVMode)
			{
				// Normal / UTS
				case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal1, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * _Matcap2Border + 0.5;
						break;
				}
				// Top Pinch
				case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal1), dot(worldViewUp, normal1)) * _Matcap2Border + 0.5;
						break;
				}
				// Custom Double Sided
				case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal1);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * _Matcap2Border + 0.5;
						break;
				}
			}
			if (IsInMirror())
			{
				matcapUV.x = 1 - matcapUV.x;
			}

			#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
				matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap2)) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
			#else
				matcap2 = float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
			#endif
			matcap2.rgb *= _Matcap2Intensity;
			#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
				matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan);
			#else
				matcap2Mask = 1;
			#endif
			if (_Matcap2MaskInvert)
			{
				matcap2Mask = 1 - matcap2Mask;
			}

			#ifdef TPS_Penetrator
				if (_Matcap2TPSDepthEnabled)
				{
					matcap2Mask = lerp(matcap2Mask, 1, TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor) * _Matcap2TPSMaskStrength);
				}
			#endif

			poiFragData.alpha *= lerp(1, matcap2.a, matcap2Mask * _Matcap2AlphaOverride);
			
			//UNITY_BRANCH
			if (_Matcap2HueShiftEnabled)
			{
				matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
			}
			
			blendMatcap(poiLight, poiFragData, _Matcap2Add, _Matcap2AddToLight, _Matcap2Multiply, _Matcap2Replace, _Matcap2Mixed, matcap2, matcap2Mask, _Matcap2EmissionStrength, _Matcap2LightMask
			#ifdef POI_BLACKLIGHT
				, _BlackLightMaskMatcap2
			#endif
			);
		#endif
	}
#endif

#T#PoiMatcapFunctionCalls
#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D)
	applyMatcap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
#endif
