#line 2 "E:\Program Files\Dead Steel\Data\Shaders\Generated\NiTerrainMaterial\Shader0000-V.hlsl"
/*
Shader description:
OUTPUTWORLDNBT = 1
TANGENTS = 1
FOGTYPE = 0
OUTPUTWORLDNBT = 1
TANGENTS = 1
FOGTYPE = 0
NUM_TEXCOORDS = 1
*/

//---------------------------------------------------------------------------
// Types:
#if defined(DIRECT3D)
#define BONEMATRIX_TYPE float4x3
#else
#define BONEMATRIX_TYPE float3x4
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Constant variables:
//---------------------------------------------------------------------------

float2 g_UVScaleBlend;
float2 g_UVOffsetBlend;
float2 g_UVScaleSurface;
float2 g_UVOffsetSurface;
float4x4 g_World;
float4 g_EyePos;
float g_LODThresholdDistance;
float g_LODMorphDistance;
float3 g_AdjustedEyePos;
float4x4 g_ViewProj;
//---------------------------------------------------------------------------
// Functions:
//---------------------------------------------------------------------------

/*

      This fragment takes an incoming float4 vertex position with the xyz
      components containing the position, and the w component containing the
      height in the vertex of the next level of detail. The height or z value of
      the final vertex position is interpolated between the 2 levels of detail.
    
*/

void SplitPosition(float4 CombinedPosition,
    out float4 PositionHigh,
    out float4 PositionLow)
{

      PositionHigh = float4(CombinedPosition.xyz, 1.0);
      PositionLow = float4(CombinedPosition.xyw, 1.0);
    
}
//---------------------------------------------------------------------------
/*

      This fragment takes an incoming float4 encoding the xz of the vertex tangent.
      The zw components encode the xz of the lower lod vertex tangent. The output
      is a 3 component vertex tangent of the incoming tangent and the lower lod
      tangent.
    
*/

void SplitTangent(float4 CombinedTangent,
    out float3 TangentHigh,
    out float3 TangentLow)
{

      TangentHigh = float3(CombinedTangent.x, 0.0, CombinedTangent.y);
      TangentLow = float3(CombinedTangent.z, 0.0, CombinedTangent.w);
    
}
//---------------------------------------------------------------------------
/*

      Scales and offsets the specified texture coordinate based on the block's
      level of detail. This is too allow blocks to share the same UV set instead
      of allocate once large UV set for each layer.
    
*/

void CalculateTextureCoordinates(float2 UVCoord,
    float2 UVBlendScale,
    float2 UVBlendOffset,
    float2 UVSurfaceScale,
    float2 UVSurfaceOffset,
    out float4 OutputUVCoord)
{

      OutputUVCoord.zw = UVCoord * UVBlendScale + UVBlendOffset;
      OutputUVCoord.xy = (OutputUVCoord.zw) * UVSurfaceScale + UVSurfaceOffset;
    
}
//---------------------------------------------------------------------------
/*

      This fragment is responsible for applying the world transform to the
      incoming local vertex position.
    
*/

void TransformPositionToWorld(float4 LocalPosition,
    float4x4 WorldMatrix,
    out float4 WorldPos)
{

      WorldPos = mul(LocalPosition, WorldMatrix);
    
}
//---------------------------------------------------------------------------
/*

      This fragment is responsible for applying the view-projection matrix
      to the incoming world space vertex position.
    
*/

void TransformPositionToClip(float4 WorldPosition,
    float4x4 ViewProjMatrix,
    out float4 WorldProj)
{

      WorldProj = mul(WorldPosition, ViewProjMatrix);
    
}
//---------------------------------------------------------------------------
/*

      This fragment takes an incoming float4 encoding the xy of the vertex normal.
      The zw components encode the xy of the lower lod vertex normal. The output
      is a 3 component vertex normal of the incoming normal and the lower lod
      normal.
    
*/

void SplitNormal(float4 CombinedNormal,
    out float3 NormalHigh,
    out float3 NormalLow)
{

      NormalHigh = float3(CombinedNormal.xy, 1.0);
      NormalLow = float3(CombinedNormal.zw, 1.0);
    
}
//---------------------------------------------------------------------------
/*

        Calculates the amount in which to morph one vertex in the terrain to the
        target vertex in the next terrain lod. This function uses the 2D distance
        of the camera to the vertex to select the morphing value
    
*/

void Calculate2DVertexMorph(float LODThresholdDistance,
    float LODMorphDistance,
    float3 TerrainCameraPos,
    float4 LocalPos,
    out float LODMorphValue)
{

        float d = distance(LocalPos.xy, TerrainCameraPos.xy);
        LODMorphValue = saturate((d - LODThresholdDistance) / LODMorphDistance);
    
}
//---------------------------------------------------------------------------
/*

      Linearly interpolates a float3 value and normalizes the result.
    
*/

