// 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.
/// <summary>
/// Defines the methods to get the normal in world space.
/// </summary>
shader NormalUpdate : NormalStream
{
    stage void GenerateNormal_VS()
    {
        streams.normalWS = 0.0f;
    }

    stage void GenerateNormal_PS()
    {
    }
	
    float3x3 GetTangentMatrix()
    {
        float3x3 tangentMatrix;

        streams.meshNormal = normalize(streams.meshNormal);
        var tangent = normalize(streams.meshTangent.xyz);
        float3 bitangent = streams.meshTangent.w * cross(streams.meshNormal, tangent);
        tangentMatrix = float3x3(tangent, bitangent, streams.meshNormal);

        return tangentMatrix;
    }
	
    stage void UpdateTangentToWorld()
    {
        var tangentMatrix = GetTangentMatrix();
        var tangentWorldTransform = GetTangentWorldTransform();
        streams.tangentToWorld =  mul(tangentMatrix, tangentWorldTransform);
    }

    float3x3 GetTangentWorldTransform()
    {
        return float3x3(1,0,0, 0,1,0, 0,0,1);
    }
	
    // This method is called by the MaterialSurfaceLightingAndShading to calculate the effective normal
    stage void UpdateNormalFromTangentSpace(float3 normalInTangentSpace)
    {
        streams.normalWS = normalize(mul(normalInTangentSpace, streams.tangentToWorld));
    }
};