#T#lilFurProperties
// substantial parts copied from liltoon's fur shader implementation
// will be marked with a comment containing "start MIT liltoon" and "end MIT liltoon" respectively

// MIT License

// Copyright (c) 2020-2024 lilxyzw

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

//start MIT liltoon
[sRGBWarning] _FurLengthMask ("Length Mask--{shouldHaveSRGB:false}", 2D) = "white" {}
[Normal] _FurVectorTex ("Normal Map--{reference_properties:[_FurVectorScale]}", 2D) = "bump" {}
[HideInInspector]_FurVectorScale ("Normal Scale", Range(-10,10)) = 1
[sRGBWarning] _FurMask ("Alpha Mask--{shouldHaveSRGB:false}", 2D) = "white" {}
[sRGBWarning] _FurNoiseMask ("Noise--{shouldHaveSRGB:false}", 2D) = "white" {}
[Vector31] _FurVector ("Fur Vector|Length", Vector) = (0.0,0.0,1.0,0.02)
[ThryToggle()] _VertexColor2FurVector ("VertexColor -> Fur Vector", Int) = 0
_FurGravity ("Gravity", Range(0,1)) = 0.25
_FurRandomize ("Randomize", Float) = 0
_FurAO ("Ambient Occlusion", Range(0,1)) = 0
[ThryWideEnum(Shrink, 0, Subdivision, 1)] _FurMeshType ("Mesh Type", Int) = 0
[ThryIntRange] _FurLayerNum ("FurLayers--{condition_show:{type:PROPERTY_BOOL,data:_FurMeshType==0}}", Range(1, 6)) = 2
[ThryIntRange] _FurLayerNum ("FurLayers--{condition_show:{type:PROPERTY_BOOL,data:_FurMeshType==1}}", Range(1, 3)) = 2
_FurRootOffset ("Root Width", Range(-1,0)) = 0

// only used in two pass fur
//_FurCutoutLength ("sLength+ (Cutout)", Float) = 0.8

//_FurTouchStrength ("sTouchStrength", Range(0, 1)) = 0
//end MIT liltoon

#T#lilFurVertexOutVariable
//start MIT liltoon
float3 furVector : TEXCOORD13;
float furLayer : TEXCOORD14;
//end MIT liltoon

#T#lilFurKeywords
#pragma shader_feature_local LIL_FUR

#T#lilFurVariables
//start MIT liltoon
Texture2D _FurNoiseMask;
float4 _FurNoiseMask_ST;
Texture2D _FurMask;
float4 _FurMask_ST;
sampler2D _FurLengthMask;
float4 _FurLengthMask_ST;
sampler2D _FurVectorTex;
float4 _FurVectorTex_ST;
float _FurVectorScale;
float4 _FurVector;
int _VertexColor2FurVector;
float _FurGravity;
float _FurRandomize;
float _FurAO;
int _FurMeshType;
float _FurLayerNum;
float _FurRootOffset;

// only used in two pass fur
//float _FurCutoutLength;

//float _FurTouchStrength;
//end MIT liltoon

#T#lilFurVertexFunctionCalls
//start MIT liltoon
float3 bitangentOS = normalize(cross(v.normal, v.tangent.xyz)) * (v.tangent.w * length(v.normal));
float3x3 tbnOS = float3x3(v.tangent.xyz, bitangentOS, v.normal);
o.furVector = _FurVector.xyz + float3(0,0,0.001);
if(_VertexColor2FurVector) o.furVector = PoiBlendNormal(o.furVector, v.color.xyz);
#if defined(PROP_FURVECTORTEX) || !defined(OPTIMIZER_ENABLED)
    o.furVector = PoiBlendNormal(o.furVector, UnpackScaleNormal(tex2Dlod(_FurVectorTex, float4(o.uv[0] * _FurVectorTex_ST.xy + _FurVectorTex_ST.zw,0, 0)), _FurVectorScale));
