#T#PoiOutlineProperties
// Outline Vertex
[HideInInspector][ToggleUI]_EnableOutlines ("Enable Outlines", float) = 0
[Enum(Basic, 0, Tint, 1, Rim Light, 2, Directional, 3, DropShadow, 4)]_OutlineMode ("Mode", Int) = 0
_OutlineTintMix ("Tint Mix--{condition_show:{type:PROPERTY_BOOL,data:_OutlineMode==1}}", Range(0, 1)) = 0
_OutlineRimLightBlend ("Rim Light Blend--{condition_show:{type:PROPERTY_BOOL,data:_OutlineMode==2}}", Range(0, 1)) = 0
_OutlinePersonaDirection ("directional Offset XY--{condition_show:{type:PROPERTY_BOOL,data:_OutlineMode==3}}", Vector) = (1, 0, 0, 0)
_OutlineDropShadowOffset ("Drop Direction XY--{condition_show:{type:PROPERTY_BOOL,data:_OutlineMode==4}}", Vector) = (1, 0, 0, 0)
[ToggleUI]_OutlineFixedSize ("Fixed Size?", Float) = 0
_OutlinesMaxDistance ("Fixed Size Max Distance", Float) = 9999
[Enum(Off, 0, Normals, 1, Mask VC.r, 2)]_OutlineUseVertexColors ("Vertex Color", Float) = 0
[ToggleUI]_OutlineLit ("Enable Lighting", Float) = 1
_LineWidth ("Width", Float) = 0
_LineColor ("Color--{reference_property:_LineColorThemeIndex}", 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)] _LineColorThemeIndex ("", Int) = 0
_OutlineEmission ("Outline Emission", Float) = 0
_OutlineTexture ("Outline Texture--{reference_properties:[_OutlineTexturePan, _OutlineTextureUV]}", 2D) = "white" { }
[HideInInspector][Vector2]_OutlineTexturePan ("Outline Texture Pan", 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)] _OutlineTextureUV ("UV", Int) = 0
_OutlineMask ("Outline Mask--{reference_properties:[_OutlineMaskPan, _OutlineMaskUV]}", 2D) = "white" { }
[HideInInspector][Vector2]_OutlineMaskPan ("Panning", Vector) = (0, 0, 0, 0)
[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _OutlineMaskUV ("UV", Int) = 0
_OutlineShadowStrength ("Shadow Strength", Range(0, 1)) = 1

[ThryToggleUI(true)]_OutlineHueShift ("<size=13><b>  Hue Shift</b></size>", Float) = 0
_OutlineHueOffset ("Shift--{condition_showS:(_OutlineHueShift==1)}", Range(0, 1)) = 0
_OutlineHueOffsetSpeed ("Shift Speed--{condition_showS:(_OutlineHueShift==1)}", Float) = 0
[HideInInspector] m_start_outlineAdvanced ("Advanced", Float) = 0
[ToggleUI]_OutlineClipAtZeroWidth ("Clip 0 Width", Float) = 0
[ToggleUI]_OutlineOverrideAlpha ("Override Base Alpha", Float) = 0
_Offset_Z ("Cam Z Offset", Float) = 0
[Vector2]_OutlineFadeDistance ("Outline distance Fade", Vector) = (0, 0, 0, 0)
[Enum(UnityEngine.Rendering.CullMode)] _OutlineCull ("Cull", Float) = 1
[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineZTest ("ZTest", Float) = 4
_OutlineOffsetFactor ("Offset Factor", Float) = 0
_OutlineOffsetUnits ("Offset Units", Float) = 0
[HideInInspector] m_end_outlineAdvanced ("Advanced", Float) = 0

#T#PoiOutlineStencilProperties
// Outline Stencil
[HideInInspector] m_start_OutlineStencil ("Outline Stencil", Float) = 0
[IntRange] _OutlineStencilRef ("Stencil Reference Value", Range(0, 255)) = 0
[IntRange] _OutlineStencilReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255
[IntRange] _OutlineStencilWriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255
[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilPassOp ("Stencil Pass Op", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilFailOp ("Stencil Fail Op", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilZFailOp ("Stencil ZFail Op", Float) = 0
[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineStencilCompareFunction ("Stencil Compare Function", Float) = 8
[HideInInspector] m_end_OutlineStencil ("Outline Stencil", Float) = 0

#T#PoiOutlineVariables
#ifdef POI_PASS_OUTLINE
    // outline Vertex Options
    float _OutlineMode;
    float4 _OutlinePersonaDirection;
    float4 _OutlineDropShadowOffset;
    float _OutlineUseVertexColors;
    float _OutlineFixedSize;
    float _EnableOutlines;
    float _OutlinesMaxDistance;
    float _LineWidth;
    float _OutlineEmission;
    float4 _LineColor;
    float _OutlineOverrideAlpha;
    texture2D _OutlineTexture; //TODO make this dynamically not read for lock in
    float4 _OutlineTexture_ST;
    float2 _OutlineTexturePan;
    float _OutlineTextureUV;
    float4 _OutlineFadeDistance;
    float4 _OutlineGlobalPan;
    sampler2D _OutlineMask;
    float4 _OutlineMask_ST;
    float2 _OutlineMaskPan;
    float _OutlineMaskUV;
    float _OutlineRimLightBlend;
    float _OutlineLit;
    float _OutlineTintMix;
    half _OutlineHueOffset;
    half _OutlineHueShift;
    half _OutlineHueOffsetSpeed;
    float _OutlineShadowStrength;
    float _LineColorThemeIndex;
    float _Offset_Z;
    float _OutlineClipAtZeroWidth;
#endif

#T#OutlineVertexOffset
#ifdef POI_PASS_OUTLINE
    float outlineMask = 1;
    //TODO figure out why uvs can't be set dynamically
    outlineMask = poiMax(tex2Dlod(_OutlineMask, float4(poiUV(o.uv[0], _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0)).rgb);

    //UNITY_BRANCH
    if (_OutlineUseVertexColors == 2)
    {
        outlineMask *= v.color.r;
    }

    float3 outlineNormal = o.normal;
    //UNITY_BRANCH
    if (_OutlineUseVertexColors == 1)
    {
        //TODO normals appear to be transformed before entering the vertex shader and I'm not sure how to achieve the same results with vertex colors
        outlineNormal = UnityObjectToWorldNormal(v.color);
    }

    half offsetMultiplier = 1;
    half distanceOffset = 1;
    //UNITY_BRANCH
    if (_OutlineFixedSize)
    {
        distanceOffset *= min(distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz), _OutlinesMaxDistance);
    }
    
    float3 offset = outlineNormal * (_LineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
    
    //UNITY_BRANCH
    if (_OutlineMode == 2)
    {
        float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
        offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
        offset *= offsetMultiplier;
        offset *= distanceOffset;
    }
    else if (_OutlineMode == 3)
    {
        half3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
        offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
        
        offset *= offsetMultiplier;
        offset *= distanceOffset;
    }
    else if (_OutlineMode == 4)
    {
        offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
        offset *= distanceOffset;
    }

    localOffset += mul(unity_WorldToObject, offset);
    worldOffset += offset;
#endif

#T#OutlineFragmentFunction
#ifdef POI_PASS_OUTLINE
    void applyOutlineColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
    {
        clip(_EnableOutlines - 0.01);
        float OutlineMask = tex2D(_OutlineMask, TRANSFORM_TEX(poiMesh.uv[_OutlineMaskUV], _OutlineMask) + _Time.x * _OutlineMaskPan).r;
        if (_OutlineClipAtZeroWidth)
        {
            clip(OutlineMask * _LineWidth - 0.001);
        }
        float4 col = POI2D_SAMPLER_PAN(_OutlineTexture, _MainTex, poiUV(poiMesh.uv[_OutlineTextureUV], _OutlineTexture_ST), _OutlineTexturePan) * float4(poiThemeColor(poiMods, _LineColor.rgb, _LineColorThemeIndex), _LineColor.a);
        //UNITY_BRANCH
        if (_OutlineMode == 0)
        {
            poiFragData.baseColor = col;
        }
        //UNITY_BRANCH
        if (_OutlineMode == 1)
        {
            poiFragData.baseColor = lerp(float4(poiThemeColor(poiMods, _LineColor.rgb, _LineColorThemeIndex), _LineColor.a), poiFragData.baseColor, _OutlineTintMix) * col;
        }
        //UNITY_BRANCH
        if (_OutlineMode == 2)
        {
            poiFragData.baseColor = lerp(poiFragData.baseColor, poiLight.directColor, _OutlineRimLightBlend) * col;
        }

        if (_OutlineOverrideAlpha)
        {
            poiFragData.alpha = col.a;
        }
        else
        {
            poiFragData.alpha *= col.a;
        }

        // Hue shift
        //UNITY_BRANCH
        if (_OutlineHueShift)
        {
            poiFragData.baseColor = hueShift(poiFragData.baseColor, _OutlineHueOffset +_OutlineHueOffsetSpeed * _Time.x);
        }

        poiFragData.emission += poiFragData.baseColor * _OutlineEmission;
    }
#endif

#T#OutlineFragmentFunctionCall
#ifdef POI_PASS_OUTLINE
    applyOutlineColor(poiFragData, poiMesh, poiLight, poiMods);
#endif

#T#OutlineForceSmoothNormals
#ifdef POI_PASS_OUTLINE
    poiMesh.normals[1] = poiMesh.normals[0];
#endif