<?xml version="1.0" encoding="utf-8"?>

<CustomShader version="5">
    <Parameters>
        <Parameter name="fillTypeId"    target="fillTypeId"    type="float"  group="base" defaultValue = "0"/>
        <Parameter name="colorScale"    target="colorScale"    type="float3" group="base" defaultValue = "1.0 1.0 1.0" minValue = "0 0 0" maxValue = "1 1 1"/>
        <Parameter name="isCustomShape" target="isCustomShape" type="float"  group="base" defaultValue = "0.0"/>
        <Parameter name="uvOffset"      target="uvOffset"      type="float3" group="base" defaultValue="0 0 0 1" />
    </Parameters>
    <UvUsages>
        <UvUsage textureName="baseMap"   uvType="worldspace"/>
        <UvUsage textureName="normalMap" uvType="worldspace"/>
        <UvUsage textureName="glossMap"  uvType="worldspace"/>
    </UvUsages>
    <Textures>
      <Texture name="baseMap"   type="2dArray"/>
      <Texture name="glossMap"  type="2dArray"/>
      <Texture name="normalMap" type="2dArray"/>
    </Textures>
    <VertexAttributes>
        <IgnoredVertexAttribute name="uv0"     group="base"/>
        <IgnoredVertexAttribute name="tangent" group="base"/>
    </VertexAttributes>
    <LodLevel startDistance="0">
        <CodeInjections>
            <CodeInjection position="SHARED_START">
<![CDATA[
#define ALBEDO_MAP_TYPE sampler2DArray
#define NORMAL_MAP_TYPE sampler2DArray
#define GLOSS_MAP_TYPE  sampler2DArray
]]>
            </CodeInjection>
            <CodeInjection position="CONFIG_DEFINES">
<![CDATA[
//#define ALBEDO_MAP
//#define NORMAL_MAP
//#define GLOSS_MAP
#define ALPHA_TESTED
]]>
            </CodeInjection>
            <CodeInjection position="OBJECT_PARAMETERS">
<![CDATA[
float fillTypeId;
float3 colorScale; // extra color control
// 0 - geometry generated by the game, which have In.normal.w calculated
// 1 - cutom geometry made by artists, do not have In.normal.w
float isCustomShape;
float3 uvOffset;
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float2 texCoordsX  : TEXCOORDn;
float2 texCoordsY  : TEXCOORDn;
float2 texCoordsZ  : TEXCOORDn;
float4 blendNormal : TEXCOORDn;
]]>
            </CodeInjection>
            <CodeInjection position="POST_SET_TEXCOORDS_VS">
<![CDATA[
    float2 uvScale = float2(1.0,1.0); //object.uvScale was here
    Out.texCoordsY = (In.position.xz + object.uvOffset.xz) * uvScale;
    Out.texCoordsZ = (In.position.xy + object.uvOffset.xy) * uvScale;
    Out.texCoordsX = (In.position.zy + object.uvOffset.zy) * uvScale;
    if (object.isCustomShape>0.0){
        Out.blendNormal.xyz = normalize(In.normal.xyz);
    }else{
        Out.blendNormal.xyz = normalize(getNormal(In, object));
    }
    Out.blendNormal.w = In.normal.w;
]]>
            </CodeInjection>
            <CodeInjection position="GET_NORMAL_VS">
<![CDATA[
    if (object.isCustomShape>0.0){
        //do nothing
    }else{
        // convert from ubyte to [-1,1] range
        return In.normal.xyz-0.5;
    }
]]>
            </CodeInjection>
            <CodeInjection position = "FS_GLOBALS">
<![CDATA[
    float3 gBlendWeights;
]]>
            </CodeInjection>
            <CodeInjection position = "START_FS">
<![CDATA[
    globals.gBlendWeights = pow(abs(In.vs.blendNormal.xyz), 2.5);
    globals.gBlendWeights /= (globals.gBlendWeights.x + globals.gBlendWeights.y + globals.gBlendWeights.z);
]]>
            </CodeInjection>
            <CodeInjection position="POST_DIFFUSE_COLOR_FS">
