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

<!--
Edit by Ifko[nator]

Date: 18.07.2017

Added support for light beams witch now also can blinkig
-->

<CustomShader version="3">
    <Parameters>
		<Parameter name="blinkOffset"  target="blinkOffset"  type="float4" defaultValue="0 0 0 0"   			minValue="0 0 0 0"  				maxValue="1 1 1 1"/>
		<Parameter name="UVScaleSpeed" target="UVScaleSpeed" type="float4" defaultValue="1.0 2.0 0.005 -0.001" 	minValue="-10.0 -10.0 -10.0 -10.0" 	maxValue="10.0 10.0 10.0 10.0"/>
        <Parameter name="colorScale"   target="colorScale"   type="float4" defaultValue="1.0 1.0 1.0 1.0" 		minValue="0.0 0.0 0.0 0.0" 			maxValue="1.0 1.0 1.0 1.0"/>
    </Parameters>
	<Textures>
        <Texture name="mistNmap" defaultColorProfile="linearRGB" defaultFilename="../shared/mist_diffuse.png"/>
    </Textures>
    <Variations>
        <Variation name = "STATIC_LIGHT">
<![CDATA[
    #define STATIC_LIGHT
]]>
        </Variation>
        <Variation name = "STATIC_LIGHT_PATTERN">
<![CDATA[
    #define ENABLE_PATTERN
    #define STATIC_LIGHT
]]>
        </Variation>
        <Variation name = "STATIC_TURNLIGHT">
<![CDATA[
    #define STATIC_TURNLIGHT
]]>
        </Variation>
        <Variation name = "STATIC_TURNLIGHT_PATTERN">
<![CDATA[
    #define ENABLE_PATTERN
    #define STATIC_TURNLIGHT
]]>
        </Variation>
        <Variation name = "BILLBOARD">
<![CDATA[
    #define BILLBOARD
]]>
        </Variation>
        <Variation name = "BILLBOARD_TURNLIGHT">
<![CDATA[
    #define BILLBOARD_TURNLIGHT
]]>
        </Variation>
        <Variation name = "BILLBOARD_BEACON">
<![CDATA[
    #define BILLBOARD_BEACON
]]>
        </Variation>
        <Variation name = "BILLBOARD_360">
<![CDATA[
    #define BILLBOARD_360
]]>
        </Variation>
		<Variation name="TOP_DOWN">
<![CDATA[
    #define TOP_DOWN
]]>
		</Variation>
		<Variation name="TOP_DOWN_STATIC_TURNLIGHT">
<![CDATA[
    #define TOP_DOWN_STATIC_TURNLIGHT
]]>
		</Variation>
		<Variation name="LIGHT_BEAM">
<![CDATA[
    #define LIGHT_BEAM
]]>
		</Variation>
		<Variation name="LIGHT_BEAM_STATIC_TURNLIGHT">
<![CDATA[
    #define LIGHT_BEAM_STATIC_TURNLIGHT
]]>
		</Variation>
    </Variations>
    <LodLevel startDistance="0" alphaForceMode = "use">
        <CodeInjections>
			<CodeInjection position="SAMPLERS">
<![CDATA[
sampler2D mistNmap;
]]>
			</CodeInjection>
            <CodeInjection position = "MATERIALINFO">
<![CDATA[
#if defined( BILLBOARD_TURNLIGHT ) || defined( STATIC_TURNLIGHT ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
    uniform float4 blinkOffset;
	
#endif

uniform float4 UVScaleSpeed;
uniform float4 colorScale;
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float mVisScale : TEXCOORDn;
float2 centerScreenPos : TEXCOORDn;
float centerScreenPosZ : TEXCOORDn;
float centerScreenPosW : TEXCOORDn;

#if defined( TOP_DOWN ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
float2 albedoMapTexCoords2 : TEXCOORDn;
#endif
]]>
            </CodeInjection>
			<CodeInjection position="POST_SET_TEXCOORDS_VS"><![CDATA[
#if defined( TOP_DOWN ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
    // Pass second UVSet to the Pixel Shader
    Out.albedoMapTexCoords2 = convertDefaultTexCoords( In, In.texCoords1.xy );
#endif
]]></CodeInjection>
            <CodeInjection position="POST_GET_WORLD_POSE_VS">
