#ifndef LIGHTWEIGHT_TREE_INCLUDED
#define LIGHTWEIGHT_TREE_INCLUDED


// Bark lighting

inline half3 LightingTreeBark (Light light, half3 albedo, half3 specular, half gloss, half squashAmount, half3 normal, half3 viewDir)
{
    float3 halfDir = SafeNormalize(light.direction + viewDir);
    half NoL = saturate( dot (normal, light.direction) );
    float NoH = saturate( dot (normal, halfDir) );
    float spec = pow (NoH, specular.r * 128.0f) * gloss;
    
    half3 c;
    half3 lighting = light.color * light.distanceAttenuation * light.shadowAttenuation * squashAmount;
    // c = albedo * lighting * NoL + lighting * specular * spec;
    c = (albedo + specular * spec) * NoL * lighting;
    return c;
}

half4 LuxURPTreeBarkFragment (InputData inputData, half3 albedo, half3 specular,
    half smoothness, half occlusion, half alpha, half squashAmount
)
{

//  ShadowMask: To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders
    #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
        half4 shadowMask = inputData.shadowMask;
    #elif !defined (LIGHTMAP_ON)
        half4 shadowMask = unity_ProbesOcclusion;
    #else
        half4 shadowMask = half4(1, 1, 1, 1);
    #endif

    //Light mainLight = GetMainLight(inputData.shadowCoord);
    Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask);

//  SSAO
    #if defined(_SCREEN_SPACE_OCCLUSION)
        AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(inputData.normalizedScreenSpaceUV);
        mainLight.color *= aoFactor.directAmbientOcclusion;
        occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
    #endif

    //MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));

    half3 color = albedo * inputData.bakedGI * occlusion;
    color += LightingTreeBark(mainLight, albedo, specular, smoothness, 1.0h, inputData.normalWS, inputData.viewDirectionWS);

    #ifdef _ADDITIONAL_LIGHTS
        uint pixelLightCount = GetAdditionalLightsCount();
        for (uint i = 0u; i < pixelLightCount; ++i)
        {
            // Light light = GetAdditionalLight(i, inputData.positionWS);
        //  URP 10: We have to use the new GetAdditionalLight function
            Light light = GetAdditionalLight(i, inputData.positionWS, shadowMask);
            #if defined(_SCREEN_SPACE_OCCLUSION)
                light.color *= aoFactor.directAmbientOcclusion;
            #endif
            color += LightingTreeBark(light, albedo, specular, smoothness, squashAmount, inputData.normalWS, inputData.viewDirectionWS);
        }
    #endif

    #ifdef _ADDITIONAL_LIGHTS_VERTEX
        color += inputData.vertexLighting * albedo;
    #endif
    
    return half4(color, alpha);
}



// Leaf lighting

inline half3 LightingTreeLeaf(Light light, half3 albedo, half3 specular, half gloss, half2 translucency, half3 translucencyColor, half squashAmount, half3 normal, half3 viewDir)
{
    float3 halfDir = SafeNormalize(light.direction + viewDir);
    half NoL = dot(normal, light.direction);
    float NoH = saturate( dot (normal, halfDir) );
    float spec = pow(NoH, specular.r * 128.0f) * gloss;
    
    // view dependent back contribution for translucency
    half backContrib = saturate(dot(viewDir, -light.direction));
    // normally translucency is more like -nl, but looks better when it's view dependent
    backContrib = lerp(saturate(-NoL), backContrib, translucency.y);
    translucencyColor *= backContrib * translucency.x;
    // wrap-around diffuse
    NoL = saturate (NoL * 0.6h + 0.4h);
    
    half3 c;
    /////@TODO: what is is this multiply 2x here???
    c = albedo * (translucencyColor * 2 + NoL);
//  No lighting on spec?!
    // c = c * light.color * light.distanceAttenuation * light.shadowAttenuation * squashAmount + spec;
    half3 lighting = light.color * light.distanceAttenuation * light.shadowAttenuation * squashAmount;
    c = (c + spec) * lighting;
    
    return c;
}


half4 LuxURPTreeLeafFragmentPBR(InputData inputData, half3 albedo, half3 specular,
    half smoothness, half occlusion, half alpha, half2 translucency, half3 translucencyColor, half squashAmount, half shadowStrength
)
{
    

//  ShadowMask: To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders
    #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
        half4 shadowMask = inputData.shadowMask;
    #elif !defined (LIGHTMAP_ON)
        half4 shadowMask = unity_ProbesOcclusion;
    #else
        half4 shadowMask = half4(1, 1, 1, 1);
    #endif

    //Light mainLight = GetMainLight(inputData.shadowCoord);
    //MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
    Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask);

//  SSAO
    #if defined(_SCREEN_SPACE_OCCLUSION)
        AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(inputData.normalizedScreenSpaceUV);
        mainLight.color *= aoFactor.directAmbientOcclusion;
        occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
    #endif

    mainLight.shadowAttenuation = lerp(1.0h, mainLight.shadowAttenuation, shadowStrength * squashAmount /* fade out */);

    half3 color = albedo * inputData.bakedGI * occlusion;
    color += LightingTreeLeaf(mainLight, albedo, specular, smoothness, translucency, translucencyColor, 1, inputData.normalWS, inputData.viewDirectionWS);

    #ifdef _ADDITIONAL_LIGHTS
        uint pixelLightCount = GetAdditionalLightsCount();
        for (uint i = 0u; i < pixelLightCount; ++i)
        {
            Light light = GetAdditionalLight(i, inputData.positionWS);
            color += LightingTreeLeaf(light, albedo, specular, smoothness, translucency, translucencyColor, squashAmount, inputData.normalWS, inputData.viewDirectionWS);
        }
    #endif

    #ifdef _ADDITIONAL_LIGHTS_VERTEX
        color += inputData.vertexLighting * albedo;
    #endif
    
    return half4(color, alpha);
}

#endif