#T#PoiDepthRimLightProperties
// Rim Lighting
[HideInInspector] m_start_depthRimLightOptions ("Depth Rim Lighting--{reference_property:_EnableDepthRimLighting}", Float) = 0
[HideInInspector][ThryToggle(_POI_DEPTH_RIMLIGHT)]_EnableDepthRimLighting ("", Float) = 0
[Enum(vertex, 0, pixel, 1)] _DepthRimNormalToUse ("Normal To Use", Int) = 1
[ThryWideEnum(Two Samples, 0, Ten Samples, 1)] _DepthRimType ("Rim Type", Int) = 0
_DepthRimWidth ("Width", Range(0, 1)) = .2
_DepthRimSharpness ("Depth", Range(0, 1)) = .2
[ToggleUI]_DepthRimHideInShadow ("Hide In Shadow", Float) = 0

[Space][ThryHeaderLabel(Color and Blending, 13)]
_DepthRimMixBaseColor ("Use Base Color", Range(0, 1)) = 0
_DepthRimMixLightColor ("Light Color Mix", Range(0, 1)) = 0
_DepthRimColor ("Rim Color--{reference_property:_DepthRimColorThemeIndex}", Color) = (1, 1, 1, 1)
_DepthRimBrightness ("Color Brightness", Range(0, 10)) = 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)] _DepthRimColorThemeIndex ("", Int) = 0
_DepthRimEmission ("Emission", Range(0, 20)) = 0
_DepthRimReplace ("Replace", Range(0, 1)) = 0
_DepthRimAdd ("Add", Range(0, 1)) = 0
_DepthRimMultiply ("Multiply", Range(0, 1)) = 0
_DepthRimAdditiveLighting ("Add to Light", Range(0, 1)) = 0
[HideInInspector] m_end_depthRimLightOptions ("Rim Lighting", Float) = 0

#T#PoiRimLightKeywords
#pragma shader_feature_local _POI_DEPTH_RIMLIGHT

#T#PoiDepthRimLightVariables
#ifdef _POI_DEPTH_RIMLIGHT
	float _DepthRimNormalToUse;
	float _DepthRimWidth;
	float _DepthRimSharpness;
	float _DepthRimHideInShadow;
	float4 _DepthRimColor;
	float _DepthRimColorThemeIndex;
	float _DepthRimMixBaseColor;
	float _DepthRimEmission;
	float _DepthRimReplace;
	float _DepthRimAdd;
	float _DepthRimMultiply;
	float _DepthRimAdditiveLighting;
	float _DepthRimMixLightColor;
	float _DepthRimType;
	float _DepthRimBrightness;

	static float2 sobelSamplePoints[9] = {
		float2(-1, 1), float2(0, 1), float2(1, 1),
		float2(-1, 0), float2(0, 0), float2(1, 01),
		float2(-1, -1), float2(0, -1), float2(1, -1)
	};

	static float sobelXMatrix[9] = {
		1, 0, -1,
		2, 0, -2,
		1, 0, -1
	};
	static float sobelYMatrix[9] = {
		1, 2, 1,
		0, 0, 0,
		- 1, -2, -1
	};
#endif

/*
Texture2D ;
float4 _ST;
float2 Pan;
float UV;
*/

#T#PoiDepthRimLightFunction
#ifdef _POI_DEPTH_RIMLIGHT
	
	float PositivePow(float base, float power)
	{
		return pow(max(abs(base), Epsilon), power);
	}

	float GetScaleWithHight()
	{
		return _ScreenParams.y / 1080;
	}

	float GetSSRimScale(float z)
	{
		float w = (1.0 / (PositivePow(z + saturate(UNITY_MATRIX_P._m00), 1.5) + 0.75)) * GetScaleWithHight();
		w *= lerp(1, UNITY_MATRIX_P._m00, 0.60 * saturate(0.25 * z * z));
		return w < 0.01 ? 0 : w;
	}

	void ApplyDepthRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiLight poiLight, in PoiMods poiMods)
	{
		float rim = 0;
		float perspectiveDivide = 1.0f / poiCam.clipPos.w;
		float4 direction = poiCam.worldDirection * perspectiveDivide;
		float2 screenPos = poiCam.grabPos.xy * perspectiveDivide;
		float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
		
		#if UNITY_REVERSED_Z
			if (z == 0) return;
		#else
			if (z == 1) return;
		#endif
		
		float depth = CorrectedLinearEyeDepth(z, direction.w);


		switch(_DepthRimType)
		{
			case 0:
				{
					float3 viewPos = UnityObjectToViewPos(poiMesh.localPos);
					float3 viewDir = normalize(viewPos);
					
					float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, poiMesh.normals[_DepthRimNormalToUse]);
					float3 viewCrossNorm = cross(viewDir, viewNorm);
					float2 N_View = normalize(float2(-viewCrossNorm.y, viewCrossNorm.x));

					float3 viewLight = mul((float3x3)UNITY_MATRIX_V, poiLight.direction);
					float3 viewCrossLight = cross(viewDir, viewLight);
					float2 L_View = normalize(float2(-viewCrossLight.y, viewCrossLight.x));
					
					//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
					float scale = _DepthRimWidth * GetSSRimScale(depth);
					float2 ssUV1 = clamp(screenPos + N_View * .1 * scale, 0, _ScreenParams.xy - 1);
					float depthDiff = z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1) ;

					rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
					rim *= lerp(1, (dot(L_View, N_View) > 0), _DepthRimHideInShadow);
				}
				break;
			case 1:
				{
					//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
					float scale = _DepthRimWidth * GetSSRimScale(depth);
					float depthDiff = 0;
					for (int i = 0; i < 9; i++)
					{
						float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
						depthDiff = max(depthDiff, z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1));
					}
					rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
					rim *= lerp(1, lerp(poiLight.vertexNDotL > 0, poiLight.nDotL > 0, _DepthRimNormalToUse), _DepthRimHideInShadow);
				}
				break;
		}

		float3 rimColor = poiThemeColor(poiMods, _DepthRimColor.rgb, _DepthRimColorThemeIndex).rgb * lerp(1, poiLight.directColor, _DepthRimMixLightColor) * lerp(1, poiFragData.baseColor, _DepthRimMixBaseColor) * _DepthRimBrightness;

		poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
		poiFragData.emission += rim * rimColor * _DepthRimEmission;
		poiFragData.baseColor = lerp(poiFragData.baseColor, rimColor, rim * _DepthRimReplace);
		poiFragData.baseColor += rim * rimColor * _DepthRimAdd;
		poiFragData.baseColor *= lerp(1, rimColor, rim * _DepthRimMultiply);
	}
#endif

#T#PoiDepthRimLightFunctionCall
#ifdef _POI_DEPTH_RIMLIGHT
	if (!IsInMirror())
	{
		ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
	}
#endif

