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

<CustomShader version="3">
    <Parameters>
        <Parameter name = "param"    target = "param"    type = "float4" defaultValue = "0.0 0.0 0.0 1.0" minValue = "-5 -5 -5 0.01" maxValue = "5 5 5 2.0"/>
        <Parameter name = "exhaustColor"    target = "exhaustColor"    type = "float4" defaultValue = "0.5 0.5 0.5 1.0" minValue = "0 0 0 0" maxValue = "1 1 1 10"/>
    </Parameters>
    <Textures>
        <Texture name = "mCloudMap" defaultColorProfile = "linearRGB" defaultFilename = "../textures/fx_clouds01_diffuse.png"/>
    </Textures>
    <Variations>
        <Variation name = "SCALE_Y_ONLY">
<![CDATA[
    #define SCALE_Y_ONLY       // Allows only Y axis scale 
]]>
        </Variation>
    </Variations>
    <LodLevel startDistance="0" alphaForceMode = "use">
        <CodeInjections>
            <CodeInjection position = "MATERIALINFO">
<![CDATA[
    /*
    param.x = Rx - rotate along ZY
    param.y = Rz - rotate along XY
    param.z = not used
    param.a = global scale
    */
    uniform float4 param;
    uniform float4 exhaustColor;
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float2 defaultTexCoords2 : TEXCOORDn;
]]>
            </CodeInjection>
            <CodeInjection position="POST_SET_TEXCOORDS_VS">
<![CDATA[
    // Pass second UVSet to the Pixel Shader
    Out.defaultTexCoords2 = convertDefaultTexCoords(In, In.texCoords1.xy);
    // =================================
]]>
            </CodeInjection>
            <CodeInjection position="GET_POSITION_VS">
<![CDATA[
//         Ry                                   Rx                               Rz
// [ cos(time)   0   -sin(time)]      [ 1        0        0      ]     [ cos(time) -sin(time)  0]
// [    0        1       0     ]      [ 0 cos(time)    -sin(time)]     [ sin(time)  cos(time)  0]
// [ sin(time)   0    cos(time)]      [ 0 sin(time)     cos(time)]     [ 0             0       1]
//          Rz                          Rx
// [ cos(z) -sin(z)  0]  [ 1        0        0     ]  [ cos(z)  -sin(z)*cos(x)  -sin(z)*-sin(x) ]
// [ sin(z)  cos(z)  0]  [ 0      cos(x)    -sin(x)]  [ sin(z)   cos(z)*cos(x)   cos(z)*-sin(x) ]
// [ 0       0       1]  [ 0      sin(x)     cos(x)]  [ 0        sin(x)               cos(x)    ]

    // WOBBLING
    float  mSkinning    = saturate( sqrt( In.texCoords0.y ) ); // TODO conversion needed?
    float  mRx          = param.x;
    float  mRz          = param.y;
    float  mAmpl        = 0.25;
    float3 mScale      = float3( param.a, param.a, param.a);
#if defined( SCALE_Y_ONLY )
    mScale = float3( 1.0, mScale.y, 1.0 );
#endif
    float2 mSinCos;

    sincos( 100 * In.texCoords0.y - 20 * cTime_s, mSinCos.x, mSinCos.y );
    float3 mWobblingPosition = mAmpl * In.normal.xyz * (  mSinCos.x + mSinCos.y ) * mSkinning;

    // ROTATION
    float3 mSourcePosition      = (In.position.xyz + mWobblingPosition.xyz)*mScale;

    autoclear float2 mSinCosX;
    autoclear float2 mSinCosZ;
    sincos( mRx * mSkinning, mSinCosX.x, mSinCosX.y );
    sincos( mRz * mSkinning, mSinCosZ.x, mSinCosZ.y );
    float3 mResultPosition;
    mResultPosition.x = dot( mSourcePosition.xyz, float3( mSinCosZ.y, -mSinCosZ.x * mSinCosX.y, -mSinCosZ.x * -mSinCosX.x) );
    mResultPosition.y = dot( mSourcePosition.xyz, float3( mSinCosZ.x,  mSinCosZ.y * mSinCosX.y,  mSinCosZ.y * -mSinCosX.x ) );
    mResultPosition.z = dot( mSourcePosition.yz,  float2( mSinCosX.x,  mSinCosX.y ) );

    return float4( mResultPosition, 1.0 );
]]>
            </CodeInjection>
            <CodeInjection position="GET_NORMAL_VS">
<![CDATA[
    float  mSkinning    = saturate( sqrt( In.texCoords0.y ) ); // TODO conversion needed?
    float  mRx          = param.x;
    float  mRz          = param.y;

    // ROTATION
    float3 mSourcePosition      = In.normal.xyz;

    autoclear float2 mSinCosX;
    autoclear float2 mSinCosZ;
    sincos( mRx * mSkinning, mSinCosX.x, mSinCosX.y );
    sincos( mRz * mSkinning, mSinCosZ.x, mSinCosZ.y );
    float3 mResultPosition;
    mResultPosition.x = dot( mSourcePosition.xyz, float3( mSinCosZ.y, -mSinCosZ.x * mSinCosX.y, -mSinCosZ.x * -mSinCosX.x) );
    mResultPosition.y = dot( mSourcePosition.xyz, float3( mSinCosZ.x,  mSinCosZ.y * mSinCosX.y,  mSinCosZ.y * -mSinCosX.x ) );
    mResultPosition.z = dot( mSourcePosition.yz,  float2( mSinCosX.x,  mSinCosX.y ) );

    return mResultPosition;
]]>
            </CodeInjection>
            <CodeInjection position = "SAMPLERS">
