
/* CgFX 1.4 file for bumpdemo effect. */

uniform sampler2D texture;
uniform sampler2D texture_normal;
uniform sampler2D texture_height;
uniform sampler2D texture_shadow_map;

float3 ambient_light_col;
float3 obj_position;
float obj_w;
float obj_h;
float obj_t;

float bump_factor;
float no_lighting=0.0;

float bump_mapping;

float3 directional_light;
float ambient_light;
float directional_strength;
float projection_factor;
float height_factor;

float light_x[32];
float light_y[32];
float light_z[32];
float light_r[32];
float light_g[32];
float light_b[32];
float light_range[32];
float lights_count;

float screen_x;
float screen_y;
float screen_w;
float screen_h;

float scale;

float obj_sw;
float obj_sh;

float map_w;
float map_h;
float map_t;

struct PS_OUTPUT
{
    float4 color : COLOR0;
    float depth : DEPTH;
};

PS_OUTPUT ps_main(float2 normalMapTexCoord : TEXCOORD0)
{

    PS_OUTPUT Out;
    float4 color;
    float4 normal_col;
    float4 height_col;
    float4 shadow_col;
    float3 light_vector;
    float3 normal_vector;
    float3 final_light;
    final_light[0] = 0.0;
    final_light[1] = 0.0;
    final_light[2] = 0.0;

    color = tex2D(texture, normalMapTexCoord);
    Out.color = color;
    if (color.a == 0.0) return Out;
    normal_col = tex2D(texture_normal, normalMapTexCoord);
    height_col = tex2D(texture_height, normalMapTexCoord);




    float dx, dy, dz, tx, ty, tz, sx, sy;
    sx = (obj_w * normalMapTexCoord.x);
    sy = (obj_h * (1.0-normalMapTexCoord.y));
    tz = obj_position[2] + (obj_t * height_col.r);

    ty = (sy + tz*height_factor)/projection_factor + sx;
    tx = -ty + sx*2.0;


    tx *= scale;
    ty *= scale;
    tz -= obj_position[2];
    tz *= scale;
    tz += obj_position[2];

    float2 screen_pos;
    screen_pos.x = (screen_x+normalMapTexCoord.x*obj_w*scale)/screen_w;
    screen_pos.y = 1.0-(((screen_y+(1.0-normalMapTexCoord.y)*obj_h*scale)+tz*height_factor)/screen_h);

    shadow_col = tex2D(texture_shadow_map, screen_pos);
    float shadow_s, shadow_f;
    shadow_f = shadow_col.r*255.0 + shadow_col.g*255.0*255.0;
    shadow_s = shadow_col.b*255.0 + shadow_col.a*255.0*255.0;

    normal_vector[0] = (normal_col.r - 0.5) / 0.5;
    normal_vector[1] = (normal_col.g - 0.5) / 0.5;
    normal_vector[2] = (normal_col.b - 0.5) / 0.5;
    normal_vector = normalize(normal_vector);

    int i;
    float luminance;
    float luminance2;
    i = 0;

    while (i < 32) {

        dx = abs(light_x[i] - obj_position[0] - tx);
        dy = abs(light_y[i] - obj_position[1] - ty);
        dz = abs(light_z[i] - obj_position[2] - tz);

        luminance = sqrt(dx*dx + dy*dy + dz*dz);

        luminance = luminance / light_range[i];
        if (luminance > 1.0) luminance = 1.0;
        luminance = 1.0 - luminance;

        if (bump_factor > 0) {

            light_vector[0] = tx-light_x[i];
            light_vector[1] = ty-light_y[i];
            light_vector[2] = tz-light_z[i];

            light_vector = normalize(light_vector);

            dx = abs(light_vector[0] - normal_vector[0]) * (1.0/bump_factor);
            dy = abs(light_vector[1] - normal_vector[1]) * (1.0/bump_factor);
            dz = abs(light_vector[2] - normal_vector[2]) * (1.0/bump_factor);


            luminance2 = sqrt(dx*dx + dy*dy + dz*dz);

            if (luminance2 < 0.6) {
                luminance2 = (luminance2/0.6)*0.55;
            }

            if (luminance2 < 0.0) luminance2 = 0.0;
            if (luminance2 > 1.0) luminance2 = 1.0;

            luminance *= luminance2;
        }

        final_light[0] += luminance*light_r[i];
        final_light[1] += luminance*light_g[i];
        final_light[2] += luminance*light_b[i];

        i+=1;
        if (i>=lights_count) break;
    }




    if (directional_strength > 0) {
        light_vector = normalize(directional_light);

        dx = abs(light_vector[0] - normal_vector[0]);
        dy = abs(light_vector[1] - normal_vector[1]);
        dz = abs(light_vector[2] - normal_vector[2]);
        luminance2 = sqrt(dx*dx + dy*dy + dz*dz);

        luminance2 = luminance2*directional_strength + ambient_light;
        if (luminance2 > 1.0) luminance2 = 1.0;
        if (tz < shadow_f) {
            float4 new_col;
            float al;
            al = 1.0;

            new_col = tex2D(texture_shadow_map, screen_pos+float2((2.0/screen_w), (2.0/screen_h)));
            float shadow_t;
            shadow_t = new_col.r*255.0 + new_col.g*255.0*255.0;
            if (tz < shadow_t) al+=1.0;

            new_col = tex2D(texture_shadow_map, screen_pos+float2((2.0/screen_w), (-2.0/screen_h)));
            shadow_t = new_col.r*255.0 + new_col.g*255.0*255.0;
            if (tz < shadow_t) al+=1.0;

            new_col = tex2D(texture_shadow_map, screen_pos+float2((-2.0/screen_w), (2.0/screen_h)));
            shadow_t = new_col.r*255.0 + new_col.g*255.0*255.0;
            if (tz < shadow_t) al+=1.0;

            new_col = tex2D(texture_shadow_map, screen_pos+float2((-2.0/screen_w), (-2.0/screen_h)));
            shadow_t = new_col.r*255.0 + new_col.g*255.0*255.0;
            if (tz < shadow_t) al+=1.0;

            al /= 5.0;
            luminance2 -= 0.12*al*directional_strength;
        }
        if (luminance2 < 0.0) luminance = 0.0;

        final_light[0] += luminance2*ambient_light_col[0];
        final_light[1] += luminance2*ambient_light_col[1];
        final_light[2] += luminance2*ambient_light_col[2];
    }


    float op;
    op = 1.0 - (1.0-height_col.r)*.15;
    final_light *=op;

    if (no_lighting) {
        final_light[0] = 1.0;
        final_light[1] = 1.0;
        final_light[2] = 1.0;
    }

    color.r *= final_light[0];
    color.g *= final_light[1];
    color.b *= final_light[2];

    Out.color = color;

    tz = (obj_t * height_col.r);
    ty = (sy + tz*height_factor)/projection_factor + sx;
    tx = -ty + sx*2.0;

    tx*=scale;
    ty*=scale;
    tz*=scale;

    float depth;
    depth = map_w-(tx + obj_position[0]);
    depth /= (map_w+map_h+map_t)*2.0;
    if (depth <= 0.0) depth = 0.0001;
    if (depth >= 1.0) depth = 0.9999;
    Out.depth = 1.0-depth;

    return Out;
}

technique lighting {
  pass {
    FragmentProgram = compile glslf ps_main();
    VertexProgram = NULL;
  }
}

