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

<CustomShader version="4">
    <Parameters>
        <Parameter name="bumpSpeedScale" target="bumpSpeedScale" type="float4" />
        <Parameter name="reflectionAmount" target="reflectionAmount" type="float4" />
        <Parameter name="underwaterFogColor" target="underwaterFogColor" type="float4" />
    </Parameters>
    <Textures>
        <Texture name = "mWaterPlantsMask"   defaultColorProfile = "linearRGB"   defaultFilename = "../maps/textures/sosnovka/waterPlanes_diffuse.png"/>
        <Texture name = "mWaterPlant01"    defaultColorProfile = "sRGB"   defaultFilename = "../maps/textures/sosnovka/duckweed_diffuse.png"/>
    </Textures>
    <LodLevel startDistance="0" subsequentPassForceMode="ignore">
        <CodeInjections>
           <CodeInjection position="LIB_FUNCTION_FS">
<![CDATA[

float getWaterDepth(FS_INPUT In, FS_GLOBALS globals)
{
    float screenDepth = In.vs.screenPosZ / In.vs.screenPosW * 0.5 + 0.5;
    float screenDepthLinear = convertDepthToEyeZ(screenDepth);
    float sceneDepthLinear = convertDepthToEyeZ(getSceneDepth(In, globals));
    return (sceneDepthLinear - screenDepthLinear);
}

float getNormalizedWaterDepth(FS_INPUT In, FS_GLOBALS globals, float depthScale)
{
    return saturate(getWaterDepth(In, globals)*depthScale);
}

float calcFogExpFactor(float fogDensity, float distance)
{    
    // calculate exponential fog factor
    float fogFactor = (fogDensity * distance);
    fogFactor = saturate(exp(-fogFactor)); // e^-(dist*density) or e^-(dist*density)^2    
    return fogFactor;
}

]]>
            </CodeInjection>        
            <CodeInjection position="NUM_TEXCOORDS">
<![CDATA[
// only allow directional lights, specular only
#define NUM_DIFFUSE_LIGHTS 0
#define NUM_POINT_LIGHTS 0
#define NUM_SPOT_LIGHTS 0

#if defined(DIFFUSE)
#undef DIFFUSE
#endif

// for low spec no lights at all
//#ifdef LOWSPEC
//#define NUM_DIRECTIONAL_LIGHTS 0
//#endif


#if defined(REFRACTION_MAP) && defined(LIGHTING) && defined(NORMAL_MAP)
#define WATER_RENDERING
#endif
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float2 normalMapTexCoord0  : TEXCOORDn;
float2 normalMapTexCoord1  : TEXCOORDn;
float2 normalMapTexCoord2  : TEXCOORDn;
float2 albedoMapTexCoord0  : TEXCOORDn;
]]>
            </CodeInjection>
            <CodeInjection position="MATERIALINFO">
<![CDATA[
#if defined(WATER_RENDERING)
    uniform float4 bumpSpeedScale;
    uniform float4 reflectionAmount;
    uniform float4 underwaterFogColor;
#endif
]]>
            </CodeInjection>
            <CodeInjection position = "SAMPLERS">
<![CDATA[
sampler2D mWaterPlantsMask;
sampler2D mWaterPlant01;
]]>
            </CodeInjection>
            <CodeInjection position="POST_SET_TEXCOORDS_VS">
<![CDATA[
#if defined(WATER_RENDERING)
    float textureScale = bumpSpeedScale.z;
    float2 bumpSpeed = bumpSpeedScale.xy*textureScale;

    float2 translation=float2(cTime_s*bumpSpeed.x, 0);
    float2 translation2=float2(translation.x, cTime_s*bumpSpeed.y);

    float2 texCoords=In.position.xz*textureScale;

    Out.normalMapTexCoord0 = texCoords.xy+translation;
    Out.normalMapTexCoord1 = texCoords.xy*2.0+translation*4.0;
    Out.normalMapTexCoord2 = texCoords.xy*4.0-translation2;

    Out.albedoMapTexCoord0 = In.position.xz * bumpSpeedScale.w;
#endif
]]>
            </CodeInjection>
            <CodeInjection position = "FS_GLOBALS">
<![CDATA[
    float  mWaterMask01;
    float4 mWP01;
    float2 mUVdistort;
    float  mWaterMaskGlobal;
]]>
            </CodeInjection>

            <CodeInjection position = "START_FS">
