// Depth buffer copied to this input with 3Dmigoto:
Texture2D<float> DepthBuffer : register(t110);

//define 70 matrices copied from CB1 from light shader to CB13
//used for auto depth crosshair with universal formula for UE4 by DJ_RK
cbuffer camera : register(b13)
{
    float4 cb1[70];
}

static const float near = 0.00001;
static const float far = 1;

float world_z_from_depth_buffer(float x, float y)
{
    uint width, height;
    float z;
    float4 r0;
    DepthBuffer.GetDimensions(width, height);

    x = min(max((x / 2 + 0.5) * width, 0), width - 1);
    y = min(max((-y / 2 + 0.5) * height, 0), height - 1);
    z = DepthBuffer.Load(int3(x, y, 0)).x;
    if (z == 1)
        return 0;

//skip original formula for autodepth calc and replace with DJ_RKs universal Depth calculation formula for UE4 Games.
//return (far*near/((z)*near) + (far*z));
//let the shader find the right matrix


if(cb1[51].w==-0.00000000999999994)
{
  r0.zw = cb1[51].xz * float2(z,z);
  r0.z = cb1[51].y + r0.z;
  r0.w = -cb1[51].w + r0.w;
}
if(cb1[53].w==-0.00000000999999994)
{
  r0.zw = cb1[53].xz * float2(z,z);
  r0.z = cb1[53].y + r0.z;
  r0.w = -cb1[53].w + r0.w;
}
if(cb1[57].w==-0.00000000999999994)
{
  r0.zw = cb1[57].xz * float2(z,z);
  r0.z = cb1[57].y + r0.z;
  r0.w = -cb1[57].w + r0.w;
}
if(cb1[61].w==-0.00000000999999994)
{
  r0.zw = cb1[61].xz * float2(z,z);
  r0.z = cb1[61].y + r0.z;
  r0.w = -cb1[61].w + r0.w;
}
if(cb1[65].w==-0.00000000999999994)
{
  r0.zw = cb1[65].xz * float2(z,z);
  r0.z = cb1[65].y + r0.z;
  r0.w = -cb1[65].w + r0.w;
}

  r0.w = 1 / r0.w;
  r0.z = r0.z + r0.w; 
  return r0.z;
}

float adjust_from_depth_buffer(float x, float y, float numsamples)
{
    float4 stereo = StereoParams.Load(0);
  if (stereo.x==0) {return 0;}
    float separation = stereo.x; float convergence = stereo.y;
    float4 CrosshairDepth2 = IniParams.Load(int2(27,0));
    float old_offset, offset, w, sampled_w, distance;
    uint i;

    // Stereo cursor: To improve the accuracy of the stereo cursor, we
    // sample a number of points on the depth buffer, starting at the near
    // clipping plane and working towards original x + separation.
    //
    // You can think of this as a line in three dimensional space that
    // starts at each eye and stretches out towards infinity. We sample 255
    // points along this line (evenly spaced in the X axis) and compare
    // with the depth buffer to find where the line is first intersected.
    //
    // Note: The reason for sampling 255 points came from a restriction in
    // DX9/SM3 where loops had to run a constant number of iterations and
    // there was no way to set that number from within the shader itself.
    // I'm not sure if the same restriction applies in DX11 with SM4/5 - if
    // it doesn't, we could change this to check each pixel instead for
    // better accuracy.
    //
    // Based on DarkStarSword's stereo crosshair code originally developed
    // for Miasmata, adapted to Unity, then translated to HLSL.

    offset = (near - convergence) * separation; // Z = X offset from center
    distance = separation - offset;         // Total distance to cover (separation - starting X offset)

    old_offset = offset;
    for (i = 0; i < numsamples; i++) {
        offset += distance / numsamples;

        // Calculate depth for this point on the line:
        w = (separation * convergence) / (separation - offset);

        sampled_w = world_z_from_depth_buffer(x + offset, y);
        if (sampled_w == 0)
            return separation;

        // If the sampled depth is closer than the calculated depth,
        // we have found something that intersects the line, so exit
        // the loop and return the last point that was not intersected:
        if (w > sampled_w)
            break;

        old_offset = offset;
    }

    return old_offset;
}