#endif
o.furVector = mul(normalize(o.furVector), tbnOS);
o.furVector *= _FurVector.w;
#if defined(LIL_FUR_PRE)
    o.furVector *= _FurCutoutLength;
#endif
o.furVector = lilTransformDirOStoWS(o.furVector, false);
float furLength = length(o.furVector);
o.furVector.y -= _FurGravity * furLength;

// not implemented
// #if defined(LIL_FEATURE_FUR_COLLISION) && defined(LIL_BRP) && defined(VERTEXLIGHT_ON)
//     // Touch
//     float3 positionWS2 = o.positionWS + o.furVector;
//     float4 toLightX = unity_4LightPosX0 - positionWS2.x;
//     float4 toLightY = unity_4LightPosY0 - positionWS2.y;
//     float4 toLightZ = unity_4LightPosZ0 - positionWS2.z;
//     float4 lengthSq = toLightX * toLightX + 0.000001;
//     lengthSq += toLightY * toLightY;
//     lengthSq += toLightZ * toLightZ;
//     float4 atten = saturate(1.0 - lengthSq * unity_4LightAtten0 / 25.0) * _FurTouchStrength * furLength;
//     //float4 rangeToggle = abs(frac(sqrt(25.0 / unity_4LightAtten0) * 100.0) - 0.22);
//     float4 rangeToggle = abs(frac(sqrt(250000 / unity_4LightAtten0)) - 0.22);
//     o.furVector = rangeToggle[0] < 0.001 - unity_LightColor[0].r - unity_LightColor[0].g - unity_LightColor[0].b ? o.furVector - float3(toLightX[0], toLightY[0], toLightZ[0]) * rsqrt(lengthSq[0]) * atten[0] : o.furVector;
//     o.furVector = rangeToggle[1] < 0.001 - unity_LightColor[1].r - unity_LightColor[1].g - unity_LightColor[1].b ? o.furVector - float3(toLightX[1], toLightY[1], toLightZ[1]) * rsqrt(lengthSq[1]) * atten[1] : o.furVector;
//     o.furVector = rangeToggle[2] < 0.001 - unity_LightColor[2].r - unity_LightColor[2].g - unity_LightColor[2].b ? o.furVector - float3(toLightX[2], toLightY[2], toLightZ[2]) * rsqrt(lengthSq[2]) * atten[2] : o.furVector;
//     o.furVector = rangeToggle[3] < 0.001 - unity_LightColor[3].r - unity_LightColor[3].g - unity_LightColor[3].b ? o.furVector - float3(toLightX[3], toLightY[3], toLightZ[3]) * rsqrt(lengthSq[3]) * atten[3] : o.furVector;
// #endif
//end MIT liltoon

#T#lilFurGeometryFunctions
//start MIT liltoon
float  lilLerp3(float  a, float  b, float  c, float3 factor) { return a * factor.x + b * factor.y + c * factor.z; }
float2 lilLerp3(float2 a, float2 b, float2 c, float3 factor) { return a * factor.x + b * factor.y + c * factor.z; }
float3 lilLerp3(float3 a, float3 b, float3 c, float3 factor) { return a * factor.x + b * factor.y + c * factor.z; }
float4 lilLerp3(float4 a, float4 b, float4 c, float3 factor) { return a * factor.x + b * factor.y + c * factor.z; }
float  lilLerp3(float  a[3], float3 factor) { return lilLerp3(a[0], a[1], a[2], factor); }
float2 lilLerp3(float2 a[3], float3 factor) { return lilLerp3(a[0], a[1], a[2], factor); }
float3 lilLerp3(float3 a[3], float3 factor) { return lilLerp3(a[0], a[1], a[2], factor); }
float4 lilLerp3(float4 a[3], float3 factor) { return lilLerp3(a[0], a[1], a[2], factor); }

