//decal/shadow variant - FIXED FOR STEREO 3D
//decals
// ---- Created with 3Dmigoto v0.6.164 on Sat Dec 20 01:09:00 2025
Texture2D<float4> t1 : register(t1);
Texture2D<float4> t0 : register(t0);

SamplerState s1_s : register(s1);
SamplerState s0_s : register(s0);

cbuffer cb3 : register(b3)
{
  float4 cb3[8];
}

cbuffer cb2 : register(b2)
{
  float4 cb2[22];
}

cbuffer cb1 : register(b1)
{
  float4 cb1[8];
}

cbuffer cb0 : register(b0)
{
  float4 cb0[20];
}

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


void main(
  float4 v0 : SV_POSITION0,
  float4 v1 : TEXCOORD0,      // CORREGIDO: float4 en lugar de float2 + float2
  float4 v2 : TEXCOORD1,
  float4 v3 : TEXCOORD2,
  float3 v4 : TEXCOORD3,
  out float4 o0 : SV_Target0)
{
  float4 r0,r1,r2;
  uint4 bitmask, uiDest;
  float4 fDest;
  
  // Carga parámetros estéreo
  float4 s = StereoParams.Load(0);
  float4 ini = IniParams.Load(int2(90,0));

  // Lee depth buffer
  r0.xy = v2.xy / v2.ww;
  r0.x = t0.Sample(s1_s, r0.xy).x;
  r0.x = cb1[7].x * r0.x + cb1[7].y;
  r0.x = 1 / r0.x;
  
  // Reconstruye posición en view space
  r0.y = cb1[5].z / v3.z;
  r0.yzw = v3.xyz * r0.yyy;
  r0.xyz = r0.yzw * r0.xxx;
  
  // ============================================================
  // STEREO 3D FIX
  // ============================================================

  
  
  r0.x -= s.x * (r0.z - s.y) * cb2[10].x;
  // ============================================================
  
  // Transforma a world space
  r1.xyz = cb2[19].xyz * r0.yyy;
  r0.xyw = cb2[18].xyz * r0.xxx + r1.xyz;
  r0.xyz = cb2[20].xyz * r0.zzz + r0.xyw;
  r0.xyz = cb2[21].xyz + r0.xyz;
  
  // Transforma a decal/shadow space
  r1.xyz = cb3[5].xyz * r0.yyy;
  r0.xyw = cb3[4].xyz * r0.xxx + r1.xyz;
  r0.xyz = cb3[6].xyz * r0.zzz + r0.xyw;
  r0.xyz = cb3[7].xyz + r0.xyz;
  
  // Verifica límites
  r1.xyz = float3(0.5,0.5,0.5) + -abs(r0.xyz);
  
  // Calcula UVs
  r0.xy = float2(0.5,0.5) + r0.xz;
  r0.xy = cb0[19].xy * r0.xy;
  
  // Sample textura
  r0.xyzw = t1.Sample(s0_s, r0.xy).xyzw;
  
  // Descarta si está fuera
  r1.xyz = cmp(r1.xyz < float3(0,0,0));
  r1.x = (int)r1.y | (int)r1.x;
  r1.x = (int)r1.z | (int)r1.x;
  if (r1.x != 0) discard;
  
  // Fog/blend
  r1.xyz = -cb0[5].xyz + cb0[4].xyz;
  r1.xyz = v1.www * r1.xyz + cb0[5].xyz;  // CORREGIDO: v1.www
  r1.xyz = -r0.xyz * cb0[18].xyz + r1.xyz;
  r2.xyzw = cb0[18].xyzw * r0.xyzw;
  r1.xyz = cb0[7].xxx * r1.xyz + r2.xyz;
  o0.w = r2.w;
  r0.xyz = r0.xyz * cb0[18].xyz + -r1.xyz;
  o0.xyz = v1.zzz * r0.xyz + r1.xyz;  // CORREGIDO: v1.zzz
  return;
}