<![CDATA[
#if defined(ALBEDO_MAP)
{
           diffuseColor  = tex2D(baseMap, float3(In.vs.texCoordsY, object.fillTypeId)).xyz;
    float3 diffuseColor2 = tex2D(baseMap, float3(In.vs.texCoordsZ, object.fillTypeId)).xyz;
    float3 diffuseColor3 = tex2D(baseMap, float3(In.vs.texCoordsX, object.fillTypeId)).xyz;
    diffuseColor = diffuseColor*globals.gBlendWeights.y + diffuseColor2*globals.gBlendWeights.z + diffuseColor3*globals.gBlendWeights.x;
    if ( (1.0 > object.colorScale.r) || (1.0 > object.colorScale.g) || (1.0 > object.colorScale.b) ){
        diffuseColor *= object.colorScale.rgb;
    }
}
#endif
]]>
            </CodeInjection>
            <CodeInjection position="ALPHA_FS">
<![CDATA[
{
    if (object.isCustomShape>0.0){
        alpha = 1.0;
    }else{
        alpha = In.vs.blendNormal.w;
    }
}
]]>
            </CodeInjection>
            <CodeInjection position="MODIFY_ALPHA_CLIP_FS">
<![CDATA[
    alphaClipLevel = 0.009;
]]>
            </CodeInjection>
            <CodeInjection position="POST_GLOSS_COLOR_FS">
<![CDATA[
#if defined(GLOSS_MAP)
{
    float3 pbrMapValues  = tex2D(glossMap, float3(In.vs.texCoordsY, object.fillTypeId)).xyz;
    float3 pbrMapValues2 = tex2D(glossMap, float3(In.vs.texCoordsZ, object.fillTypeId)).xyz;
    float3 pbrMapValues3 = tex2D(glossMap, float3(In.vs.texCoordsX, object.fillTypeId)).xyz;
    pbrMapValues = pbrMapValues*globals.gBlendWeights.y + pbrMapValues2*globals.gBlendWeights.z + pbrMapValues3*globals.gBlendWeights.x;
    roughness = 1-pbrMapValues.x;
    bakedAO   = pbrMapValues.y;
    metalness = pbrMapValues.z;
}
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_NORMAL_FS">
<![CDATA[
// Our normal is always in world space
#if defined(NORMAL_MAP)
{
    float3 normal1 = tex2D(normalMap, float3(In.vs.texCoordsY, object.fillTypeId)).xyz - 0.5;
    float3 normal2 = tex2D(normalMap, float3(In.vs.texCoordsZ, object.fillTypeId)).xyz - 0.5;
    float3 normal3 = tex2D(normalMap, float3(In.vs.texCoordsX, object.fillTypeId)).xyz - 0.5;

    float3 signedNormalsZ = sign(In.vs.blendNormal.xyz)*float3(normal3.z, normal1.z, normal2.z);

    normal1 = float3(normal1.x, signedNormalsZ.y, -signedNormalsZ.y*normal1.y);
    normal2 = float3(normal2.x, -signedNormalsZ.z*normal2.y, signedNormalsZ.z);
    normal3 = float3(signedNormalsZ.x, -signedNormalsZ.x*normal3.y, normal3.x);

    float3 blendedNormal = normal1*globals.gBlendWeights.y + normal2*globals.gBlendWeights.z + normal3*globals.gBlendWeights.x;
    blendedNormal = mul((float3x3) object.modelMatrix, blendedNormal);

    return normalize(blendedNormal);
}
#endif
]]>
            </CodeInjection>
            <CodeInjection position="PARALLAX_MAPPING_FS">
<![CDATA[
#ifdef PARALLAX_MAP
{
    // TODO handle parallax mapping
}
#endif
]]>
            </CodeInjection>
            <CodeInjection position="FINAL_POS_FS">
<![CDATA[
//oColor.xyz *= 0.001;
//oColor.xyz += In.vs.blendNormal.w; //getNormal(In, globals, object);
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
