#T#PoiDepthRimLightProperties
//ifex _EnableDepthRimLighting==0
[HideInInspector] m_start_depthRimLightOptions ("Depth Rim Lighting--{reference_property:_EnableDepthRimLighting,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/depth-rim-lighting},hover:Documentation}}", 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

[HideInInspector] s_start_FixedRimShapeControl ("Shape Control--{persistent_expand:true,default_expand:true}", Float) = 1
_DepthRimWidth ("Width", Range(0, 1)) = .2
_DepthRimSharpness ("Depth", Range(0, 1)) = .2
[ToggleUI]_DepthRimHideInShadow ("Hide In Shadow", Float) = 0
[HideInInspector] s_end_FixedRimShapeControl ("Shape Control", Float) = 0


[HideInInspector] s_start_FixedRimColor ("Color--{persistent_expand:true,default_expand:true}", Float) = 1
_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
[HideInInspector] s_end_FixedRimColor ("Color", Float) = 0
[HideInInspector] s_start_FixedRimBlending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
_DepthRimReplace ("Replace", Range(0, 1)) = 0
_DepthRimAdd ("Add", Range(0, 1)) = 0
_DepthRimMultiply ("Multiply", Range(0, 1)) = 0
_DepthRimAdditiveLighting ("Unlit Add", Range(0, 1)) = 0
[HideInInspector] s_end_FixedRimBlending ("Blending", Float) = 0
[HideInInspector] m_end_depthRimLightOptions ("Rim Lighting", Float) = 0
//endex

#T#PoiRimLightKeywords
//ifex _EnableDepthRimLighting==0
#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
//endex

#T#PoiDepthRimLightVariables
//ifex _EnableDepthRimLighting==0
#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
//endex

#T#PoiDepthRimLightFunction
//ifex _EnableDepthRimLighting==0
#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.posScreenSpace.xy * perspectiveDivide;
		
        if(!DepthTextureExists()) return;
        float z = SampleScreenDepth(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 - SampleScreenDepth(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;
                    [unroll(9)]
                    for (int i = 0; i < 9; i++)
                    {
                        float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
                        depthDiff = max(depthDiff, z - SampleScreenDepth(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;

        #ifdef POI_PASS_BASE
            poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
        #endif
        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
//endex

#T#PoiDepthRimLightFunctionCall
//ifex _EnableDepthRimLighting==0
#ifdef _POI_DEPTH_RIMLIGHT
    if (!IsInMirror())
    {
        ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
    }
#endif
//endex

