
cbuffer _Globals : register(b0)
{
  float3 g_cameraPos : packoffset(c0);
  float2 g_invScreenSize : packoffset(c1);
  float4x4 g_invViewProjMatrix : packoffset(c2);
  float4 g_cloudOffsetAndScale : packoffset(c6);
  float4 g_cloudCoverageExponentAndFade : packoffset(c7);
  float3 g_lightDir : packoffset(c8);
  float4 g_keyColor : packoffset(c9);
  float2 g_lightAngularRadius : packoffset(c10);
  float4 g_keyTranslucencyParams : packoffset(c11);
  float4 g_subParams : packoffset(c12);
  float4 g_envmapParams : packoffset(c13);
  float g_skyEnvmap8BitTexInvScale : packoffset(c14);
  float4 g_exposureMultipliers : packoffset(c15);
  float4 g_envmapsMipmapCount : packoffset(c16);
  int g_drawReference : packoffset(c17);
  float g_skyEnvmapMipmapCount : packoffset(c17.y);
}
SamplerState g_cloudShadowSampler_s : register(s0);
SamplerState g_skyEnvmapSampler_s : register(s1);
SamplerState g_customSampler_s : register(s2);
SamplerState g_diffuseOcclusionSampler_s : register(s3);
Texture2D<float4> g_cloudShadowTexture : register(t0);
TextureCube<float4> g_skyEnvmap : register(t1);
TextureCube<float4> g_customEnvmap : register(t2);
Texture2D<float4> g_diffuseOcclusionTexture : register(t3);
Texture2D<float4> g_depthTexture : register(t4);
Texture2D<float4> g_gbufferTexture0 : register(t5);
Texture2D<float4> g_gbufferTexture1 : register(t6);
Texture2D<float4> g_gbufferTexture2 : register(t7);
Texture2D<float4> g_gbufferTexture3 : register(t8);
Texture2D<float4> g_gbufferTexture4 : register(t9);
Texture2D<float4> g_shadowAccumTexture : register(t10);

Texture2D<float4> StereoParams : register(t125);