void LerpFloat3AndNormalize(float3 InputOne,
    float3 InputTwo,
    float Amount,
    out float3 InterpolatedOutput)
{

      InterpolatedOutput = normalize(lerp(InputOne, InputTwo, Amount));
    
}
//---------------------------------------------------------------------------
/*

      This fragment only applys the rotation portion of the world transformation to
      the incoming float3.
    
*/

void ApplyWorldRotation(float3 ValueToRotate,
    float4x4 WorldMatrix,
    out float3 WorldRotationOfValue)
{

      WorldRotationOfValue = mul(ValueToRotate, (float3x3)WorldMatrix);
    
}
//---------------------------------------------------------------------------
/*

      Linearly interpolates a float4.
    
*/

void LerpFloat4(float4 InputOne,
    float4 InputTwo,
    float Amount,
    out float4 InterpolatedOutput)
{

      InterpolatedOutput = lerp(InputOne, InputTwo, Amount);
    
}
//---------------------------------------------------------------------------
/*

      Takes the cross product of a vertex normal and a tangent to create a binormal.      
      Assumes the vertex normal and tangent are normalized.
    
*/

void CalculateBinormal(float3 WorldNormal,
    float3 WorldTangent,
    out float3 WorldBinormal)
{

      WorldBinormal = cross(WorldNormal, WorldTangent);
    
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Input:
//---------------------------------------------------------------------------

struct Input
{
    float4 vPosition : POSITION0;
    float4 vNormal : NORMAL0;
    float2 UVSet0 : TEXCOORD0;
    float4 vTangent : TANGENT0;

};

//---------------------------------------------------------------------------
// Output:
//---------------------------------------------------------------------------

struct Output
{
    float4 WorldProj : POSITION0;
    float4 UVSet0 : TEXCOORD0;
    float3 WorldNormal : TEXCOORD1;
    float3 WorldBinormal : TEXCOORD2;
    float3 WorldTangent : TEXCOORD3;
    float4 WorldPos : TEXCOORD4;

};

//---------------------------------------------------------------------------
// Main():
//---------------------------------------------------------------------------

Output Main(Input In)
{
    Output Out;
	// Function call #0
    float4 PositionHigh_CallOut0;
    float4 PositionLow_CallOut0;
    SplitPosition(In.vPosition, PositionHigh_CallOut0, PositionLow_CallOut0);

	// Function call #1
    float3 TangentHigh_CallOut1;
    float3 TangentLow_CallOut1;
    SplitTangent(In.vTangent, TangentHigh_CallOut1, TangentLow_CallOut1);

	// Function call #2
    CalculateTextureCoordinates(In.UVSet0, g_UVScaleBlend, g_UVOffsetBlend, 
        g_UVScaleSurface, g_UVOffsetSurface, Out.UVSet0);

	// Function call #3
    TransformPositionToWorld(PositionHigh_CallOut0, g_World, Out.WorldPos);

	// Function call #4
    float4 WorldProj_CallOut4;
    TransformPositionToClip(Out.WorldPos, g_ViewProj, WorldProj_CallOut4);

	// Function call #5
    float3 NormalHigh_CallOut5;
    float3 NormalLow_CallOut5;
    SplitNormal(In.vNormal, NormalHigh_CallOut5, NormalLow_CallOut5);

	// Function call #6
    float LODMorphValue_CallOut6;
    Calculate2DVertexMorph(g_LODThresholdDistance, g_LODMorphDistance, 
        g_AdjustedEyePos, In.vPosition, LODMorphValue_CallOut6);

	// Function call #7
    float3 InterpolatedOutput_CallOut7;
    LerpFloat3AndNormalize(NormalHigh_CallOut5, NormalLow_CallOut5, 
        LODMorphValue_CallOut6, InterpolatedOutput_CallOut7);

	// Function call #8
    float3 InterpolatedOutput_CallOut8;
    LerpFloat3AndNormalize(TangentHigh_CallOut1, TangentLow_CallOut1, 
        LODMorphValue_CallOut6, InterpolatedOutput_CallOut8);

	// Function call #9
    float4 WorldPos_CallOut9;
    TransformPositionToWorld(PositionLow_CallOut0, g_World, WorldPos_CallOut9);

	// Function call #10
    ApplyWorldRotation(InterpolatedOutput_CallOut8, g_World, Out.WorldTangent);

	// Function call #11
    float4 WorldProj_CallOut11;
    TransformPositionToClip(WorldPos_CallOut9, g_ViewProj, WorldProj_CallOut11);

	// Function call #12
    ApplyWorldRotation(InterpolatedOutput_CallOut7, g_World, Out.WorldNormal);

	// Function call #13
    LerpFloat4(WorldProj_CallOut4, WorldProj_CallOut11, LODMorphValue_CallOut6, 
        Out.WorldProj);

	// Function call #14
    CalculateBinormal(Out.WorldNormal, Out.WorldTangent, Out.WorldBinormal);

    return Out;
}