void AppendFur(inout TriangleStream<VertexOut> outStream, inout VertexOut output, VertexOut input[3], float3 furVectors[3], float3 factor)
{
    output.uv[0] = lilLerp3(input[0].uv[0], input[1].uv[0], input[2].uv[0], factor);
    output.uv[1] = lilLerp3(input[0].uv[1], input[1].uv[1], input[2].uv[1], factor);

    output.normal = lilLerp3(input[0].normal, input[1].normal, input[2].normal, factor);

    output.tangent = lilLerp3(input[0].tangent, input[1].tangent, input[2].tangent, factor);

    output.localPos = lilLerp3(input[0].localPos, input[1].localPos, input[2].localPos, factor);

    output.vertexColor = lilLerp3(input[0].vertexColor, input[1].vertexColor, input[2].vertexColor, factor);

    output.lightmapUV = lilLerp3(input[0].lightmapUV, input[1].lightmapUV, input[2].lightmapUV, factor);

    output.fogCoord = lilLerp3(input[0].fogCoord, input[1].fogCoord, input[2].fogCoord, factor);

    float3 positionWS = lilLerp3(input[0].worldPos, input[1].worldPos, input[2].worldPos, factor);
    output.worldPos = float4(positionWS,0);

    output.pos = UnityWorldToClipPos(positionWS);

    // not implemented
    // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
    //     float3 previousPositionWS = lilLerp3(input[0].previousPositionWS, input[1].previousPositionWS, input[2].previousPositionWS, factor);
    //     output.previousPositionCS = mul(LIL_MATRIX_PREV_VP, float4(previousPositionWS, 1.0));
    // #endif
    output.furLayer = 0;

    #if defined(LIL_FUR_PRE)
        #if defined(UNITY_REVERSED_Z)
            // DirectX
            output.positionCS.z -= 0.0000001;
        #else
            // OpenGL
            output.positionCS.z += 0.0000001;
        #endif
    #endif

    outStream.Append(output);

    float3 mixVector = lilLerp3(furVectors[0], furVectors[1], furVectors[2], factor);
    positionWS.xyz += mixVector;
    output.worldPos = float4(positionWS,0);
    output.pos = UnityWorldToClipPos(positionWS);

    // not implemented
    // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
    //     previousPositionWS.xyz += mixVector;
    //     output.previousPositionCS = mul(LIL_MATRIX_PREV_VP, float4(previousPositionWS, 1.0));
    // #endif

    output.furLayer = 1;

    #if defined(LIL_FUR_PRE)
        #if defined(UNITY_REVERSED_Z)
            // DirectX
            output.positionCS.z -= 0.000001;
        #else
            // OpenGL
            output.positionCS.z += 0.000001;
        #endif
    #endif
    outStream.Append(output);
}
//end MIT liltoon

#T#lilFurGeometryBeforeInit
//start MIT liltoon
//------------------------------------------------------------------------------------------------------------------------------
// Copy
#if defined(LIL_ONEPASS_FUR)
    VertexOut outputBase[3];
    PoiInitStruct(VertexOut, outputBase[0]);
    PoiInitStruct(VertexOut, outputBase[1]);
    PoiInitStruct(VertexOut, outputBase[2]);

    for(uint i = 0; i < 3; i++)
    {
        UNITY_TRANSFER_INSTANCE_ID(input[i], outputBase[i]);
        UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(input[i], outputBase[i]);

        outputBase[i].pos = UnityWorldToClipPos(input[i].worldPos);
        
        // not implemented
        // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
        //     outputBase[i].previousPositionCS = mul(LIL_MATRIX_PREV_VP, float4(input[i].previousPositionWS, 1.0));
        // #endif

        outputBase[i].tangent = input[i].tangent;
        outputBase[i].worldPos = input[i].worldPos;
        outputBase[i].localPos = input[i].localPos;
        outputBase[i].vertexColor = input[i].vertexColor;
        outputBase[i].lightmapUV = input[i].lightmapUV;
        outputBase[i].fogCoord = input[i].fogCoord;
        outputBase[i].uv[0] = input[i].uv[0];
        outputBase[i].uv[1] = input[i].uv[1];
        outputBase[i].normal = input[i].normal;
        outputBase[i].furLayer = -2;
    }

    // Front
    if(_Cull != 1)
    {
        outStream.Append(outputBase[0]);
        outStream.Append(outputBase[1]);
        outStream.Append(outputBase[2]);
        outStream.RestartStrip();
    }

    // Back
    if(_Cull != 2)
    {
        outStream.Append(outputBase[2]);
        outStream.Append(outputBase[1]);
        outStream.Append(outputBase[0]);
        outStream.RestartStrip();
    }