void main(
  float4 v0 : SV_Position0,
  out float4 o0 : SV_Target0,
  out float4 o1 : SV_Target1)
{
  float4 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14;
  uint4 bitmask;

//Work out Inverse
//...Variables
float4 a1, a2, a3, a4;
float4 b1, b2, b3, b4;
float det;
//...Original Matrix
a1 = g_invViewProjMatrix._m00_m10_m20_m30;
a2 = g_invViewProjMatrix._m01_m11_m21_m31;
a3 = g_invViewProjMatrix._m02_m12_m22_m32;
a4 = g_invViewProjMatrix._m03_m13_m23_m33;
//...Determinant
det  = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));
//...Inverse Matrix Elements
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);
b1.xyzw /= det;
b2.xyzw /= det;
b3.xyzw /= det;
b4.xyzw /= det;
//End Inverse


  r0.xy = g_invScreenSize.xy * v0.xy;
  r1.xy = (int2)v0.xy;
  r1.zw = float2(0.000000e+000,0.000000e+000);
  r2.xyzw = g_gbufferTexture0.Load(r1.xyw).xyzw;
  r3.xyzw = g_gbufferTexture1.Load(r1.xyw).xyzw;
  r4.xyzw = g_gbufferTexture2.Load(r1.xyw).yxzw;
  r5.xyz = g_gbufferTexture3.Load(r1.xyw).xyz;
  r6.z = g_depthTexture.Load(r1.xyw).x;
  r0.z = 2.550000000e+002 * r4.w;
  r0.z = round(r0.z);
  r0.z = (int)r0.z;
  r7.xy = r0.zz == float2(4.000000e+000,2.000000e+000);
  if (r7.x != 0) {
    r8.xyzw = g_gbufferTexture4.Load(r1.xyw).xyzw;
    r9.xyzw = r2.xyzw * float4(4.000000e+000,4.000000e+000,4.000000e+000,4.000000e+000) + float4(-2.000000e+000,-2.000000e+000,-2.000000e+000,-2.000000e+000);
    r0.w = dot(r9.xy, r9.xy);
    r10.zw = -r0.ww * float2(2.500000e-001,5.000000e-001) + float2(1.000000e+000,1.000000e+000);
    r0.w = max(r10.z, 0.000000000e+000);
    r0.w = sqrt(r0.w);
    r10.xy = r9.xy * r0.ww;
    r0.w = dot(r10.xyw, r10.xyw);
    r0.w = rsqrt(r0.w);
    r10.xyz = r10.xyw * r0.www;
    r0.w = dot(r9.zw, r9.zw);
    r11.zw = -r0.ww * float2(2.500000e-001,5.000000e-001) + float2(1.000000e+000,1.000000e+000);
    r0.w = max(r11.z, 0.000000000e+000);
    r0.w = sqrt(r0.w);
    r11.xy = r9.zw * r0.ww;
    r0.w = dot(r11.xyw, r11.xyw);
    r0.w = rsqrt(r0.w);
    r9.xyz = r11.xyw * r0.www;
    r0.w = dot(r8.xy, float2(6.528000e+004,2.550000e+002));
    r0.w = round(r0.w);
    r5.w = 3.125000000e-002 * r0.w;
    r5.w = trunc(r5.w);
    r11.z = r0.w * 3.125000000e-002 + -r5.w;
    r0.w = 1.562500000e-002 * r5.w;
    r11.x = trunc(r0.w);
    r11.y = r5.w * 1.562500000e-002 + -r11.x;
    r11.xyz = float3(3.225806e-002,1.015873e+000,1.032258e+000) * r11.xyz;
    r7.zw = float2(2.550000e+002,2.550000e+002) * r8.zw;
    r7.zw = round(r7.zw);
    r8.xy = float2(6.250000e-002,6.250000e-002) * r7.zw;
    r8.xy = trunc(r8.xy);
    r8.zw = r7.zw * float2(6.250000e-002,6.250000e-002) + -r8.xy;
    r12.xw = float2(6.666667e-002,1.066667e+000) * r8.yw;
    r7.zw = r8.xz * float2(8.000001e-001,1.280000e+001) + float2(1.000000e+000,1.000000e+000);
    r7.zw = exp2(r7.zw);
    r7.zw = r7.zw * float2(1.443000e+000,1.443000e+000) + float2(1.443000e+000,1.443000e+000);
    r8.xyzw = r3.xyzw * r3.xyzw;
    r13.xyz = r8.www;
    r0.w = 0.000000000e+000;
  } else {
    r2.xyz = r2.xyz * float3(2.000000e+000,2.000000e+000,2.000000e+000) + float3(-1.000000e+000,-1.000000e+000,-1.000000e+000);
    r5.w = dot(r2.xyz, r2.xyz);
    r5.w = rsqrt(r5.w);
    r10.xyz = r5.www * r2.xyz;
    r3.xyzw = r3.xyzw * r3.xyzw;
    r2.x = r0.z == 5;
    if (r2.x != 0) {
      r8.xyz = r3.xyz * r3.www;
      r13.xyz = r3.xyz;
    } else {
      r2.x = r0.z == 1;
      if (r2.x != 0) {
        r13.xyz = r3.www * r3.xyz;
      } else {
        r13.xyz = r3.www;
      }
      r8.xyz = r3.xyz;
    }
    r2.x = 0.000000000e+000 < r13.x;
    r0.w = r2.x ? r2.w : 0;
    r2.x = r0.w * 1.200000000e+001 + 1.000000000e+000;
    r2.x = exp2(r2.x);
    r7.z = r2.x * 1.442999959e+000 + 1.442999959e+000;
    r7.w = 0.000000000e+000;
    r11.xyz = float3(0.000000e+000,0.000000e+000,0.000000e+000);
    r9.xyz = float3(0.000000e+000,0.000000e+000,0.000000e+000);
    r12.xw = float2(0.000000e+000,0.000000e+000);
  }
  r2.xy = r0.xy * float2(2.000000e+000,2.000000e+000) + float2(-1.000000e+000,-1.000000e+000);
  r6.xy = float2(1.000000e+000,-1.000000e+000) * r2.xy;
  r6.w = 1.000000000e+000;
  r2.x = dot(r6.xyzw, g_invViewProjMatrix._m00_m10_m20_m30);
  r2.y = dot(r6.xyzw, g_invViewProjMatrix._m01_m11_m21_m31);
  r2.z = dot(r6.xyzw, g_invViewProjMatrix._m02_m12_m22_m32);
  r2.w = dot(r6.xyzw, g_invViewProjMatrix._m03_m13_m23_m33);
  r2.w = 1.000000e+000 / r2.w;


