//Shadows
// ---- Created with 3Dmigoto v1.2.56 on Wed May 24 18:33:04 2017

cbuffer _Globals : register(b0)
{
  float4 VPtoRTScaleBias : packoffset(c0);
  float4 ShadowProperties : packoffset(c1);
  float4 LightProperties : packoffset(c2);
  float4 ShadowFarPlanes : packoffset(c3);
  float4 ShadowFrustumWidths : packoffset(c4);
  row_major float4x4 ViewMatrix[5] : packoffset(c5);
  row_major float4x4 ProjectionMatrix[4] : packoffset(c25);
}

cbuffer PerView : register(b12)
{
  row_major float4x4 global_View : packoffset(c0);
  row_major float4x4 global_Projection : packoffset(c4);
  row_major float4x4 global_ViewProjection : packoffset(c8);
  float4 global_ViewPos : packoffset(c12);
  float4 global_ViewInfo : packoffset(c13);
  float4 global_ScaleAndBias : packoffset(c14);
}

SamplerState PointSampler_s : register(s0);
Texture2D<float4> LinearDepth : register(t0);
Texture2D<float4> Shadow : register(t1);


// 3Dmigoto declarations
#define cmp -
Texture1D<float4> IniParams : register(t120);
Texture2D<float4> StereoParams : register(t125);

#include <ShaderFixes/matrix.hlsl>

