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

<CustomShader version="1.0" classRequirement="">
    <LodLevel startDistance="0" subsequentPassForceMode="use">
        <Parameters>
            <Parameter name="textureUVScale1" target="In.mat.textureUVScale1" type="float4"/>
            <Parameter name="textureUVScale2" target="In.mat.textureUVScale2" type="float4"/>
            <Parameter name="textureUVScale3" target="In.mat.textureUVScale3" type="float4"/>
            <Parameter name="dirtUVScale" target="In.mat.dirtUVScale" type="float4"/>
            <Parameter name="alphaBlendStartEnd" target="In.mat.alphaBlendStartEnd" type="float4" defaultValue="75 80"/>
        </Parameters>
        <Textures>
          <Texture name="diffuseMap1" />
          <Texture name="normalMap1" />
          <Texture name="diffuseMap2" />
          <Texture name="normalMap2" />
          <Texture name="diffuseMap3" />
          <Texture name="blendMap" />
          <Texture name="noiseMap" />
        </Textures>
        <CodeInjections>
            <CodeInjection position="NUM_TEXCOORDS">
<![CDATA[
// ignore engine core tex coords
#define NUM_TEXCOORDS 0

#if defined(DIFFUSE) // if diffuse is defined, we are in color output mode
#define USE_GROUND_SHADER_COLOR
#endif

#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        #defeval CHANNEL1_TEXCOORD NEXT_TEXCOORD
        //#defeval NORMALMAP1_TEXCOORD NEXT_TEXCOORD
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_2)
        #defeval CHANNEL2_TEXCOORD NEXT_TEXCOORD
        //#defeval NORMALMAP2_TEXCOORD NEXT_TEXCOORD
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_3)
        #defeval CHANNEL3_TEXCOORD NEXT_TEXCOORD
    #endif
    #defeval DIRT_TEXCOORD NEXT_TEXCOORD
#else
    #defeval NOISE_TEXCOORD NEXT_TEXCOORD
#endif

#defeval BLENDMAP_TEXCOORD NEXT_TEXCOORD

]]>
            </CodeInjection>
            <CodeInjection position="CONFIG_DEFINES">
<![CDATA[
#if !defined(TERRAIN_DETAIL_CHANNEL_3)
    #undef _NEED_FS_NORMAL
#endif
#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
        #define _NEED_FS_EYE_VECTOR
        #undef _NEED_FS_NORMAL
        // we need tangent space vectors
        #undef _NO_TANGENTSPACE
        #undef _NO_TANGENTSPACE_LIGHT
    #endif
#endif

#define _HAS_TEXTURES
]]>
            </CodeInjection>
            <CodeInjection position="SAMPLERS">
<![CDATA[
#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        uniform sampler2D diffuseMap1 : TEXUNITN;
        uniform sampler2D normalMap1 : TEXUNITN;
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_2)
        uniform sampler2D diffuseMap2 : TEXUNITN;
        uniform sampler2D normalMap2 : TEXUNITN;
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_3)
        uniform sampler2D diffuseMap3 : TEXUNITN;
    #endif
#endif
uniform sampler2D blendMap : TEXUNITN;
uniform sampler2D noiseMap : TEXUNITN;
]]>
            </CodeInjection>
            <CodeInjection position="MATERIALINFO">
<![CDATA[
#if defined(TERRAIN_DETAIL_CHANNEL_1)
uniform float4 textureUVScale1;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_2)
uniform float4 textureUVScale2;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_3)
uniform float4 textureUVScale3;
#endif
uniform float4 dirtUVScale;
uniform float2 alphaBlendStartEnd;
]]>
            </CodeInjection>
            <CodeInjection position="GET_TEXCOORDS_VS">
<![CDATA[
// convert from short to 0-1 range
return In.texCoords[texCoordSet]/32767.0;
]]>
            </CodeInjection>
            <CodeInjection position="GET_TANGENT_VS">
