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

cbuffer _cbSharedPerViewData : register(b13)
{

  struct
  {
    row_major float4x4 mProjection;
    row_major float4x4 mProjectionPrev;
    row_major float4x4 mViewToViewport;
    row_major float4x4 mViewToWorld;
    row_major float4x4 mViewToWorldPrev;
    row_major float4x4 mFxWorldToSampleSpace;
    float4 vViewRemap;
    float4 vViewDepthRemap;
    float4 vEyeVectorUL;
    float4 vEyeVectorLR;
    float4 vEyeVectorDelta;
    float4 vPixelToEyeVectorScaleBias;
    float4 vViewSpaceUpVector;
    float4 vViewportSize;
    float4 vTesselationEnabled;
    float4 vEngineTime;
    uint nFrameCounter;
    float4 vShaderColor0;
    float4 vShaderColor1;
    float4 vShaderColor2;
    float4 vShaderColor3;
    float4 vShaderColor4;
    float4 vClipPlane;
    float4 vClipPlane0;
    float4 vClipPlane1;
    float4 vClipPlane2;
    float4 vClipPlane3;
    float4 vClipPlane4;
    float4 vClipPlane5;
    float4 vMippedDepthRemap;
    float4 vSpecularOcclusionSettings;
    float4 vSaturatedAmbientOcclusionSettings;
    float4 vLightModelSettings;
    float4 vHDRScale;
    float4 vTweakableShaderParams;
    float4 vAtmosphericScatteringParameters;
    float4 vAtmosphericScatteringParameters2;
    float4 vAtmosphericScatteringParameters3;
    float3 vAtmosphericScatteringMieBeta;
    float3 vAtmosphericScatteringRayleighBeta;
    float3 vAtmosphericScatteringShadowedMieBeta;
    float3 vAtmosphericScatteringShadowedRayleighBeta;
    float3 vAttenuatedSunColor;
    float3 vSunDirectionVS;
    row_major float4x4 mViewToGlobalShadowVSPT;
    float4 vWindDirectionAndStrength;
    float4 vWindDirectionAndStrengthPrev;
    float4 vWindInitialDirectionAndStrength;
    float4 vFxFadeParameters;
    float2 vFxSize;
    int nEnableGBufferSpecPowerAdjustment;
    int nNumCSMCascades;
    float fCSMFadeAdd;
    int nEnableClothBias;
    int2 viNumTiles;
    int nLightTileDebugFlags;
    int nEnableBoxReflections;
    int nSelectedBoxReflectionId;
    int nEnableAtmosphericScatteringBackdrop;
    int nEnableSampleFromUICameraBackbuffer;
    int nFallbackRoomMask;
    float4 vClearColor;
    float3 vGlobalLightDirectionVS;
    float3 vGlobalLightFrontColor;
    float3 vGlobalLightBackColor;
    float4 vShadowAtlasSize;
    float2 vShadowPoissonScale;
    int nShadowSpotKernel;
    int nShadowCSMKernel;
    float4 vJitter;
    float4 vUnjitter;
    int nHashedAlphaPeriod;
    int nIsRenderingOffscreen;
  } cbSharedPerViewData : packoffset(c0);

}


float world_z_from_depth_buffer(float x, float y)
{
	uint width, height;
	float z;
		
	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;
	
	float4 r0;
	r0.x = cbSharedPerViewData.vViewRemap.z * z + -cbSharedPerViewData.vViewRemap.y;
    return 1 / r0.x;
	
	
}

float adjust_from_depth_buffer(float x, float y)
{
	float4 stereo = StereoParams.Load(0);
	float separation = stereo.x; float convergence = stereo.y;
	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.
	

	offset = -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 < 255; i++) {
		offset += distance / 255.0;

		// 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 0;

		// 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;
}