<![CDATA[
    globals.mUVdistort = float2(0.0,0.0);
#if defined(WATER_RENDERING)
    globals.mUVdistort      = getTangentSpaceNormal(In, globals).xy;
#endif
    globals.mUVdistort     *= 0.025;
    float4 mWaterMask       = tex2D( mWaterPlantsMask , 0.1*globals.mUVdistort + In.vs.defaultTexCoords.xy ).rgba;
    globals.mWP01           = tex2D( mWaterPlant01 , 0.1*globals.mUVdistort + In.vs.albedoMapTexCoord0 ).rgba;
    globals.mWaterMask01    = saturate( ( mWaterMask.r - globals.mWP01.a ) / ( 0.25 ) );
    globals.mWaterMaskGlobal = saturate( 1 -  globals.mWaterMask01 );
]]>
            </CodeInjection>
            <CodeInjection position = "POST_GLOSS_COLOR_FS">
<![CDATA[
    metalness = 0;//metalness *= globals.mWaterMaskGlobal;
    float cosPower = 1000 * globals.mWaterMaskGlobal;
    roughness = sqrt(sqrt(2.0/(cosPower+2.0)));
]]>
            </CodeInjection>
            <CodeInjection position="GET_UNNORMALIZED_TANGENT_SPACE_NORMAL_FS">
<![CDATA[
#if defined(WATER_RENDERING)
    // sum normal maps
    // sample from 3 different points so no texture repetition is noticeable
    float3 t0 = tex2D(normalMap, In.vs.normalMapTexCoord0).xyz;
    float3 t1 = tex2D(normalMap, In.vs.normalMapTexCoord1).xyz;
    float3 t2 = tex2D(normalMap, In.vs.normalMapTexCoord2).xyz;
    float3 mResult = (t0.xyz + t1.xyz + t2.xyz) - 1.5;    
    mResult = lerp( float3( 0,0,1 ) , mResult, cShared0 );
    return mResult;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="POST_ALBEDO_FS">
<![CDATA[
#if defined(WATER_RENDERING)
    albedo          = float4(0, 0, 0, 1);                    
    albedo.rgb      = globals.mWP01.rgb * globals.mWaterMask01 *( 1- globals.mWaterMaskGlobal );
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_REFRACTION_COLOR_TEX_FS">
<![CDATA[
#if defined(WATER_RENDERING)
    float depth = getNormalizedWaterDepth(In, globals, 1.0/2.0);
    float2 finalCoord2 = In.vs.screenPos.xy/In.vs.screenPosW;
    finalCoord2 += globals.mWaterMaskGlobal*(tangentSpaceNormal.xy*cRefractionBumpScale*depth);
#if defined(FLIP_TEXCOORD_Y)
	finalCoord2.y = 1-finalCoord2.y;
#endif
    return tex2D(refractionMap, finalCoord2).xyz;
#endif

]]>
            </CodeInjection>
            <CodeInjection position="GET_REFLECTION_REFRACTION_FACTOR_FS">
<![CDATA[
#if defined(WATER_RENDERING)
{
    float fresnel = getFresnel(facing, cReflectionCoeff, 5.0);
    fresnel = saturate(fresnel * reflectionAmount.x*globals.mWaterMaskGlobal);
    reflectionFactor = fresnel;
    refractionFactor = 1-fresnel;
}
#endif
]]>
            </CodeInjection>            
            <CodeInjection position="GET_REFRACTION_COLOR_FS">
<![CDATA[
{
#if defined(WATER_RENDERING)
    float softIntersect =  getNormalizedWaterDepth(In, globals, 1.0/4.0);
    float fogDepth = calcFogExpFactor(0.5, getWaterDepth(In, globals));
    float3 refractionColor = getRefractionColorTex(In, globals, specularColor, roughness, fresnelStrength, viewDir, normal, tangentSpaceNormal);
    refractionColor = lerp( underwaterFogColor.xyz, refractionColor, fogDepth);
    float3 mResult = lerp(refractionColor, oColor.xyz + refractionColor*refractionFactor, softIntersect);
    return mResult;
#endif
}
]]>
            </CodeInjection>
            <CodeInjection position="GET_REFLECTION_COLOR_TEX_FS">
<![CDATA[
#if defined(WATER_RENDERING)
    float2 finalCoord2 = In.vs.screenPos.xy/In.vs.screenPosW;
    finalCoord2 += globals.mWaterMaskGlobal*tangentSpaceNormal.xy*cReflectionBumpScale;
    return tex2D(reflectionMap, finalCoord2).xyz;
#endif
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>