#endif
//end MIT liltoon

#T#lilFurGeometryMods
//start MIT liltoon
if(_FurMeshType)
{
    #if !defined(OPTIMIZER_ENABLED)
    if(instanceID == 0) {
    #endif

    float3 furVectors[3];
    furVectors[0] = input[0].furVector;
    furVectors[1] = input[1].furVector;
    furVectors[2] = input[2].furVector;
    uint3 n0 = (input[0].vertexId * 3 + input[1].vertexId * 1 + input[2].vertexId * 1) * uint3(1597334677U, 3812015801U, 2912667907U);
    uint3 n1 = (input[0].vertexId * 1 + input[1].vertexId * 3 + input[2].vertexId * 1) * uint3(1597334677U, 3812015801U, 2912667907U);
    uint3 n2 = (input[0].vertexId * 1 + input[1].vertexId * 1 + input[2].vertexId * 3) * uint3(1597334677U, 3812015801U, 2912667907U);
    float3 noise0 = normalize(float3(n0) * (2.0/float(0xffffffffU)) - 1.0);
    float3 noise1 = normalize(float3(n1) * (2.0/float(0xffffffffU)) - 1.0);
    float3 noise2 = normalize(float3(n2) * (2.0/float(0xffffffffU)) - 1.0);
    furVectors[0] += noise0 * _FurVector.w * _FurRandomize;
    furVectors[1] += noise1 * _FurVector.w * _FurRandomize;
    furVectors[2] += noise2 * _FurVector.w * _FurRandomize;
    #if defined(PROP_FURLENGTHMASK) || !defined(OPTIMIZER_ENABLED)
        furVectors[0] *= tex2Dlod(_FurLengthMask, float4(input[0].uv[0] * _FurLengthMask_ST.xy + _FurLengthMask_ST.zw,0, 0)).r;
        furVectors[1] *= tex2Dlod(_FurLengthMask, float4(input[1].uv[0] * _FurLengthMask_ST.xy + _FurLengthMask_ST.zw,0, 0)).r;
        furVectors[2] *= tex2Dlod(_FurLengthMask, float4(input[2].uv[0] * _FurLengthMask_ST.xy + _FurLengthMask_ST.zw,0, 0)).r;
    #endif

    if(_FurLayerNum == 1)
    {
        AppendFur(outStream, output, input, furVectors, float3(1.0, 0.0, 0.0) / 1.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 1.0, 0.0) / 1.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 0.0, 1.0) / 1.0);
    }
    else if(_FurLayerNum >= 2)
    {
        AppendFur(outStream, output, input, furVectors, float3(1.0, 0.0, 0.0) / 1.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 1.0, 1.0) / 2.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 1.0, 0.0) / 1.0);
        AppendFur(outStream, output, input, furVectors, float3(1.0, 0.0, 1.0) / 2.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 0.0, 1.0) / 1.0);
        AppendFur(outStream, output, input, furVectors, float3(1.0, 1.0, 0.0) / 2.0);
    }
    if(_FurLayerNum >= 3)
    {
        AppendFur(outStream, output, input, furVectors, float3(1.0, 4.0, 1.0) / 6.0);
        AppendFur(outStream, output, input, furVectors, float3(0.0, 1.0, 1.0) / 2.0);
        AppendFur(outStream, output, input, furVectors, float3(1.0, 1.0, 4.0) / 6.0);
        AppendFur(outStream, output, input, furVectors, float3(1.0, 0.0, 1.0) / 2.0);
        AppendFur(outStream, output, input, furVectors, float3(4.0, 1.0, 1.0) / 6.0);
        AppendFur(outStream, output, input, furVectors, float3(1.0, 1.0, 0.0) / 2.0);
    }
    AppendFur(outStream, output, input, furVectors, float3(1.0, 0.0, 0.0) / 1.0);
    outStream.RestartStrip();

    #if !defined(OPTIMIZER_ENABLED)
    }
    #endif
}
else
{
    // the following is based on liltoon, but this section in liltoon was based on UnlitWF/UnToon by whiteflare (https://github.com/whiteflare/Unlit_WF_ShaderSuite), which is licensed under the MIT license
    // The MIT License

    // Copyright 2018-2024 whiteflare.

    // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
    // to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    // and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    float3 fvc = (input[0].furVector + input[1].furVector + input[2].furVector) * 0.333333333333;
    float4 wpc = (input[0].worldPos + input[1].worldPos + input[2].worldPos) * 0.333333333333;
    float4 uv0c = (input[0].uv[0] + input[1].uv[0] + input[2].uv[0]) * 0.333333333333;
    float4 uv1c = (input[0].uv[1] + input[1].uv[1] + input[2].uv[1]) * 0.333333333333;
    
    float3 ndc = (input[0].normal + input[1].normal + input[2].normal) * 0.333333333333;
    float4 tangentc = (input[0].tangent + input[1].tangent + input[2].tangent) * 0.333333333333;
    float4 vcolorc = (input[0].vertexColor + input[1].vertexColor + input[2].vertexColor) * 0.333333333333;
    float4 lmapuvc = (input[0].lightmapUV + input[1].lightmapUV + input[2].lightmapUV) * 0.333333333333;
    
    float2 vlfc = (input[0].fogCoord + input[1].fogCoord + input[2].fogCoord) * 0.333333333333;
    
    // not implemented
    // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
    //     float3 pwpc = (input[0].previousPositionWS + input[1].previousPositionWS + input[2].previousPositionWS) *0.333333333333;
    // #endif

    for(uint fl = instanceID * _FurLayerNum * 0.5; fl < _FurLayerNum * (0.5 + 0.5 * instanceID); fl++)
    {
        float lpmix = fl/(float)_FurLayerNum;
        for(int ii=0;ii<4;ii++)
        {
            int inputIndex = ii==3 ? 0 : ii;

            // Common
            float4 outUV = lerp(input[inputIndex].uv[0],uv0c,lpmix);
            output.uv[0] = outUV;
            output.uv[1] = lerp(input[inputIndex].uv[1],uv1c,lpmix);
            output.normal = lerp(input[inputIndex].normal,ndc,lpmix);
            output.fogCoord = lerp(input[inputIndex].fogCoord,vlfc,lpmix);

            float3 fvmix = lerp(input[inputIndex].furVector,fvc,lpmix);
            float3 furVector = normalize(fvmix);
            uint3 n0 = (input[0].vertexId * input[1].vertexId * input[2].vertexId + (fl * 439853 + ii * 364273 + 1)) * uint3(1597334677U, 3812015801U, 2912667907U);
            float3 noise0 = normalize(float3(n0) * (2.0/float(0xffffffffU)) - 1.0);
            fvmix += noise0 * _FurVector.w * _FurRandomize;
            #if defined(PROP_FURLENGTHMASK) || !defined(OPTIMIZER_ENABLED)
                fvmix *= tex2Dlod(_FurLengthMask, float4(outUV * _FurLengthMask_ST.xy + _FurLengthMask_ST.zw,0, 0)).r;
            #endif

            // In
            float4 positionWS = lerp(input[inputIndex].worldPos,wpc,lpmix);
            output.worldPos = positionWS;
            output.pos = UnityWorldToClipPos(positionWS);
            output.localPos = mul(unity_WorldToObject, positionWS);

            // not implemented
            // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
            //     float3 previousPositionWS = lerp(input[inputIndex].previousPositionWS,pwpc,lpmix);
            //     output.previousPositionCS = mul(LIL_MATRIX_PREV_VP, float4(previousPositionWS, 1.0));
            // #endif

            output.furLayer = 0;

            #if defined(LIL_FUR_PRE)
                #if defined(UNITY_REVERSED_Z)
                    // DirectX
                    output.pos.z -= 0.0000001;
                #else
                    // OpenGL
                    output.pos.z += 0.0000001;
                #endif
            #endif
            outStream.Append(output);

            // Out
            positionWS += float4(fvmix,0);
            output.worldPos = positionWS;
            output.pos = UnityWorldToClipPos(positionWS);
            output.localPos = mul(unity_WorldToObject, positionWS);

            // not implemented
            // #if defined(LIL_PASS_MOTIONVECTOR_INCLUDED)
            //     previousPositionWS.xyz += fvmix;
            //     output.previousPositionCS = mul(LIL_MATRIX_PREV_VP, float4(previousPositionWS, 1.0));
            // #endif

            output.furLayer = 1;

            #if defined(LIL_FUR_PRE)
                #if defined(UNITY_REVERSED_Z)
                    // DirectX
                    output.positionCS.z -= 0.0000001;
                #else
                    // OpenGL
                    output.positionCS.z += 0.0000001;
                #endif
            #endif
            outStream.Append(output);
        }
        outStream.RestartStrip();
    }
    // section based on UnlitWF/UnToon by whiteflare ends here
}
//end MIT liltoon