<![CDATA[
sampler2D mCloudMap;
]]>
            </CodeInjection>
            <CodeInjection position = "FS_GLOBALS">
<![CDATA[
    float gAlphaValue;
    float gRefractionValue;
    float gRefractionBlendingRatio;
]]>
            </CodeInjection>
            <CodeInjection position = "START_FS">
<![CDATA[
#if defined( VERTEX_COLOR )
    #undef VERTEX_COLOR
#endif

    float2 mSpeed   = float2( 0.1, -1.5 ) * cTime_s;
    float2 mUVscale = float2( 0.75, 1.75 );
    float2 mUVOrig1  = In.vs.ALBEDOMAP_TEXCOORD;
    float2 mUVOrig2  = In.vs.defaultTexCoords2;
    float4 mUV1, mUV2;
    mUV1.rg   =        mUVscale * ( mUVOrig1 + mSpeed );
    mUV1.ba   = 1.33 * mUVscale * ( mUVOrig1 + mSpeed );
    mUV2.rg   =        mUVscale * ( mUVOrig2 + mSpeed );
    mUV2.ba   = 1.33 * mUVscale * ( mUVOrig2 + mSpeed );
    float mAlphaValue1, mAlphaValue2;

    float mAlphaGradient = 1 - mUVOrig1.y;

    float2 mA           = tex2D( mCloudMap, mUV1.rg ).ba;
    float2 mB           = tex2D( mCloudMap, mUV1.ba ).ba;

    float2 mC           = tex2D( mCloudMap, mUV2.rg ).ba;
    float2 mD           = tex2D( mCloudMap, mUV2.ba ).ba;

    mAlphaValue1        = mA.x * mB.x * mA.y * mB.y;
    mAlphaValue1        = clamp( 1.0 * mAlphaValue1, 0.0 , 1.0 );

    mAlphaValue2        = mC.x * mD.x * mC.y * mD.y;
    mAlphaValue2        = clamp( 1.0 * mAlphaValue2, 0.0 , 1.0 );

    globals.gAlphaValue = lerp( mAlphaValue1, mAlphaValue2, In.vs.vertexColor.r );
    
    globals.gRefractionValue    = globals.gAlphaValue * (mAlphaGradient + 0.2) * 0.8;
    globals.gAlphaValue *= mAlphaGradient * mAlphaGradient;
    
    globals.gRefractionBlendingRatio = 0.25;
]]>
            </CodeInjection>
            <CodeInjection position="POST_ALBEDO_FS">
<![CDATA[
    albedo = exhaustColor;
    float mAlphaFresnel      = 1 - facing;
    mAlphaFresnel            *= mAlphaFresnel;
    globals.gAlphaValue      *= mAlphaFresnel;
    globals.gRefractionValue *= mAlphaFresnel;
]]>
            </CodeInjection>
            <CodeInjection position="GET_REFRACTION_COLOR_FS">
<![CDATA[
    refractionFactor = (1-oColor.a)*globals.gRefractionBlendingRatio;
]]>
            </CodeInjection>
            <CodeInjection position="GET_REFRACTION_COLOR_TEX_FS">
<![CDATA[
#if defined( REFRACTION_MAP )
    float2 mFinalCoord = In.vs.reflRefrCoord.xy/In.vs.reflRefrCoord.w;
    mFinalCoord += 0.08 * globals.gRefractionValue;
    #if defined(FLIP_TEXCOORD_Y)
        mFinalCoord.y = 1 - mFinalCoord.y;
    #endif
    return tex2D( refractionMap, mFinalCoord ).xyz;
#endif
    return float3(0,0,0);
]]>
            </CodeInjection>
            <CodeInjection position="POST_GLOSS_COLOR_FS">
<![CDATA[
#if defined( SPECULAR ) && defined( ALPHA_BLENDED )
    #undef SPECULAR // Disable specular color
#endif
]]>
            </CodeInjection>
            <CodeInjection position="ALPHA_FS">
<![CDATA[
#if defined( ALPHA_BLENDED )
    oColor.a = saturate(exhaustColor.a*globals.gAlphaValue);
#endif

]]>
            </CodeInjection>
            <CodeInjection position="FINAL_POS_FS">
<![CDATA[
    // The final blending should be:
    // (rgbOut)   +   (refraction*gRefractionBlendingRatio + oldRgb*(1-gRefractionBlendingRatio)) * (1-a)
    // Reformulate to match the hardware blending (rgbOut'  +  oldRgb * (1-a'):
    // rgbOut' = rgbOut + refraction*gRefractionBlendingRatio*(1-a)
    // a' = (1-gRefractionBlendingRatio)*a + gRefractionBlendingRatio

    oColor.a = (1-globals.gRefractionBlendingRatio)*oColor.a + globals.gRefractionBlendingRatio;

#if defined( ALPHA_BLENDED )/*
    oColor.xyz *= 0.001;
    oColor.xyz += globals.gAlphaValue;
    //oColor.xyz +=  In.vs.vertexColor.rgb ;
    oColor.a = 1;*/
#endif
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
