// File generated by Flax Materials Editor
// Version: @0

#define MATERIAL 1
@3
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#include "./Flax/GUICommon.hlsl"
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 ViewProjectionMatrix;
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float3 ViewPos;
float ViewFar;
float3 ViewDir;
float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float4 ViewSize;
@1META_CB_END

// Shader resources
@2
// Interpolants passed from the vertex shader
struct VertexOutput
{
	float4 Position          : SV_Position;
	float3 WorldPosition     : TEXCOORD0;
	float2 TexCoord          : TEXCOORD1;
	float2 WindowPos         : TEXCOORD2;
#if USE_VERTEX_COLOR
	half4 VertexColor        : COLOR;
#endif
	float4 ClipExtents       : TEXCOORD3;
	float2 ClipOrigin        : TEXCOORD4;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
};

// Interpolants passed to the pixel shader
struct PixelInput
{
	float4 Position          : SV_Position;
	float3 WorldPosition     : TEXCOORD0;
	float2 TexCoord          : TEXCOORD1;
	float2 WindowPos         : TEXCOORD2;
#if USE_VERTEX_COLOR
	half4 VertexColor        : COLOR;
#endif
	float4 ClipExtents       : TEXCOORD3;
	float2 ClipOrigin        : TEXCOORD4;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
	bool IsFrontFace         : SV_IsFrontFace;
};

// Material properties generation input
struct MaterialInput
{
	float3 WorldPosition;
	float TwoSidedSign;
	float2 TexCoord;
#if USE_VERTEX_COLOR
	half4 VertexColor;
#endif
	float3x3 TBN;
	float4 SvPosition;
	float3 PreSkinnedPosition;
	float3 PreSkinnedNormal;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT];
#endif
};

MaterialInput GetMaterialInput(Render2DVertex input, VertexOutput output)
{
	MaterialInput result;
	result.WorldPosition = output.WorldPosition;
	result.TexCoord = output.TexCoord;
#if USE_VERTEX_COLOR
	result.VertexColor = output.VertexColor;
#endif
	result.TBN[0] = float3(1, 0, 0);
	result.TBN[1] = float3(0, 1, 0);
	result.TBN[2] = float3(0, 0, 1);
	result.TwoSidedSign = 1.0;
	result.SvPosition = output.Position;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	result.CustomVSToPS = output.CustomVSToPS;
#endif
	return result;
}

MaterialInput GetMaterialInput(PixelInput input)
{
	MaterialInput result;
	result.WorldPosition = input.WorldPosition;
	result.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
	result.VertexColor = input.VertexColor;
#endif
	result.TBN[0] = float3(1, 0, 0);
	result.TBN[1] = float3(0, 1, 0);
	result.TBN[2] = float3(0, 0, 1);
	result.TwoSidedSign = input.IsFrontFace	? 1.0 : -1.0;
	result.SvPosition = input.Position;
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	result.CustomVSToPS = input.CustomVSToPS;
#endif
	return result;
}

// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{
	return mul(tangentVector, input.TBN);
}

// Transforms a vector from world space to tangent space
float3 TransformWorldVectorToTangent(MaterialInput input, float3 worldVector)
{
	return mul(input.TBN, worldVector);
}

// Transforms a vector from world space to view space
float3 TransformWorldVectorToView(MaterialInput input, float3 worldVector)
{
	return mul(worldVector, (float3x3)ViewMatrix);
}

// Transforms a vector from view space to world space
float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
{
	return mul((float3x3)ViewMatrix, viewVector);
}

// Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{
	return localVector;
}

// Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{
	return worldVector;
}

// Gets the current object position (supports instancing)
float3 GetObjectPosition(MaterialInput input)
{
	return float3(0, 0, 0);
}

// Gets the current object size
float3 GetObjectSize(MaterialInput input)
{
	return float3(1, 1, 1);
}

// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
	return 0;
}

// Get the current object LOD transition dither factor (supports instancing)
float GetLODDitherFactor(MaterialInput input)
{
	return 0;
}

// Gets the interpolated vertex color (in linear space)
float4 GetVertexColor(MaterialInput input)
{
#if USE_VERTEX_COLOR
	return input.VertexColor;
#else
	return 1;
#endif
}

@8

// Get material properties function (for vertex shader)
Material GetMaterialVS(MaterialInput input)
{
@5
}

// Get material properties function (for pixel shader)
Material GetMaterialPS(MaterialInput input)
{
@4
}

// Vertex Shader function for GUI materials rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT,       0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT,       0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(COLOR,    0, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 2, R32G32B32A32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_GUI(Render2DVertex input)
{
	VertexOutput output;

	// Render2D::RenderingFeatures::VertexSnapping
	if ((int)input.CustomDataAndClipOrigin.y & 1)
		input.Position = (int2)input.Position;

	output.Position = mul(float4(input.Position, 0, 1), ViewProjectionMatrix);
	output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
	output.TexCoord = input.TexCoord;
	output.WindowPos = input.Position;
#if USE_VERTEX_COLOR
	output.VertexColor = input.Color;
#endif
	output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
	output.ClipExtents = input.ClipExtents;

	// Get material input params if need to evaluate any material property
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	MaterialInput materialInput = GetMaterialInput(input, output);
	Material material = GetMaterialVS(materialInput);
#endif

	// Copy interpolants for other shader stages
#if USE_CUSTOM_VERTEX_INTERPOLATORS
	output.CustomVSToPS = material.CustomVSToPS;
#endif

	return output;
}

// Pixel Shader function for GUI materials rendering
META_PS(true, FEATURE_LEVEL_ES2)
float4 PS_GUI(PixelInput input) : SV_Target0
{
	// 2D per pixel clipping
	PerformClipping(input.ClipOrigin, input.WindowPos, input.ClipExtents);

	// Get material parameters
	MaterialInput materialInput = GetMaterialInput(input);
	Material material = GetMaterialPS(materialInput);

	// Masking
#if MATERIAL_MASKED
	clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif

	return float4(material.Emissive, material.Opacity);
}

@9