#T#lilFurFragColorLate
//start MIT liltoon
float furLayer = i.furLayer; // (-2,0,1)
float furLayerShift = furLayer - furLayer * _FurRootOffset + _FurRootOffset; // (-2,0,1) bis 1
float furLayerAbs = abs(furLayerShift);
float furNoiseMask = 1.0;

#if defined(PROP_FURNOISEMASK) || !defined(OPTIMIZER_ENABLED)
    furNoiseMask = POI2D_SAMPLER(_FurNoiseMask, _MainTex, poiUV(poiMesh.uv[0], _FurNoiseMask_ST)).r;
#endif

#if defined(LIL_FUR_PRE)
    bool firstPass = true;
#else
    bool firstPass = false;
#endif

bool cutoutRendering = _Mode == POI_MODE_CUTOUT || _Mode == POI_MODE_TRANSCLIPPING;

// should be optimized by the compiler in the locked version
float furAlphaMultiplier = cutoutRendering || firstPass ? furLayerAbs + 0.25 : 1;

#if defined(LIL_ONEPASS_FUR)
    float furAlpha = furLayerShift < -1.5 ? 1.0 : saturate(furNoiseMask - furLayerShift * furLayerAbs * furLayerAbs * furAlphaMultiplier);
#else
    float furAlpha = saturate(furNoiseMask - furLayerShift * furLayerAbs * furLayerAbs * furAlphaMultiplier);
#endif

#if defined(PROP_FURMASK) || !defined(OPTIMIZER_ENABLED)
    furAlpha *= POI2D_SAMPLER(_FurMask, _MainTex, poiUV(poiMesh.uv[0], _FurMask_ST)).r;
#endif

poiFragData.alpha *= furAlpha;

// should be optimized by the compiler in the locked version
if(cutoutRendering || firstPass)
{
    float furAO = _FurAO * saturate(1.0 - fwidth(i.furLayer));
    poiFragData.baseColor.rgb *= furLayer * furAO * 2.0 + 1.0 - furAO;
} else
{
    poiFragData.baseColor.rgb *= saturate(1.0 - furNoiseMask + furNoiseMask * furLayer) * _FurAO * 1.25 + 1.0 - _FurAO;
}
//end MIT liltoon