<![CDATA[
#if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
    return normalize(cross(In.normal.xyz, float3(0,0,1)));
#else
    return float3(1,0,0);
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_BITANGENT_VS">
<![CDATA[
#if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
    float3 tangent = getTangent(In);
    return normalize(cross(tangent, In.normal.xyz));
#else
    return float3(0,0,1);
#endif
]]>
            </CodeInjection>
            <CodeInjection position="POST_SET_TEXCOORDS_VS">
<![CDATA[
float2 albedoTexCoord = getTexCoords(In, ALBEDOMAP_INPUT_TEXCOORD);

#if defined(TERRAIN_DETAIL_CHANNEL_1)
    float2 textureUV1;
    textureUV1.xy = position.xz*In.mat.textureUVScale1.xy;
    //textureUV1.zw = position.xz*In.mat.textureUVScale1.zw;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_2)
    float2 textureUV2;
    textureUV2.xy = position.xz*In.mat.textureUVScale2.xy;
    //textureUV2.zw = position.xz*In.mat.textureUVScale2.zw;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_3)
    float2 textureUV3;
    textureUV3.xy = position.xz*In.mat.textureUVScale3.xy;
#endif

#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        setTexCoords(Out.texCoords[CHANNEL1_TEXCOORD/2], CHANNEL1_TEXCOORD, textureUV1.xy);
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_2)
        setTexCoords(Out.texCoords[CHANNEL2_TEXCOORD/2], CHANNEL2_TEXCOORD, textureUV2.xy);
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_3)
        setTexCoords(Out.texCoords[CHANNEL3_TEXCOORD/2], CHANNEL3_TEXCOORD, textureUV3.xy);
    #endif

    setTexCoords(Out.texCoords[DIRT_TEXCOORD/2], DIRT_TEXCOORD, position.xz*In.mat.dirtUVScale.xy);
#else
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        setTexCoords(Out.texCoords[NOISE_TEXCOORD/2], NOISE_TEXCOORD, textureUV1.xy);
    #elif defined(TERRAIN_DETAIL_CHANNEL_2)
        setTexCoords(Out.texCoords[NOISE_TEXCOORD/2], NOISE_TEXCOORD, textureUV2.xy);
    #elif defined(TERRAIN_DETAIL_CHANNEL_3)
        setTexCoords(Out.texCoords[NOISE_TEXCOORD/2], NOISE_TEXCOORD, textureUV3.xy);
    #else
        // this should never happen
        setTexCoords(Out.texCoords[NOISE_TEXCOORD/2], NOISE_TEXCOORD, float2(0,0));
    #endif
#endif

setTexCoords(Out.texCoords[BLENDMAP_TEXCOORD/2], BLENDMAP_TEXCOORD, albedoTexCoord);
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float alphaScale;
]]>
            </CodeInjection>
            <CodeInjection position="VS_END">
<![CDATA[
Out.alphaScale = saturate((length(viewDir)-(In.mat.alphaBlendStartEnd.x))/(In.mat.alphaBlendStartEnd.x-In.mat.alphaBlendStartEnd.y));
]]>
            </CodeInjection>
            <CodeInjection position="FS_GLOBALS">
<![CDATA[
float4 blendMap;
float4 noisedBlendMap;
float3 steppedBlendMap;
#ifdef USE_GROUND_SHADER_COLOR
float dirt;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="START_FS">
<![CDATA[
float2 noiseTexCoord = In.vs.texCoords[0].xy;

float noise = tex2D(In.samplers.noiseMap, noiseTexCoord.xy).x;
globals.blendMap = tex2D(In.samplers.blendMap, getTexCoords(In, globals, BLENDMAP_TEXCOORD).xy).xyzw;
globals.noisedBlendMap = globals.blendMap*noise;

#if defined(TERRAIN_DETAIL_CHANNEL_1)
    globals.steppedBlendMap.x = (globals.noisedBlendMap.x > 0.1);
#else
    globals.steppedBlendMap.x = 0.0;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_2)
    globals.steppedBlendMap.y = (globals.noisedBlendMap.y > 0.1)*(1 - globals.steppedBlendMap.x);
#else
    globals.steppedBlendMap.y = 0.0;
#endif
#if defined(TERRAIN_DETAIL_CHANNEL_3)
    globals.steppedBlendMap.z = (globals.noisedBlendMap.z > 0.1)*(1 - (globals.steppedBlendMap.x+globals.steppedBlendMap.y));
    //globals.steppedBlendMap.z = (1 - (globals.steppedBlendMap.x+globals.steppedBlendMap.y));
#else
    globals.steppedBlendMap.z = 0.0;
#endif
#ifdef USE_GROUND_SHADER_COLOR
    globals.dirt = tex2D(In.samplers.noiseMap, getTexCoords(In, globals, DIRT_TEXCOORD)).z*1.2;

#endif
]]>
            </CodeInjection>
            <CodeInjection position="PARALLAX_MAPPING_FS">
<![CDATA[
#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
        float parallaxValue = 0.035*1.5;
        float height = getBumpHeight(In, globals);
        float2 offset = viewDir.xy * (height * 2*parallaxValue -parallaxValue);
        for (int i=0; i < NUM_TEXCOORDS; i++) {
            //if (i != BLENDMAP_TEXCOORD) { // do not disturb blendmap texcoords by parallax map
                addToTexCoords(In.vs.texCoords[i/2], i, offset);
            //}
        }
    #endif
#endif
]]>
            </CodeInjection>
            <CodeInjection position="POST_ALBEDO_FS">
<![CDATA[
#ifdef USE_GROUND_SHADER_COLOR
    albedo.xyz = float3(0,0,0);
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        #if defined(TERRAIN_DETAIL_CHANNEL_2) || defined(TERRAIN_DETAIL_CHANNEL_3)
            albedo.xyz += (tex2D(In.samplers.diffuseMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).xyz)*globals.steppedBlendMap.x;
        #else
            albedo.xyz += (tex2D(In.samplers.diffuseMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).xyz);
        #endif
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_2)
        #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_3)
            albedo.xyz += (tex2D(In.samplers.diffuseMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).xyz)*globals.steppedBlendMap.y;
        #else
            albedo.xyz += (tex2D(In.samplers.diffuseMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).xyz);
        #endif
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_3)
        #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
            albedo.xyz += (tex2D(In.samplers.diffuseMap3, getTexCoords(In, globals, CHANNEL3_TEXCOORD)).xyz)*globals.steppedBlendMap.z;
        #else
            albedo.xyz += (tex2D(In.samplers.diffuseMap3, getTexCoords(In, globals, CHANNEL3_TEXCOORD)).xyz);
        #endif
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_4)
        albedo.xyz = lerp(albedo.xyz, albedo.xyz*0.04, globals.noisedBlendMap.w);
    #endif
    albedo.xyz *= globals.dirt;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_NORMAL_FS">