<![CDATA[
    float3 camToPos = float3(modelMatrix[0][3], modelMatrix[1][3], modelMatrix[2][3]);
    float3 negDirVector = normalize(camToPos);
    float camFacing = -dot(negDirVector, normalize(float3(modelMatrix[0][2], modelMatrix[1][2], modelMatrix[2][2])));
#if defined( BILLBOARD ) || defined( BILLBOARD_TURNLIGHT ) || defined( BILLBOARD_BEACON ) || defined( BILLBOARD_360 )
    float3   mPosition = position.xyz;
    #if defined( BILLBOARD_BEACON )
        mPosition *= saturate(camFacing);  // scale based on cameraVector
    #endif

    float3 upVector = float3(invViewMatrix[0][1], invViewMatrix[1][1], invViewMatrix[2][1]);
    float3 sideVector = normalize(cross(negDirVector, upVector));
    upVector = cross(sideVector, negDirVector);

    // Allow scaling
    sideVector *= length(float3(modelMatrix[0][0], modelMatrix[1][0], modelMatrix[2][0]));
    upVector *= length(float3(modelMatrix[0][1], modelMatrix[1][1], modelMatrix[2][1]));

    worldPosition = camToPos+upVector*mPosition.y + sideVector*mPosition.x;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="VS_END">
<![CDATA[
    float visScale = 1.0;
#if defined( BILLBOARD ) || defined( BILLBOARD_TURNLIGHT ) || defined( BILLBOARD_BEACON )
    float fadeFactor = saturate( camFacing * 6 );
    #if defined( BILLBOARD_BEACON )
        fadeFactor = saturate( camFacing );
    #endif
    visScale *= fadeFactor;
#endif
#if defined( BILLBOARD_TURNLIGHT ) || defined( STATIC_TURNLIGHT ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
    // slower blinking + variation to achieve different ratio between on and off state
    float pi = 3.14159265359;
    visScale *= saturate(cos( 7.0 * cTime_s + 2 * pi * blinkOffset.x ) + 0.2);
#endif
#if (defined( BILLBOARD ) || defined( BILLBOARD_TURNLIGHT ) || defined( BILLBOARD_BEACON ) || defined( BILLBOARD_360 )) && GPU_PROFILE >= GPU_PROFILE_HIGH && defined(ALPHA_BLENDED)
    Out.position.z = min(Out.position.z, -Out.position.w);
    float4 centerScreenPos = mul(viewProjMatrix, float4(camToPos, 1));
    Out.centerScreenPos = centerScreenPos.xy*0.5 + 0.5*centerScreenPos.w;
    Out.centerScreenPosZ = centerScreenPos.z;
    Out.centerScreenPosW = centerScreenPos.w;
#endif
    Out.mVisScale = visScale;
    // TODO
    //Out.position.z -= 0.05;
]]>
            </CodeInjection>
            <CodeInjection position="POST_GLOSS_COLOR_FS">
<![CDATA[
#if defined( SPECULAR ) && defined( ALPHA_BLENDED )
    #undef SPECULAR // Disable specular color for alphaBlended billboards
#endif
]]>
            </CodeInjection>
            <CodeInjection position="EMISSIVE_FS">
<![CDATA[
#if defined( ALPHA_BLENDED )
    #if defined( STATIC_LIGHT ) || defined( STATIC_TURNLIGHT ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
        #if defined( VERTEX_COLOR )
            #if defined( ENABLE_PATTERN )
                emissiveColor.rgb *= In.vs.vertexColor.rgb;
                emissiveColor.rgb *= 2;
            #else
                emissiveColor.rgb = 0.50 * In.vs.vertexColor.rgb;
            #endif
        #endif
    #endif
    #if defined( STATIC_TURNLIGHT ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
        emissiveColor.rgb  *= In.vs.mVisScale;
    #endif
#endif

#if defined( EMISSIVE_MAP ) || defined( LIGHT_BEAM ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
   emissiveColor.rgb *= colorScale.rgb;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="ALPHA_FS">
<![CDATA[
#if defined( ALPHA_BLENDED )
    alpha = 1;
    #if defined(BILLBOARD) || defined(BILLBOARD_TURNLIGHT) || defined(BILLBOARD_BEACON)
        alpha *= In.vs.mVisScale;
    #endif

    #if (defined( BILLBOARD ) || defined( BILLBOARD_TURNLIGHT ) || defined( BILLBOARD_BEACON ) || defined( BILLBOARD_360 )) && GPU_PROFILE >= GPU_PROFILE_HIGH
    {
        float screenDepth = In.vs.centerScreenPosZ / In.vs.centerScreenPosW * 0.5 + 0.5;
        float2 coords = In.vs.centerScreenPos.xy / In.vs.centerScreenPosW;

        #if defined(FLIP_TEXCOORD_Y)
            coords.y = 1-coords.y;
        #endif

        float2 sampleOffset = 4.0/viewportSize.xy;

        float sceneDepth = tex2D(sceneDepthMap, coords).x;
        float sceneDepth0 = tex2D(sceneDepthMap, coords + float2(0.0, -sampleOffset.y)).x;
        float sceneDepth1 = tex2D(sceneDepthMap, coords + float2(0.0,  sampleOffset.y)).x;
        float sceneDepth2 = tex2D(sceneDepthMap, coords + float2(-sampleOffset.x, 0.0)).x;
        float sceneDepth3 = tex2D(sceneDepthMap, coords + float2( sampleOffset.x, 0.0)).x;

        float maxSceneDepth = max(max(max(sceneDepth0, sceneDepth1), max(sceneDepth2, sceneDepth3)), sceneDepth);

        alpha *= (screenDepth < maxSceneDepth);
    }
    #endif
#endif

#if defined( LIGHT_BEAM ) || defined( TOP_DOWN ) || defined( LIGHT_BEAM_STATIC_TURNLIGHT ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
	float  mMist = 1.0;
    float  mPixelDepth = 1.0;
    float2 mSpeed   = UVScaleSpeed.zw * cTime_s;
    float2 mUVscale = UVScaleSpeed.xy ;
    float4 mA = tex2D( mistNmap, mUVscale * ( 1.00 * In.vs.ALBEDOMAP_TEXCOORD + mSpeed ) ).rgba;
    // ------------------------------------------------
    mMist = mA.g * mA.b + mA.r;
    mMist = clamp( mMist, 0.0 , 1.0 );
    // ------------------------------------------------
    float mFacing       = max(dot(viewDir, normal),0 );
    float mGradient     = In.vs.ALBEDOMAP_TEXCOORD.y;
    float mFinalAlpha   = 1.0;
    
    #if defined( TOP_DOWN ) || defined( TOP_DOWN_STATIC_TURNLIGHT )
        float mSphere   = 1 - length( In.vs.ALBEDOMAP_TEXCOORD.xy - float2(0.5, 0.5)) * 1.41421356237;
        mSphere         = pow( mSphere, 4 );
        mFinalAlpha     = mSphere;
        // --------------------------------------------
        mGradient       = In.vs.albedoMapTexCoords2.y;
    #endif
    mFacing     = pow( mFacing,   5);
    mGradient   = pow( mGradient, 5);
    mPixelDepth = 1 - 0.01*In.vs.vertToEyeVectorProjDistance;
    // ------------------------------------------------
    mFinalAlpha *= mPixelDepth * mMist * mFacing * mGradient * colorScale.a;
    // ------------------------------------------------
    alpha = mFinalAlpha;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="GET_FOG_COLOR_FS">
<![CDATA[
#if defined(ALPHA_BLENDED) && FOG_MODE != 0
    return oColor.xyz*In.vs.fogFactor; // In additive blending mode, we need to use a black fog color
#endif
]]>
            </CodeInjection>
            <CodeInjection position="FINAL_POS_FS">
<![CDATA[
#if defined(ALPHA_BLENDED)
    oColor.a = 0.0; // additive blending
    #if defined( DEBUG_SHOW_PARALLAX )
        oColor.rgb = mFinalAlpha;
        oColor.a = 1.0f;
    #endif
#endif
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
