<?xml version="1.0" encoding="utf-8"?>
<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"/>
    </Parameters>
    <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>
    </Variations>
    <LodLevel startDistance="0" alphaForceMode = "use">
        <CodeInjections>
            <CodeInjection position = "MATERIALINFO">
<![CDATA[
#if defined( BILLBOARD_TURNLIGHT ) || defined( STATIC_TURNLIGHT )
    uniform float4 blinkOffset;
#endif
]]>
            </CodeInjection>
            <CodeInjection position="VS_OUTPUT">
<![CDATA[
float mVisScale : TEXCOORDn;
float2 centerScreenPos : TEXCOORDn;
float centerScreenPosZ : TEXCOORDn;
float centerScreenPosW : TEXCOORDn;
]]>
            </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 )
    // 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 )
        #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 )
        emissiveColor.rgb  *= In.vs.mVisScale;
    #endif
#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
]]>
            </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
#endif
]]>
            </CodeInjection>
        </CodeInjections>
    </LodLevel>
</CustomShader>
