/*
 * Copyright (c) Contributors to the Open 3D Engine Project.
 * For complete copyright and license terms please see the LICENSE at the root of this distribution.
 *
 * SPDX-License-Identifier: Apache-2.0 OR MIT
 *
 */
 
#define MATERIALPIPELINE_SHADER_HAS_PIXEL_STAGE 1

//TODO(DeferredPOC): Support clear coat
#define ENABLE_CLEAR_COAT 0
#define ENABLE_TRANSMISSION 0

//////////////////////////////////////////////////////////////////////////////////////////////////

#include MATERIAL_TYPE_AZSLI_FILE_PATH

//////////////////////////////////////////////////////////////////////////////////////////////////

#include <viewsrg.srgi>
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
#include <Atom/Features/ColorManagement/TransformColor.azsli>
#include <Atom/Features/PBR/LightingOptions.azsli>

VsOutput MaterialVS(VsInput IN, uint instanceId : SV_InstanceID)
{
    VsSystemValues SV;
    SV.m_instanceId = instanceId;
    return EvaluateVertexGeometry(IN, SV);
}

struct DeferredMaterialOutput
{
    float4 m_baseColor  : SV_Target0;
    float4 m_roughnessMetal : SV_Target1; 
    float4 m_normal : SV_Target2;
    
#if OUTPUT_DEPTH
    float m_depth : SV_Depth;
#endif
};

// TODO(MaterialPipeline): Probably replace this with FORCE_EARLY_DEPTH_STENCIL like how it's done in MultiViewForwardPassVertexAndPixel.azsli
#if !OUTPUT_DEPTH
    [earlydepthstencil]
#endif
DeferredMaterialOutput MaterialPS(VsOutput IN, bool isFrontFace : SV_IsFrontFace)
{
    // ------- Geometry -> Surface -------

    PixelGeometryData geoData = EvaluatePixelGeometry(IN, isFrontFace);

    Surface surface = EvaluateSurface(IN, geoData);

    // ------- Output -------

    DeferredMaterialOutput OUT;

    OUT.m_baseColor = float4(surface.baseColor, 1);
    OUT.m_roughnessMetal = float4(surface.roughnessLinear, surface.metallic, 0, 0);
    OUT.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
    OUT.m_normal.a = EncodeUnorm2BitFlags(o_enableIBL, o_specularF0_enableMultiScatterCompensation);
    
#if OUTPUT_DEPTH
    // Can be modified in Parallax calculations in EvaluatePixelGeometry
    OUT.m_depth = IN.position.z;
#endif

    return OUT;
}