<![CDATA[
#ifdef USE_GROUND_SHADER_COLOR
    #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_2)
        float3 myNormal = float3(0,0,0);
        #if defined(TERRAIN_DETAIL_CHANNEL_1)
            #if defined(TERRAIN_DETAIL_CHANNEL_2) || defined(TERRAIN_DETAIL_CHANNEL_3)
                myNormal += (tex2D(In.samplers.normalMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).xyz * 2.0 - 1.0)*globals.steppedBlendMap.x;
            #else
                myNormal += (tex2D(In.samplers.normalMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).xyz * 2.0 - 1.0);
            #endif
        #endif
        #if defined(TERRAIN_DETAIL_CHANNEL_2)
            #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_3)
                myNormal += (tex2D(In.samplers.normalMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).xyz * 2.0 - 1.0)*globals.steppedBlendMap.y;
            #else
                myNormal += (tex2D(In.samplers.normalMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).xyz * 2.0 - 1.0);
            #endif
        #endif
        #if defined(TERRAIN_DETAIL_CHANNEL_3)
            myNormal += float3(0,0,1)*globals.steppedBlendMap.z;
        #endif
        return normalize(myNormal);
    #else
        return normalize(In.vs.normal);
        //return float3(0, 1, 0);
    #endif
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_BUMP_HEIGHT_FS">
<![CDATA[
#ifdef USE_GROUND_SHADER_COLOR
    float myHeight = 0;
    #if defined(TERRAIN_DETAIL_CHANNEL_1)
        #if defined(TERRAIN_DETAIL_CHANNEL_2) || defined(TERRAIN_DETAIL_CHANNEL_3)
            myHeight += (tex2D(In.samplers.normalMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).a)*globals.steppedBlendMap.x;
        #else
            myHeight += (tex2D(In.samplers.normalMap1, getTexCoords(In, globals, CHANNEL1_TEXCOORD)).a);
        #endif
    #endif
    #if defined(TERRAIN_DETAIL_CHANNEL_2)
        #if defined(TERRAIN_DETAIL_CHANNEL_1) || defined(TERRAIN_DETAIL_CHANNEL_3)
            myHeight += (tex2D(In.samplers.normalMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).a)*globals.steppedBlendMap.y;
        #else
            myHeight += (tex2D(In.samplers.normalMap2, getTexCoords(In, globals, CHANNEL2_TEXCOORD)).a);
        #endif
    #endif
    return myHeight;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="FINAL_POS_FS">
<![CDATA[

float sum = (globals.steppedBlendMap.x+globals.steppedBlendMap.y+globals.steppedBlendMap.z)*In.vs.alphaScale;  //dot(globals.steppedBlendMap, globals.steppedBlendMap);

if (sum < 0.5) {
    discard;
}
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