void main( 
  float4 v0 : SV_Position0,
  float3 v1 : TexCoord0,
  float3 v2 : TexCoord1,
  out float4 o0 : SV_Target0)
{
  float4 r0,r1,r2,r3,r4,r5;
  uint4 bitmask, uiDest;
  float4 fDest;

  r0.xy = (int2)v0.xy;
  r0.zw = float2(0,0);
  r0.z = LinearDepth.Load(r0.xyz).x;
  r1.xy = -VPtoRTScaleBias.zw * global_ViewInfo.zw + v0.xy;
  r1.z = global_ViewInfo.w + -r1.y;
  r1.xy = r1.xz / global_ViewInfo.zw;
  r0.xy = r1.xy * float2(2,2) + float2(-1,-1);
  r0.xyz = v1.xyz * r0.xyz;
  r1.xyz = global_View._m10_m11_m12 * r0.yyy;
  r0.xyw = r0.xxx * global_View._m00_m01_m02 + r1.xyz;
  r0.xyz = r0.zzz * global_View._m20_m21_m22 + r0.xyw;
  r0.xyz = global_ViewPos.xyz + r0.xyz;
  r1.x = ShadowProperties.x * ShadowProperties.y;
  r1.x = (int)r1.x;
  r1.y = cmp(0 < (int)r1.x);
  
//CORRECT WORLD COORD
float4 s = StereoParams.Load(0);
float4 r20, r21;
r0.w = 1;
r21 = mul(global_ViewProjection, r0);  
r21.x -= s.x * (r21.w - s.y); 
r0 = mul(inverse(global_ViewProjection), r21);
  
  if (r1.y != 0) {
    r0.w = 1;
    r2.x = dot(ProjectionMatrix[0]._m00_m01_m02_m03, r0.xyzw);
    r2.y = dot(ProjectionMatrix[0]._m10_m11_m12_m13, r0.xyzw);
    r2.z = dot(ProjectionMatrix[0]._m20_m21_m22_m23, r0.xyzw);
    r1.z = dot(ProjectionMatrix[0]._m30_m31_m32_m33, r0.xyzw);
    r2.xyz = r2.xyz / r1.zzz;
    r1.zw = float2(2,2) / ShadowProperties.xy;
    r1.zw = float2(0.5,0.5) * r1.zw;
    r2.w = ShadowFrustumWidths.x * LightProperties.z;
    r2.w = 0.5 * r2.w;
    r1.zw = saturate(r2.xy / r1.zw);
    r1.zw = r1.zw * float2(2,2) + float2(-1,-1);
    r1.zw = float2(1,1) + -abs(r1.zw);
    r1.zw = saturate(r1.zw / LightProperties.zz);
    r3.x = saturate(1 + -r2.z);
    r3.x = ShadowFarPlanes.x * r3.x;
    r2.w = saturate(r3.x / r2.w);
    r1.z = r1.z * r1.w;
    r1.w = r1.z * r2.w;
    r3.x = cmp(0 < r1.w);
    if (r3.x != 0) {
      r3.y = LightProperties.w / ShadowFarPlanes.x;
      r2.z = -r3.y + r2.z;
      r2.x = Shadow.SampleLevel(PointSampler_s, r2.xy, 0).x;
      r2.x = cmp(r2.x < r2.z);
      r2.x = r2.x ? 0 : r1.w;
      r1.w = cmp(r1.w < 1);
      r2.y = (int)r1.x + -1;
      r2.y = cmp(0 < (int)r2.y);
      r1.w = r1.w ? r2.y : 0;
      if (r1.w != 0) {
        r4.x = dot(ProjectionMatrix[1]._m00_m01_m02_m03, r0.xyzw);
        r4.y = dot(ProjectionMatrix[1]._m10_m11_m12_m13, r0.xyzw);
        r4.z = dot(ProjectionMatrix[1]._m20_m21_m22_m23, r0.xyzw);
        r1.w = dot(ProjectionMatrix[1]._m30_m31_m32_m33, r0.xyzw);
        r3.yzw = r4.xyz / r1.www;
        r2.yz = float2(2,2) / ShadowProperties.yx;
        r4.xy = float2(0.5,0.5) * r2.yz;
        r1.w = ShadowFrustumWidths.y * LightProperties.z;
        r1.w = 0.5 * r1.w;
        r2.z = saturate(r3.y / r4.y);
        r2.z = r2.z * 2 + -1;
        r2.z = 1 + -abs(r2.z);
        r2.y = -r2.y * 0.5 + r3.z;
        r2.y = saturate(r2.y / r4.x);
        r2.y = r2.y * 2 + -1;
        r2.y = 1 + -abs(r2.y);
        r2.yz = saturate(r2.yz / LightProperties.zz);
        r4.x = saturate(1 + -r3.w);
        r4.x = ShadowFarPlanes.y * r4.x;
        r1.w = saturate(r4.x / r1.w);
        r2.y = r2.z * r2.y;
        r1.w = r2.y * r1.w;
        r1.w = cmp(0 < r1.w);
        if (r1.w != 0) {
          r1.w = -r1.z * r2.w + 1;
          r2.y = LightProperties.w / ShadowFarPlanes.y;
          r2.z = ShadowFrustumWidths.y / ShadowFrustumWidths.x;
          r2.y = -r2.y * r2.z + r3.w;
          r2.z = Shadow.SampleLevel(PointSampler_s, r3.yz, 0).x;
          r2.y = cmp(r2.z < r2.y);
          r1.w = r2.y ? 0 : r1.w;
          r2.x = r2.x + r1.w;
        }
      } else {
        r1.z = -r1.z * r2.w + r2.x;
        r2.x = 1 + r1.z;
      }
    } else {
      r2.x = 1;
    }
    r1.z = r3.x ? 0 : 1;
  } else {
    r2.x = 1;
    r1.z = 0;
    r3.x = -1;
  }
  r1.w = ~(int)r3.x;
  r1.y = r1.y ? r1.w : 0;
  r1.w = cmp((int)r1.z < (int)r1.x);
  r1.y = r1.w ? r1.y : 0;
  if (r1.y != 0) {
    r0.w = 1;
    r3.x = dot(ProjectionMatrix[1]._m00_m01_m02_m03, r0.xyzw);
    r3.y = dot(ProjectionMatrix[1]._m10_m11_m12_m13, r0.xyzw);
    r3.z = dot(ProjectionMatrix[1]._m20_m21_m22_m23, r0.xyzw);
    r1.w = dot(ProjectionMatrix[1]._m30_m31_m32_m33, r0.xyzw);
    r2.yzw = r3.xyz / r1.www;
    r3.xy = float2(2,2) / ShadowProperties.yx;
    r3.yz = float2(0.5,0.5) * r3.xy;
    r1.w = ShadowFrustumWidths.y * LightProperties.z;
    r1.w = 0.5 * r1.w;
    r3.z = saturate(r2.y / r3.z);
    r3.z = r3.z * 2 + -1;
    r3.z = 1 + -abs(r3.z);
    r3.x = -r3.x * 0.5 + r2.z;
    r3.x = saturate(r3.x / r3.y);
    r3.x = r3.x * 2 + -1;
    r3.x = 1 + -abs(r3.x);
    r3.xz = saturate(r3.xz / LightProperties.zz);
    r3.y = saturate(1 + -r2.w);
    r3.y = ShadowFarPlanes.y * r3.y;
    r1.w = saturate(r3.y / r1.w);
    r3.x = r3.z * r3.x;
    r3.y = r3.x * r1.w;
    r3.z = cmp(0 < r3.y);
    if (r3.z != 0) {
      r3.w = LightProperties.w / ShadowFarPlanes.y;
      r4.x = ShadowFrustumWidths.y / ShadowFrustumWidths.x;
      r2.w = -r3.w * r4.x + r2.w;
      r2.y = Shadow.SampleLevel(PointSampler_s, r2.yz, 0).x;
      r2.y = cmp(r2.y < r2.w);
      r2.x = r2.y ? 0 : r3.y;
      r2.y = cmp(r3.y < 1);
      r2.z = (int)r1.x + -1;
      r2.z = cmp(1 < (int)r2.z);
      r2.y = r2.z ? r2.y : 0;
      if (r2.y != 0) {
        r4.x = dot(ProjectionMatrix[2]._m00_m01_m02_m03, r0.xyzw);
        r4.y = dot(ProjectionMatrix[2]._m10_m11_m12_m13, r0.xyzw);
        r4.z = dot(ProjectionMatrix[2]._m20_m21_m22_m23, r0.xyzw);
        r2.y = dot(ProjectionMatrix[2]._m30_m31_m32_m33, r0.xyzw);
        r2.yzw = r4.xyz / r2.yyy;
        r3.yw = float2(2,2) / ShadowProperties.xy;
        r4.xy = float2(0.5,0.5) * r3.yw;
        r3.w = ShadowFrustumWidths.z * LightProperties.z;
        r3.w = 0.5 * r3.w;
        r3.y = -r3.y * 0.5 + r2.y;
        r3.y = saturate(r3.y / r4.x);
        r3.y = r3.y * 2 + -1;
        r3.y = 1 + -abs(r3.y);
        r3.y = saturate(r3.y / LightProperties.z);
        r4.x = saturate(r2.z / r4.y);
        r4.x = r4.x * 2 + -1;
        r4.x = 1 + -abs(r4.x);
        r4.x = saturate(r4.x / LightProperties.z);
        r4.y = saturate(1 + -r2.w);
        r4.y = ShadowFarPlanes.z * r4.y;
        r3.w = saturate(r4.y / r3.w);
        r3.y = r4.x * r3.y;
        r3.y = r3.y * r3.w;
        r3.y = cmp(0 < r3.y);
        if (r3.y != 0) {
          r3.y = -r3.x * r1.w + 1;
          r3.w = LightProperties.w / ShadowFarPlanes.z;
          r4.x = ShadowFrustumWidths.z / ShadowFrustumWidths.x;
          r2.w = -r3.w * r4.x + r2.w;
          r2.y = Shadow.SampleLevel(PointSampler_s, r2.yz, 0).x;
          r2.y = cmp(r2.y < r2.w);
          r2.y = r2.y ? 0 : r3.y;
          r2.x = r2.x + r2.y;
        }
      } else {
        r1.w = -r3.x * r1.w + r2.x;
        r2.x = 1 + r1.w;
      }
    }
    r1.z = r3.z ? 1 : 2;
  } else {
    r3.z = -1;
  }
  r1.w = ~(int)r3.z;
  r1.y = r1.y ? r1.w : 0;
  r1.w = cmp((int)r1.z < (int)r1.x);
  r1.y = r1.w ? r1.y : 0;
  if (r1.y != 0) {
    r0.w = 1;
    r3.x = dot(ProjectionMatrix[2]._m00_m01_m02_m03, r0.xyzw);
    r3.y = dot(ProjectionMatrix[2]._m10_m11_m12_m13, r0.xyzw);
    r3.z = dot(ProjectionMatrix[2]._m20_m21_m22_m23, r0.xyzw);
    r1.w = dot(ProjectionMatrix[2]._m30_m31_m32_m33, r0.xyzw);
    r2.yzw = r3.xyz / r1.www;
    r3.xy = float2(2,2) / ShadowProperties.xy;
    r3.zw = float2(0.5,0.5) * r3.xy;
    r1.w = ShadowFrustumWidths.z * LightProperties.z;
    r1.w = 0.5 * r1.w;
    r4.x = -r3.x * 0.5 + r2.y;
    r4.x = saturate(r4.x / r3.z);
    r4.x = r4.x * 2 + -1;
    r4.x = 1 + -abs(r4.x);
    r4.x = saturate(r4.x / LightProperties.z);
    r3.w = saturate(r2.z / r3.w);
    r3.w = r3.w * 2 + -1;
    r3.w = 1 + -abs(r3.w);
    r3.w = saturate(r3.w / LightProperties.z);
    r4.y = saturate(1 + -r2.w);
    r4.y = ShadowFarPlanes.z * r4.y;
    r1.w = saturate(r4.y / r1.w);
    r3.w = r4.x * r3.w;
    r4.x = r3.w * r1.w;
    r4.y = cmp(0 < r4.x);
    if (r4.y != 0) {
      r4.z = LightProperties.w / ShadowFarPlanes.z;
      r4.w = ShadowFrustumWidths.z / ShadowFrustumWidths.x;
      r2.w = -r4.z * r4.w + r2.w;
      r2.y = Shadow.SampleLevel(PointSampler_s, r2.yz, 0).x;
      r2.y = cmp(r2.y < r2.w);
      r2.x = r2.y ? 0 : r4.x;
      r2.y = cmp(r4.x < 1);
      r2.z = (int)r1.x + -1;
      r2.z = cmp(2 < (int)r2.z);
      r2.y = r2.z ? r2.y : 0;
      if (r2.y != 0) {
        r5.x = dot(ProjectionMatrix[3]._m00_m01_m02_m03, r0.xyzw);
        r5.y = dot(ProjectionMatrix[3]._m10_m11_m12_m13, r0.xyzw);
        r5.z = dot(ProjectionMatrix[3]._m20_m21_m22_m23, r0.xyzw);
        r2.y = dot(ProjectionMatrix[3]._m30_m31_m32_m33, r0.xyzw);
        r2.yzw = r5.xyz / r2.yyy;
        r4.x = ShadowFrustumWidths.w * LightProperties.z;
        r4.x = 0.5 * r4.x;
        r3.x = -r3.x * 0.5 + r2.y;
        r3.x = saturate(r3.x / r3.z);
        r3.x = r3.x * 2 + -1;
        r3.x = 1 + -abs(r3.x);
        r3.z = -r3.y * 0.5 + r2.z;
        r3.y = 0.5 * r3.y;
        r3.y = saturate(r3.z / r3.y);
        r3.y = r3.y * 2 + -1;
        r3.y = 1 + -abs(r3.y);
        r3.xy = saturate(r3.xy / LightProperties.zz);
        r3.z = saturate(1 + -r2.w);
        r3.z = ShadowFarPlanes.w * r3.z;
        r3.z = saturate(r3.z / r4.x);
        r3.x = r3.x * r3.y;
        r3.x = r3.x * r3.z;
        r3.x = cmp(0 < r3.x);
        if (r3.x != 0) {
          r3.x = -r3.w * r1.w + 1;
          r3.y = LightProperties.w / ShadowFarPlanes.w;
          r3.z = ShadowFrustumWidths.w / ShadowFrustumWidths.x;
          r2.w = -r3.y * r3.z + r2.w;
          r2.y = Shadow.SampleLevel(PointSampler_s, r2.yz, 0).x;
          r2.y = cmp(r2.y < r2.w);
          r2.y = r2.y ? 0 : r3.x;
          r2.x = r2.x + r2.y;
        }
      } else {
        r1.w = -r3.w * r1.w + r2.x;
        r2.x = 1 + r1.w;
      }
    }
    r1.z = r4.y ? 2 : 3;
  } else {
    r4.y = -1;
  }
  r1.w = ~(int)r4.y;
  r1.y = r1.y ? r1.w : 0;
  r1.z = cmp((int)r1.z < (int)r1.x);
  r1.y = r1.z ? r1.y : 0;
  if (r1.y != 0) {
    r0.w = 1;
    r3.x = dot(ProjectionMatrix[3]._m00_m01_m02_m03, r0.xyzw);
    r3.y = dot(ProjectionMatrix[3]._m10_m11_m12_m13, r0.xyzw);
    r3.z = dot(ProjectionMatrix[3]._m20_m21_m22_m23, r0.xyzw);
    r1.y = dot(ProjectionMatrix[3]._m30_m31_m32_m33, r0.xyzw);
    r1.yzw = r3.xyz / r1.yyy;
    r2.yz = float2(2,2) / ShadowProperties.xy;
    r3.xy = float2(0.5,0.5) * r2.yz;
    r2.w = ShadowFrustumWidths.w * LightProperties.z;
    r2.w = 0.5 * r2.w;
    r2.yz = -r2.yz * float2(0.5,0.5) + r1.yz;
    r2.yz = saturate(r2.yz / r3.xy);
    r2.yz = r2.yz * float2(2,2) + float2(-1,-1);
    r2.yz = float2(1,1) + -abs(r2.yz);
    r2.yz = saturate(r2.yz / LightProperties.zz);
    r3.z = saturate(1 + -r1.w);
    r3.z = ShadowFarPlanes.w * r3.z;
    r2.w = saturate(r3.z / r2.w);
    r2.y = r2.y * r2.z;
    r2.z = r2.y * r2.w;
    r3.z = cmp(0 < r2.z);
    if (r3.z != 0) {
      r3.z = LightProperties.w / ShadowFarPlanes.w;
      r3.w = ShadowFrustumWidths.w / ShadowFrustumWidths.x;
      r1.w = -r3.z * r3.w + r1.w;
      r1.y = Shadow.SampleLevel(PointSampler_s, r1.yz, 0).x;
      r1.y = cmp(r1.y < r1.w);
      r2.x = r1.y ? 0 : r2.z;
      r1.y = cmp(r2.z < 1);
      r1.x = (int)r1.x + -1;
      r1.x = cmp(3 < (int)r1.x);
      r1.x = r1.x ? r1.y : 0;
      if (r1.x != 0) {
        r1.x = dot(ProjectionMatrix[0]._m00_m01_m02_m03, r0.xyzw);
        r1.y = dot(ProjectionMatrix[0]._m10_m11_m12_m13, r0.xyzw);
        r1.z = dot(ProjectionMatrix[0]._m20_m21_m22_m23, r0.xyzw);
        r0.x = dot(ProjectionMatrix[0]._m30_m31_m32_m33, r0.xyzw);
        r0.xyz = r1.xyz / r0.xxx;
        r0.w = ShadowFrustumWidths.x * LightProperties.z;
        r0.w = 0.5 * r0.w;
        r1.xy = saturate(r0.xy / r3.xy);
        r1.xy = r1.xy * float2(2,2) + float2(-1,-1);
        r1.xy = float2(1,1) + -abs(r1.xy);
        r1.xy = saturate(r1.xy / LightProperties.zz);
        r1.z = saturate(1 + -r0.z);
        r1.z = ShadowFarPlanes.x * r1.z;
        r0.w = saturate(r1.z / r0.w);
        r1.x = r1.x * r1.y;
        r0.w = r1.x * r0.w;
        r0.w = cmp(0 < r0.w);
        if (r0.w != 0) {
          r0.w = -r2.y * r2.w + 1;
          r1.x = LightProperties.w / ShadowFarPlanes.x;
          r0.z = -r1.x + r0.z;
          r0.x = Shadow.SampleLevel(PointSampler_s, r0.xy, 0).x;
          r0.x = cmp(r0.x < r0.z);
          r0.x = r0.x ? 0 : r0.w;
          r2.x = r2.x + r0.x;
        }
      } else {
        r0.x = -r2.y * r2.w + r2.x;
        r2.x = 1 + r0.x;
      }
    }
  }
  o0.xyzw = r2.xxxx;
  return;
}