// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
namespace Stride.Rendering.Materials
{
    /// <summary>
    /// Performs a Microfacet shading
    /// </summary>
    class MaterialSurfaceShadingSpecularCelShading : IMaterialSurfaceShading, MaterialPixelShadingStream, Math, BRDFMicrofacet, LightStream
    {
        compose IMaterialCelShadingLightFunction celLightFunction;

        compose IMaterialSpecularMicrofacetFresnelFunction fresnelFunction;

        compose IMaterialSpecularMicrofacetVisibilityFunction geometricShadowingFunction;

        compose IMaterialSpecularMicrofacetNormalDistributionFunction normalDistributionFunction;

        compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction;

        override float3 ComputeDirectLightContribution()
        {
            var specularColor = streams.matSpecularVisible;

            var fresnel = fresnelFunction.Compute(specularColor);
            var geometricShadowing = geometricShadowingFunction.Compute();
            var normalDistribution = normalDistributionFunction.Compute();

            var reflected = fresnel * geometricShadowing * normalDistribution / 4;

            return celLightFunction.Compute(reflected) * streams.lightColorNdotL * streams.matDiffuseSpecularAlphaBlend.y;
        }

        override float3 ComputeEnvironmentLightContribution()
        {
            var specularColor = streams.matSpecularVisible;

            // TODO: Allow plugability of this function (pb is that it is a combination of fresnel, visibility and NDF)
            //return specularColor * streams.envLightSpecularColor;
            return environmentFunction.Compute(specularColor, streams.alphaRoughness, streams.NdotV) * streams.envLightSpecularColor;
        }
    };
}
