#include "PBR.fx"
#include "Lib/lights.fx"

float4x4 gWorld : WORLD;
float4x4 gWorldViewProj : WORLDVIEWPROJECTION;
float4x4 gMatrixViewInverse : VIEWINVERSE;

SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap; // or Mirror or Clamp or Border
    AddressV = Wrap; // or Mirror or Clamp or Border
};

RasterizerState Solid
{
    FillMode = SOLID;
    CullMode = FRONT;
};

DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
};

struct VS_INPUT
{
    float3 pos : POSITION;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float2 texCoord : TEXCOORD;
};
struct VS_OUTPUT
{
    float4 pos : SV_POSITION;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float4 worldPosition : COLOR0;
    float2 texCoord : TEXCOORD;
};

VS_OUTPUT VS(VS_INPUT input)
{

    VS_OUTPUT output;
    output.pos = mul(float4(input.pos, 1.0f), gWorldViewProj);
    output.worldPosition = mul(float4(input.pos, 1.0), gWorld);
    output.normal = normalize(mul(input.normal, (float3x3) gWorld));
    output.tangent = normalize(mul(input.tangent, (float3x3) gWorld));
    output.texCoord = input.texCoord;
    return output;
}

float4 PS(VS_OUTPUT input) : SV_TARGET
{
    float3 view = GetViewDirection(input.worldPosition.xyz, gMatrixViewInverse);
    float3 lambert = BRDFLambert(gLight, input.normal, 1, float3(1, 0, 0));
    float3 specular = BRDFSpecular(gLight, input.normal, GetViewDirection(input.worldPosition.xyz, gMatrixViewInverse),
        0.6f, GetMetalColor(0, float3(0.95f, 0.93f, 0.88f)));
    float3 color = Shade(lambert, specular);
    return float4(color, 1);
}

technique11 Default
{
    pass P0
    {
        SetRasterizerState(Solid);
        SetDepthStencilState(EnableDepth, 0);

        SetVertexShader(CompileShader(vs_4_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PS()));
    }
}
