<?xml version="1.0" encoding="utf-8"?>
<CustomShader version="3">
    <Parameters>
        <Parameter name="RDT" target="RDT" type="float4" defaultValue="1.0 1.0 20.0 20.0" minValue="0.0 0.0 0.0 0.0" maxValue="1.0 1.0 50.0 50.0"/>
        <Parameter name="offsetUV" target="offsetUV" type="float4" defaultValue="0 0 0 0" minValue="-10.0 -10.0 -10.0 -10.0" maxValue="10.0 10.0 10.0 10.0"/>
        <Parameter name="uvCenterSize" target="uvCenterSize" type="float4" defaultValue="0.5 0.5 1.0 1.0" minValue="-1.0 -1.0 0.0 0.0" maxValue="1.0 1.0 50.0 50.0"/>
        <Parameter name="colorScale" target="colorScale" type="float4" defaultValue="0.8 0.55 0.055 1.0" minValue="0.0 0.0 0.0 0.0" maxValue="1.0 1.0 1.0 1.0"/>
        <!-- added parameter by 50keda -->
        <Parameter name="envFactor" target="envFactor" type="float4" defaultValue="1.0 1.0 1.0 0.0" minValue="0.0 0.0 0.0 -0.99" maxValue="5.0 5.0 5.0 1.0"/>
        <Parameter name="dirtColor" target="dirtColor" type="float4" defaultValue="0.21 0.1443 0.065 0.0" minValue="0.0 0.0 0.0 0.0" maxValue="1.0 1.0 1.0 0.0"/>
        <Parameter name="morphPosition" target="morphPosition" type="float4" defaultValue="-0.45 -0.915 0.5 0.1" minValue="-4.0 -4.0 0.0 0.0" maxValue="2.0 2.0 1.0 1.0"/>
    </Parameters>
    <Textures>
        <Texture name="DirtNmap" defaultColorProfile="linearRGB" defaultFilename="dirt_normal.dds"/>
    </Textures>
    <Variations>
        <Variation name="uvScroll"><![CDATA[
                #define UV_SCROLL       // Enables UV scrolling
]]></Variation>
        <Variation name="uvRotate"><![CDATA[
                #define UV_ROTATE       // Enables UV rotation
]]></Variation>
        <Variation name="Decal"><![CDATA[
                #define DECAL_RENDER    // Enables 2nd UV set for specular
]]></Variation>
        <Variation name="Window"><![CDATA[
                #define WINDOW          // should be used with akphaBlended material
]]></Variation>
        <Variation name="colorMask"><![CDATA[
                #define COLOR_MASK      // Enables colorPainting by mask from glossMap.a
]]></Variation>
    </Variations>
    <LodLevel startDistance="0">
        <CodeInjections>
            <CodeInjection position="MATERIALINFO"><![CDATA[
                /*
                R - NOT USED YET
                D - Dirt Amount
                T - Dirt Texture Tile
                */
                uniform float4 RDT;

                /*Slavo doplnil*/
                uniform float4 morphPosition;

#if defined( UV_SCROLL ) || defined( UV_ROTATE )
                uniform float4 offsetUV;
#endif
#if defined( UV_ROTATE )
                uniform float4 uvCenterSize;
#endif
#if defined( COLOR_MASK )
                uniform float4 colorScale;
#endif
        //----------------------------------
        // edit by 50keda
        //----------------------------------
        uniform float4 envFactor;
        uniform float4 dirtColor;
        //----------------------------------
        // end of edit by 50keda
        //----------------------------------
]]></CodeInjection>
            <CodeInjection position="SAMPLERS"><![CDATA[
sampler2D DirtNmap;
]]></CodeInjection>
            <CodeInjection position="FS_GLOBALS"><![CDATA[
                float4 gGloss;
                float  gAO;
                float  gDirt;
                float  maxSpecularIntensity;
]]></CodeInjection>
            <CodeInjection position="CONFIG_DEFINES"><![CDATA[
#if GPU_PROFILE < GPU_PROFILE_MEDIUM
                #if defined( REFLECTION_MAP_CUBE )
                                #undef REFLECTION_MAP_CUBE
                #endif
#endif

#if defined( DECAL_RENDER )
                // Remap gloss map lookups to our custom tex coord
                #define GLOSSMAP_TEXCOORD glossMapTexCoords2
#endif
]]></CodeInjection>
            <CodeInjection position="VS_OUTPUT"><![CDATA[
#if defined( DECAL_RENDER )
float2 glossMapTexCoords2 : TEXCOORDn;
#endif
]]></CodeInjection>
            <CodeInjection position="SAMPLERS"><![CDATA[
#if defined( UV_ROTATE )
float2 m_getUVRotationSinCos( )
{
                float mTime = offsetUV.z;
                float2 mSinCos;
                // compute sin and cos for this angle
                sincos( mTime, mSinCos.x, mSinCos.y );
                return mSinCos;
}
#endif
]]></CodeInjection>
            <CodeInjection position="POST_SET_TEXCOORDS_VS"><![CDATA[
#if defined( DECAL_RENDER )
                // Pass second UVSet to the Pixel Shader
                Out.glossMapTexCoords2 = convertDefaultTexCoords(In, In.texCoords1.xy);
#endif
#if defined( UV_ROTATE ) && defined( ALBEDO_MAP )
                float2 mOutgoingUV = getDefaultTexCoords(In);
                mOutgoingUV *= uvCenterSize.zw;
                float2 mRotationCenter = uvCenterSize.xy;
                mRotationCenter *= uvCenterSize.zw;
                float2 mSinCos = m_getUVRotationSinCos();
                // move the rotation center to the origin
                float2 mTmpUV = mOutgoingUV - mRotationCenter;
                // rotate the uv
                mOutgoingUV.x = dot( mTmpUV, float2( mSinCos.y, - mSinCos.x ) );
                mOutgoingUV.y = dot( mTmpUV, mSinCos.xy );
                // move the uv's back to the correct place
                mOutgoingUV += mRotationCenter;
                mOutgoingUV /= uvCenterSize.zw;
                Out.defaultTexCoords = mOutgoingUV;
#endif
#if defined( UV_SCROLL ) && defined( ALBEDO_MAP )
                float2 mUV = getDefaultTexCoords(In);
                mUV.xy += offsetUV.xy;
                Out.defaultTexCoords = mUV;
#endif
]]></CodeInjection>
            <CodeInjection position="GET_TANGENT_VS"><![CDATA[
#if defined( UV_ROTATE ) && defined( ALBEDO_MAP )
                float2 mSinCos = m_getUVRotationSinCos();

                float3 b = cross(In.normal.xyz, In.tangent.xyz)*In.tangent.w;
                float3 t = In.tangent.xyz;

                // Rotate tangent in oposite direction than uvs to compensate changed tangent space
                return float3(
                                t.x*mSinCos.y - b.x*mSinCos.x,
                                t.y*mSinCos.y - b.y*mSinCos.x,
                                t.z*mSinCos.y - b.z*mSinCos.x);
#endif
]]></CodeInjection>
            <CodeInjection position="GET_BITANGENT_VS"><![CDATA[
#if defined( UV_ROTATE ) && defined( ALBEDO_MAP )
                return cross(In.normal.xyz, getTangent(In))*In.tangent.w;
#endif
]]></CodeInjection>
            <CodeInjection position="START_FS"><![CDATA[
    #if defined( GLOSS_MAP )
    /*
    glossMap.r - roughness
    glossMap.g - ambient occlusion
    glossMap.b - dirt mask
    glossMap.a - color mask ( if enabled )
    */
                globals.gGloss = tex2D( glossMap, In.vs.GLOSSMAP_TEXCOORD).rgba;
                globals.gAO    = globals.gGloss.g;
                float texDirt  = 1 - globals.gGloss.b;
                globals.gDirt  = saturate( (texDirt*1.05 - (RDT.g - 0.5)) * 2 );
    #endif
                globals.maxSpecularIntensity = 0.5; // iron
]]></CodeInjection>
            <CodeInjection position="GET_NORMAL_FS"><![CDATA[
    #if defined( NORMAL_MAP )
                float3 mNormal   = tex2D( normalMap, In.vs.NORMALMAP_TEXCOORD ).xyz * 2.0 - 1.0;
                float3 mDirtNmap = tex2D( DirtNmap, float2( RDT.z, RDT.w ) * In.vs.NORMALMAP_TEXCOORD ).xyz * 2.0 - 1.0;
                return normalize( mNormal + float3(mDirtNmap.xy, 0.0) * (1 - globals.gDirt) );
    #endif
]]></CodeInjection>
            <CodeInjection position="POST_ALBEDO_FS"><![CDATA[
#if defined( SPECULAR ) && defined( GLOSS_MAP )
                #if defined( COLOR_MASK )
                                albedo.xyz = lerp( albedo.rgb, albedo.rgb * colorScale.rgb, globals.gGloss.a );
                #endif
                #if defined( WINDOW )
                                albedo.xyz += clamp( 0.65 *( 1-globals.gDirt ), 0.0, 1.0 );
                #else
                                float3 mDirtColor = dirtColor.rgb; // HardCoded Dirt Color
                                albedo.xyz = lerp( mDirtColor, albedo.xyz, globals.gDirt); // DirtColor lerp
                #endif
                albedo.xyz *= globals.gAO; // Multiply AO for DIFFUSE
#endif
]]></CodeInjection>
            <CodeInjection position="POST_GLOSS_COLOR_FS"><![CDATA[
#if defined( SPECULAR ) && defined( GLOSS_MAP )
                specularCosPower = max(cCosPower * globals.gGloss.r * globals.gDirt, 0.1);
                glossColor.xyz = (float3)(globals.gGloss.r*globals.gDirt);
                glossColor.xyz *= globals.maxSpecularIntensity*globals.gAO; // Multiply AO for SPECULAR
                reflectionGlossColor = glossColor;
#endif
]]></CodeInjection>
            <CodeInjection position="GET_REFLECTION_COLOR_FS"><![CDATA[
#if GPU_PROFILE >= GPU_PROFILE_MEDIUM
                #if defined( REFLECTION_MAP_2D ) || defined( REFLECTION_MAP_CUBE )
                                float3 mResult = getReflectionColorTex( In, globals, normal, viewDir );
                                #if defined( WINDOW )
                                                mResult *= getFresnel( facing, cReflectionCoeff , 1.0 );
                                #else
                                                mResult *= globals.maxSpecularIntensity;
                                                #if defined( REFLECTION_MAP_CUBE )
                                                                float3 mTintColorTop    = float3( 0.217, 0.612, 1.00 ); // hard-coded blue tint color
                                                                float3 mTintColorBottom = float3( 0.058, 0.040, 0.03 ); // hard-coded ground tint color
                                                                // cReflectionCoeff == refractiveIndex - comes from xml file
                                                                // if 1 - fresnel default
                                                                // if 0 - fresnel more visible
                                                                float mFresnelBias = cReflectionCoeff;
                                                                float mWorldNormalY = normal.y;
                                                                #if !defined(_NO_TANGENTSPACE)
                                                                                mWorldNormalY = In.vs.worldNormal.y;
                                                                #endif
                                                                mResult += lerp( mTintColorBottom, mTintColorTop , clamp(mWorldNormalY, 0.0, 1.0 ) ) * getFresnel( facing, mFresnelBias , 4.0 );
                                                #endif
                                #endif

        //----------------------------------
        // edit by 50keda
        //----------------------------------
        mResult *= envFactor.rgb;
        //----------------------------------
        // end of edit by 50keda
        //----------------------------------

                #if defined( GLOSS_MAP )
                                float mReflectionIntensityMap = 1.0;
                                float mDirt = 0.0;
                                #if defined( WINDOW )
                                                mReflectionIntensityMap = 1.0;
                                                mDirt = globals.gDirt;
                                #else
                        //----------------------------------
                        // edit by 50keda
                        //----------------------------------
                                                mReflectionIntensityMap = (min(max(envFactor.a, globals.gDirt), 1.0) - envFactor.a) * (1.0 / (1.001 - envFactor.a)) * globals.gGloss.r;
                        mDirt = 1.0; //globals.gDirt * ( 1 - clamp(RDT.g, 0.0, 0.9));
                        //----------------------------------
                        // end of edit by 50keda
                        //----------------------------------
                                #endif
                                mReflectionIntensityMap *= mDirt;
                                mResult *= mReflectionIntensityMap;
                                mResult *= globals.gAO; // Multiply AO for REFLECTION
                #endif
                                float envScale = 0.2;
                                #if ( NUM_DIRECTIONAL_LIGHTS > 0 )
                                                float3 reflDir =  reflect(-viewDir.xyz, normal.xyz);
                                                float directionalEnvMapBias = 0.5; // Fresnel Visisbility in Shadowed Area
                                                mResult *= dot(normalize(reflDir), getLightVector(In, globals, 0)) * ( 1 - directionalEnvMapBias ) + directionalEnvMapBias;
                                                envScale = diffuseColors[0].y;
                                #endif
                                mResult *= envScale;
                                mResult += oColor.xyz;  // ADD previously calculated diffuse and specular
                                res = mResult;
                #endif
#endif
]]></CodeInjection>
            <CodeInjection position="FINAL_POS_FS"><![CDATA[
#if defined( ALPHA_BLENDED )
                #if defined( WINDOW )
                                oColor.a += clamp( 0.65*(1-globals.gDirt), 0.0, 1.0 );
                #endif
#endif
]]></CodeInjection>
            <CodeInjection position="GET_POSITION_VS"><![CDATA[
                float3 localY = mul(float3(0,1,0), (float3x3)modelMatrix);
                localY.x = 0;
                localY = normalize(localY);

                float3 mDeformedPosition = In.position.xyz;
                float localYPosition = dot(In.position, localY);

                float mBlendIn  = morphPosition.x;
                float mBlendOut = morphPosition.y;

                float mMaskBase = saturate((localYPosition - mBlendIn) / ( mBlendOut - mBlendIn ));
                float mMask = sin( mMaskBase * 3.14159 );

                float mPushOutRatio = 0.5; //morphPosition.z;
                float mPushUp  = morphPosition.w;
                float mBound   = abs( mBlendOut - mBlendIn );
                mPushUp = clamp( mPushUp, 0.0, mBound );
                float mPushOut = mPushUp * mPushOutRatio;

                mDeformedPosition.x += mPushOut * mMask * sign(In.position.x);
                mDeformedPosition += localY * (mPushUp * mMaskBase);
                return float4( mDeformedPosition, 1.0 );

]]></CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