float4 r28, r26, r27;
r26.xyz = r2.xyz * r2.www;
r26.w = 1.0;
r28.x = dot(r26.xyzw, b1.xyzw);
r28.y = dot(r26.xyzw, b2.xyzw);
r28.z = dot(r26.xyzw, b3.xyzw);
r28.w = dot(r26.xyzw, b4.xyzw);
float4 stereo = StereoParams.Load(0);
r28.x -= stereo.x * (r28.w - stereo.y); 
r26.x = dot(r28.xyzw, a1.xyzw);
r26.y = dot(r28.xyzw, a2.xyzw);
r26.z = dot(r28.xyzw, a3.xyzw);
r26.w = dot(r28.xyzw, a4.xyzw);
r2.xyz = r26.xyz / r2.www;

  r3.xyz = r2.xzy * r2.www;

  r2.x = dot(r3.xyz, r3.xyz);
  r2.z = rsqrt(r2.x);
  r6.xyz = r3.xzy * r2.zzz;
  r3.w = log2(abs(r4.y));
  r3.w = g_envmapParams.z * r3.w;
  r3.w = exp2(r3.w);
  r1.x = g_shadowAccumTexture.Load(r1.xyz).x;
  r1.y = r2.y * r2.w + g_cameraPos.y;
  r1.yz = g_lightDir.xz * r1.yy;
  r1.yz = r1.yz * g_cloudOffsetAndScale.ww + r3.xy;
  r1.yz = r1.yz * g_cloudOffsetAndScale.zz + g_cloudOffsetAndScale.xy;
  r1.y = g_cloudShadowTexture.SampleLevel(g_cloudShadowSampler_s, r1.yz, 0.000000000e+000).x;
  r1.y = saturate(g_cloudCoverageExponentAndFade.x + r1.y);
  r1.y = log2(r1.y);
  r1.y = g_cloudCoverageExponentAndFade.y * r1.y;
  r1.y = exp2(r1.y);
  r1.z = sqrt(r2.x);
  r1.z = -g_cloudCoverageExponentAndFade.z + r1.z;
  r1.z = saturate(g_cloudCoverageExponentAndFade.w * r1.z);
  r1.z = r1.z * r1.z;
  r1.w = 1.000000000e+000 + -r1.y;
  r1.y = r1.z * r1.w + r1.y;
  r1.x = r1.x * r1.y;
  r1.y = dot(r10.xyz, g_lightDir.xyz);
  r1.z = saturate(r1.y);
  r2.xyw = g_keyColor.xyz * r1.zzz;
  r2.xyw = r2.xyw * r1.xxx;
  if (r7.x != 0) {
    r12.w = saturate(r12.w);
    r1.y = r12.w * 5.000000000e-001 + r1.y;
    r1.z = r12.w * 5.000000000e-001 + 1.000000000e+000;
    r1.y = saturate(r1.y / r1.z);
    r1.yzw = g_keyColor.xyz * r1.yyy;
    r1.yzw = r1.yzw * r1.xxx;
    r12.xyz = -r10.xyz * r12.xxx + r9.xyz;
    r4.y = dot(r12.xyz, r12.xyz);
    r4.y = rsqrt(r4.y);
    r12.xyz = r12.xyz * r4.yyy;
    r14.xyz = -r3.xzy * r2.zzz + g_lightDir.xyz;
    r4.y = dot(r14.xyz, r14.xyz);
    r4.y = rsqrt(r4.y);
    r14.xyz = r14.xyz * r4.yyy;
    r4.y = dot(r9.xyz, r14.xyz);
    r4.y = -r4.y * r4.y + 1.000000000e+000;
    r4.y = max(r4.y, 0.000000000e+000);
    r4.y = sqrt(r4.y);
    r4.y = log2(r4.y);
    r4.y = r7.z * r4.y;
    r4.y = exp2(r4.y);
    r5.w = dot(r12.xyz, r14.xyz);
    r5.w = -r5.w * r5.w + 1.000000000e+000;
    r5.w = max(r5.w, 0.000000000e+000);
    r5.w = sqrt(r5.w);
    r5.w = log2(r5.w);
    r5.w = r7.w * r5.w;
    r5.w = exp2(r5.w);
    r9.xyz = r5.www * r11.xyz;
    r9.xyz = r4.yyy * r13.xxx + r9.xyz;
    r9.xyz = float3(1.500000e-001,1.500000e-001,1.500000e-001) * r9.xyz;
    r9.xyz = r9.xyz * r2.xyw;
    r9.xyz = g_keyColor.www * r9.xyz;
    r2.xyw = r1.yzw;
  } else {
    r1.yzw = -r3.xzy * r2.zzz + g_lightDir.xyz;
    r2.z = dot(r1.yzw, r1.yzw);
    r2.z = rsqrt(r2.z);
    r1.yzw = r2.zzz * r1.yzw;
    r1.y = saturate(dot(r10.xyz, r1.yzw));
    r1.z = r7.z * 8.662509918e-002 + 8.750000000e-001;
    r1.y = r1.y * r7.z + -r7.z;
    r1.y = exp2(r1.y);
    r1.y = r1.z * r1.y;
    r1.yzw = r2.xyw * r1.yyy;
    r9.xyz = g_keyColor.www * r1.yzw;
  }
  r1.yzw = r5.xyz * g_exposureMultipliers.yyy + r2.xyw;
  r2.x = r0.z != 4;
  if (r2.x != 0) {
    r2.x = dot(r6.xyz, r10.xyz);
    r2.x = r2.x + r2.x;
    r2.xyz = r10.xyz * -r2.xxx + r6.xyz;
    r11.xyzw = r4.zzzz == float4(0.000000e+000,3.922000e-003,7.843000e-003,1.176500e-002);
    r11.xyzw = r11.xyzw ? g_envmapParams.xxxx : 0;
    r2.w = 1.000000000e+000 + -g_envmapParams.w;
    r2.w = r1.x * r2.w + g_envmapParams.w;
    r2.w = r2.w * r3.w;
    r3.xy = (int2)g_envmapsMipmapCount.xy;
    r4.yz = trunc(g_envmapsMipmapCount.xy);
    r4.yz = -r0.ww * float2(1.500000e+001,1.500000e+001) + r4.yz;
    r4.yz = float2(5.000000e+000,5.000000e+000) + r4.yz;
    r3.xy = (int2)r3.xy + int2(-1,-1);
    r3.xy = r3.xy;
    r4.yz = max(r4.yz, float2(0.000000e+000,0.000000e+000));
    r3.xy = min(r3.xy, r4.yz);
    r12.xyzw = g_customEnvmap.SampleLevel(g_customSampler_s, r2.xyz, r3.y).xyzw;
    r0.w = dot(r11.xyzw, r12.xyzw);
    r2.xyz = g_skyEnvmap.SampleLevel(g_skyEnvmapSampler_s, r2.xyz, r3.x).xyz;
    r2.xyz = r2.xyz * r2.www;
    r9.xyz = r2.xyz * g_skyEnvmap8BitTexInvScale + r9.xyz;
  } else {
    r0.w = 0.000000000e+000;
  }
  r2.xyz = r5.xyz * g_exposureMultipliers.yyy + g_envmapParams.yyy;
  r2.xyz = r2.xyz * r0.www;
  r0.w = 1.000000000e+000 + -r3.w;
  r2.xyz = r2.xyz * r0.www + r9.xyz;
  r0.z = (int)r0.z >= (int)6;
  if (r0.z != 0) {
    r0.z = saturate(-2.352941222e-002 + r4.w);
    r3.y = 1.000000000e+000 + -r0.z;
    r4.x = saturate(r4.x);
    r3.x = 1.000000000e+000 + -r4.x;
    r4.xyz = r10.xyz * g_keyTranslucencyParams.www + g_lightDir.xyz;
    r0.z = saturate(dot(-r6.xyz, -r4.xyz));
    r3.xy = g_keyTranslucencyParams.yy * r3.xy;
    r3.xy = float2(-1.442695e+000,-1.442695e+000) * r3.xy;
    r3.xy = exp2(r3.xy);
    r0.z = r0.z * g_keyTranslucencyParams.z + g_keyTranslucencyParams.x;
    r0.z = dot(r0.zz, r3.xy);
    r0.z = r0.z * r1.x;
    r1.yzw = r0.zzz * g_keyColor.xyz + r1.yzw;
  }
  if (r7.x == 0) {
    r2.xyz = r2.xyz * r13.xyz;
  }
  r0.z = r7.y ? 0.000000000e+000 : 1.000000000e+000;
  r3.xyz = r2.xyz * r0.zzz;
  o0.xyz = r1.yzw * r8.xyz + r3.xyz;
  r0.xyzw = g_diffuseOcclusionTexture.Gather(g_diffuseOcclusionSampler_s, r0.xy).xyzw;
  r0.x = min(r0.y, r0.x);
  r0.x = min(r0.z, r0.x);
  o0.w = min(r0.w, r0.x);
  o1.xyz = r2.xyz;
  o1.w = 1.000000000e+000;
  return;
}
