//Specular reflections PS Kraken pool. Smoke.
#version 450
#extension GL_EXT_nonuniform_qualifier : require

struct MaterialData
{
    uvec4 paramIntData0;
    vec4 paramFloatData0;
    vec4 paramFloatData1;
    vec4 paramFloatData2;
    vec4 paramFloatData3;
    vec4 paramFloatData4;
    vec4 paramFloatData5;
    vec4 paramFloatData6;
    vec4 paramFloatData7;
    vec4 paramFloatData8;
    vec4 paramFloatData9;
    uvec4 paramImgIDs0;
    uvec4 paramImgIDs1;
    uvec4 paramImgIDs2;
};

struct LightingData
{
    vec3 L;
    vec2 energyDiffuseSpecular;
    vec3 posWS;
    vec3 posWSa;
    vec3 posVS;
    vec3 cameraPosWS;
    vec3 V;
    vec3 N;
    vec3 NVtx;
    vec3 T;
    vec4 lightingWeights0;
    vec4 lightingWeights1;
    vec3 baseColor;
    float metalness;
    float specular;
    float roughness;
    float occlusion;
    float translucency;
    float ambientOcclusion;
    vec3 emissive;
    vec3 irradiance;
    vec4 materialBlendMask;
    uint materialId;
    MaterialData materialData;
    vec4 ssrSample;
    vec3 diffuseColor;
    vec3 specularColor;
    vec3 R;
    vec3 H;
    float NdL;
    float NdV;
    float NdH;
    float VdH;
    float LdH;
    float roughness2;
    float roughness4;
    vec3 posWSneighborX;
    vec3 posWSneighborY;
    float time;
    float depthFixup;
};

struct LightingDataDesc
{
    vec3 baseColor;
    float roughness;
    float metalness;
    float occlusion;
    float translucency;
    vec3 N;
    vec3 NVtx;
    float ambientOcclusion;
    vec3 emissive;
    vec3 irradiance;
    vec4 materialBlendMask;
    vec4 lightingWeights0;
    vec4 lightingWeights1;
    vec3 cameraPosWS;
    vec3 posWS;
    vec3 posWSa;
    vec3 posVS;
    uint materialId;
    MaterialData materialData;
};

struct SH9
{
    vec3 L[9];
};

struct FlrInput
{
    vec3 posWS;
    vec3 normal;
    vec3 binormal;
    vec4 tangent;
    vec2 uv0;
    vec4 pos;
    vec2 dynamicResolutionFactor;
};

struct FlrOutput
{
    vec4 albedo;
    vec4 normals;
    vec4 parameter;
    vec3 normalsTS;
};

struct SH9Compressed
{
    uvec4 data0[2];
    uvec4 data1;
};

struct LightData
{
    vec4 posAndRadiusWS;
    vec4 colorAndIntensity;
    vec4 lightDirectionAndFalloffExp;
    vec4 lightTangent;
    uvec4 lightTypeAndFlags;
    vec4 spotLightAngles;
    vec4 sphereAndShadowParams;
};

struct ExtendedLightData
{
    mat4 boxInverseWorldMatrix;
    mat4 viewProjectionMatrix;
    uvec4 params0;
    vec4 projectorTransform;
};

struct SpecularProbeData
{
    vec4 posAndRadiusWS;
    mat4 worldMatrix;
    mat4 inverseWorldMatrix;
    uvec4 imageIdAndFlags;
    vec4 params0;
    vec4 params1;
};

struct SH9Compressed_1
{
    uvec4 data0[2];
    uvec4 data1;
};

// Vk3DVision (http://3dsurroundgaming.com/) - Stereo Injection
layout(set = 0, binding = 110, std140) uniform Vk3DParams
{
    vec4 stereo;
    vec4 custom_params;
} vk3d_params;

layout(set = 0, binding = 31, std140) uniform PerMaterial
{
    uvec4 paramIntData0;
    vec4 tint;
    vec4 waterParams4;
    vec4 uvTransform;
    vec4 waterParams0;
    vec4 waterParams3;
    vec4 waterParams1;
    vec4 waterParams2;
    vec4 paramData7;
    vec4 paramData8;
    vec4 paramData9;
    uvec4 paramImgIDs0;
    uvec4 paramImgIDs1;
} _1148;

layout(set = 0, binding = 30, std140) uniform PerInstance
{
    uvec4 params0;
    vec4 materialParams0;
    vec4 materialParams1;
    vec4 materialParams2;
    vec4 materialParams3;
} _1199;

layout(set = 0, binding = 33, std140) uniform PerView
{
    mat4 invViewProjMatrix;
    mat4 invProjMatrix;
    vec4 nearFar;
    vec4 nearFarWidthHeight;
    vec4 cameraPositionWS;
    vec4 dirLightDirWS;
    vec4 dirLightColorAndIntens;
    uvec4 dirLightProjectorParams;
    vec4 dirLightProjectorTransform;
    mat4 dirLightProjectorViewProjMatrix;
    SH9Compressed skyModelSH;
    SH9Compressed globalBackgroundSH;
    mat4 pssmViewProjMatrices[5];
    mat4 localLightViewProjMatrices[16];
    vec4 shadowParameters0;
    vec4 playerWorldPosition;
    vec4 lightingWeights0;
    vec4 lightingWeights1;
    vec4 dynamicResolutionParameters;
    vec4 frameParameters0;
    vec4 frameParameters1;
    vec4 projectionOffsets;
    vec4 irradianceGridWorldPosition;
    vec4 irradianceGridHalfExtents;
    uvec4 irradianceGridResolution;
    mat4 viewMatrix;
    vec4 volumetricsParams2;
} _1259;

layout(set = 0, binding = 41, std430) readonly buffer lightBuffer
{
    LightData _lightBuffer[];
} _2167;

layout(set = 0, binding = 42, std430) readonly buffer extendedLightBuffer
{
    ExtendedLightData _extendedLightBuffer[];
} _2172;

layout(set = 0, binding = 44, std430) readonly buffer specularProbeBuffer
{
    SpecularProbeData _specularProbeBuffer[];
} _2177;

layout(set = 0, binding = 46, std430) readonly buffer resourceIndexBuffer
{
    uint _resourceIndexBuffer[];
} _2181;

layout(set = 0, binding = 47, std430) readonly buffer materialDataBuffer
{
    MaterialData _materialDataBuffer[];
} _2186;

layout(set = 0, binding = 48, std430) readonly buffer irradianceGridBuffer
{
    SH9Compressed_1 _irradianceGridBuffer[];
} _2192;

layout(set = 0, binding = 100, std430) buffer DebugBuffer
{
    uint debugBuffer[];
} _2196;

layout(set = 2, binding = 0) uniform textureCube globalCubeTextures[];
layout(set = 0, binding = 27) uniform sampler2D depthBufferTex;
layout(set = 0, binding = 22) uniform sampler2D waterFlowTex;
layout(set = 0, binding = 23) uniform sampler2D waterNoiseTex;
layout(set = 0, binding = 24) uniform sampler2D waterNormal0Tex;
layout(set = 0, binding = 25) uniform sampler2D waterNormal1Tex;
layout(set = 0, binding = 21) uniform sampler2D waterFoamTex;
layout(set = 0, binding = 20) uniform sampler2D waterDebrisTex;
layout(set = 0, binding = 26) uniform sampler2D waterParameterTex;
layout(set = 1, binding = 0) uniform sampler linearClampSampler;
layout(set = 0, binding = 50) uniform sampler2D refractionTex;
layout(set = 0, binding = 49) uniform sampler3D scatterBufferTex;
layout(set = 2, binding = 0) uniform texture2D globalTextures[];
layout(set = 2, binding = 0) uniform texture3D global3DTextures[];
layout(set = 1, binding = 1) uniform sampler linearRepeatSampler;
layout(set = 1, binding = 2) uniform sampler nearestClampSampler;
layout(set = 1, binding = 3) uniform sampler nearestRepeatSampler;
layout(set = 1, binding = 4) uniform sampler shadowSampler;
layout(set = 0, binding = 40) uniform sampler2DArrayShadow shadowBufferTex;

layout(location = 4) in vec3 inPosWS;
layout(location = 1) in vec2 inUV0;
layout(location = 0) in vec3 inNormal;
layout(location = 3) in vec3 inBinormal;
layout(location = 2) in vec4 inTangent;
layout(location = 6) in vec4 inPosition;
layout(location = 0) out vec4 outColor;

vec4 decodeARGB8uint(uint colorU)
{
    return vec4(float((colorU & 16711680u) >> uint(16)) * 0.003921560011804103851318359375, float((colorU & 65280u) >> uint(8)) * 0.003921560011804103851318359375, float(colorU & 255u) * 0.003921560011804103851318359375, float((colorU & 4278190080u) >> uint(24)) * 0.003921560011804103851318359375);
}

vec3 gammaToLinear(vec3 color)
{
    return pow(clamp(color, vec3(0.0), vec3(1.0)), vec3(2.2000000476837158203125));
}

vec4 decodeRGBA8uint(uint colorU)
{
    return vec4(float((colorU & 4278190080u) >> uint(24)) * 0.003921560011804103851318359375, float((colorU & 16711680u) >> uint(16)) * 0.003921560011804103851318359375, float((colorU & 65280u) >> uint(8)) * 0.003921560011804103851318359375, float(colorU & 255u) * 0.003921560011804103851318359375);
}

float oldDeviceDepthToLinear(float z, float near, float far)
{
    float a = far / (far - near);
    float b = ((-far) * near) / (far - near);
    return b / ((1.0 - z) - a);
}

vec3 decodeNormalMap(vec4 normalSample)
{
    vec2 _305 = (normalSample.wy - vec2(0.5)) * 2.0;
    vec3 normal;
    normal = vec3(_305.x, _305.y, normal.z);
    normal.z = sqrt(1.0 - ((normal.x * normal.x) - (normal.y * normal.y)));
    return normal;
}

vec3 getAnimatedWaterNormal(vec2 uv, float timeOffset, float normalBias, sampler2D normal0Tex, sampler2D normal1Tex)
{
    vec2 offset = vec2(timeOffset, 0.0);
    vec3 waterNormal = vec3(0.0);
    vec4 param = texture(normal0Tex, uv + offset, normalBias);
    waterNormal += decodeNormalMap(param);
    vec4 param_1 = texture(normal1Tex, uv - offset, normalBias);
    waterNormal += decodeNormalMap(param_1);
    vec4 param_2 = texture(normal0Tex, (vec2(0.5) - uv) + offset.yx, normalBias);
    waterNormal += decodeNormalMap(param_2);
    vec4 param_3 = texture(normal1Tex, (vec2(0.5) - uv) - offset.yx, normalBias);
    waterNormal += decodeNormalMap(param_3);
    return waterNormal;
}

vec2 signNotZero(vec2 v)
{
    return vec2((v.x >= 0.0) ? 1.0 : (-1.0), (v.y >= 0.0) ? 1.0 : (-1.0));
}

vec2 encodeNormal(vec3 v)
{
    vec2 p = v.xy * (1.0 / ((abs(v.x) + abs(v.y)) + abs(v.z)));
    vec2 _222;
    if (v.z <= 0.0)
    {
        vec2 param = p;
        _222 = (vec2(1.0) - abs(p.yx)) * signNotZero(param);
    }
    else
    {
        _222 = p;
    }
    return _222;
}

void flrMain(FlrInput flrInput, inout FlrOutput flrOutput)
{
    uint param = floatBitsToUint(_1148.tint.x);
    vec4 debrisTint = decodeARGB8uint(param);
    uint param_1 = floatBitsToUint(_1148.tint.y);
    vec4 foamTint = decodeARGB8uint(param_1);
    uint param_2 = floatBitsToUint(_1148.tint.z);
    vec4 fogColor = decodeARGB8uint(param_2);
    vec3 param_3 = debrisTint.xyz;
    vec3 _1170 = gammaToLinear(param_3);
    debrisTint = vec4(_1170.x, _1170.y, _1170.z, debrisTint.w);
    vec3 param_4 = foamTint.xyz;
    vec3 _1176 = gammaToLinear(param_4);
    foamTint = vec4(_1176.x, _1176.y, _1176.z, foamTint.w);
    vec3 param_5 = fogColor.xyz;
    vec3 _1182 = gammaToLinear(param_5);
    fogColor = vec4(_1182.x, _1182.y, _1182.z, fogColor.w);
    float normalStrength = _1148.waterParams3.x;
    float translucency = fogColor.w;
    flrOutput.albedo = vec4(fogColor.xyz.x, fogColor.xyz.y, fogColor.xyz.z, flrOutput.albedo.w);
    uint param_6 = floatBitsToUint(_1199.materialParams0.w);
    vec3 perInstanceEmissiveTint = decodeRGBA8uint(param_6).xyz;
    vec3 waterEmissiveTint = perInstanceEmissiveTint * _1199.materialParams0.y;
    vec3 _1215 = flrOutput.albedo.xyz * waterEmissiveTint;
    flrOutput.albedo = vec4(_1215.x, _1215.y, _1215.z, flrOutput.albedo.w);
    vec2 uv = (flrInput.uv0 * _1148.uvTransform.xy) + _1148.uvTransform.zw;
    vec2 uvFoam = uv;
    if ((_1148.paramIntData0.x & 8u) > 0u)
    {
        uv = (flrInput.uv0 * _1148.uvTransform.xy) + (_1148.uvTransform.zw * _1259.frameParameters0.x);
        uvFoam = (flrInput.uv0 * _1148.uvTransform.xy) + ((_1148.uvTransform.zw * _1259.frameParameters0.x) * _1148.waterParams3.w);
    }
    vec2 waterDUDV = vec2(sin((_1259.frameParameters0.x * 1.25) + uv.x), cos((_1259.frameParameters0.x * 0.75) + uv.y)) * _1148.waterParams2.y;
    float waterDepth = 0.0;
    float softShoreAmount = 1.0;
    if ((_1148.paramIntData0.x & 1u) > 0u)
    {
        vec2 posNDC = flrInput.pos.xy / vec2(flrInput.pos.w);
        vec2 screenUV = (posNDC * 0.5) + vec2(0.5);
        screenUV *= flrInput.dynamicResolutionFactor;
        float waterSurfaceDepth = flrInput.pos.z / flrInput.pos.w;
        float param_7 = waterSurfaceDepth;
        float param_8 = _1259.nearFar.x;
        float param_9 = _1259.nearFar.y;
        waterSurfaceDepth = oldDeviceDepthToLinear(param_7, param_8, param_9);
        waterSurfaceDepth /= _1259.nearFar.y;
        float solidSurfaceDepth = texture(depthBufferTex, screenUV).x;
        float param_10 = solidSurfaceDepth;
        float param_11 = _1259.nearFar.x;
        float param_12 = _1259.nearFar.y;
        solidSurfaceDepth = oldDeviceDepthToLinear(param_10, param_11, param_12);
        solidSurfaceDepth /= _1259.nearFar.y;
        waterDepth = solidSurfaceDepth - waterSurfaceDepth;
        waterDepth *= _1259.nearFar.y;
        softShoreAmount = clamp(waterDepth / max(_1148.waterParams1.y, 9.9999999392252902907785028219223e-09), 0.0, 1.0);
        normalStrength *= softShoreAmount;
        waterDUDV *= clamp(waterDepth / max(_1148.waterParams1.w, 9.9999999392252902907785028219223e-09), 0.0, 1.0);
        translucency *= (1.0 - exp(((-waterDepth) * _1148.waterParams1.z) * 0.00999999977648258209228515625));
    }
    vec2 baseUV = uv + waterDUDV;
    float flowIntensity = 0.0;
    float flowPhaseBlendFactor = 0.0;
    vec2 flowUV0 = vec2(0.0);
    vec2 flowUV1 = vec2(0.0);
    vec2 flowUV0Normal = vec2(0.0);
    vec2 flowUV1Normal = vec2(0.0);
    if ((_1148.paramIntData0.x & 2u) > 0u)
    {
        vec2 waterFlowUV = uv * _1148.waterParams1.x;
        vec2 waterFlowVector = texture(waterFlowTex, waterFlowUV).wy;
        waterFlowVector = (waterFlowVector * 2.0) - vec2(1.0);
        flowIntensity = length(waterFlowVector);
        normalStrength *= (1.0 - min(flowIntensity, _1148.waterParams0.w));
        waterDUDV *= (1.0 - clamp(flowIntensity, 0.0, 1.0));
        baseUV = uv + waterDUDV;
        float waterPhaseTimer = _1148.waterParams0.y * (_1259.frameParameters0.x + texture(waterNoiseTex, waterFlowUV).y);
        float waterPhase1 = mod(waterPhaseTimer, 2.0);
        flowPhaseBlendFactor = abs(waterPhase1 - 1.0);
        waterFlowVector *= _1148.waterParams0.z;
        flowUV0Normal = waterFlowVector * waterPhase1;
        float waterPhase2 = mod(waterPhaseTimer + 1.0, 2.0);
        flowUV1Normal = (waterFlowVector * waterPhase2) + vec2(0.5);
        waterPhase1 -= 1.0;
        waterPhase2 -= 1.0;
        flowUV0 = waterFlowVector * waterPhase1;
        flowUV1 = (waterFlowVector * waterPhase2) + vec2(0.5);
    }
    float animationTime = _1259.frameParameters0.x * _1148.waterParams0.x;
    vec3 normal;
    if ((_1148.paramIntData0.x & 2u) > 0u)
    {
        vec2 param_13 = baseUV + flowUV0;
        float param_14 = animationTime;
        float param_15 = _1148.waterParams3.y;
        vec2 param_16 = baseUV + flowUV1;
        float param_17 = animationTime;
        float param_18 = _1148.waterParams3.y;
        normal = mix(getAnimatedWaterNormal(param_13, param_14, param_15, waterNormal0Tex, waterNormal1Tex), getAnimatedWaterNormal(param_16, param_17, param_18, waterNormal0Tex, waterNormal1Tex), vec3(flowPhaseBlendFactor));
    }
    else
    {
        vec2 param_19 = baseUV;
        float param_20 = animationTime;
        float param_21 = _1148.waterParams3.y;
        normal = getAnimatedWaterNormal(param_19, param_20, param_21, waterNormal0Tex, waterNormal1Tex);
    }
    normal = mix(vec3(0.0, 0.0, 1.0), normalize(normal), vec3(normalStrength));
    float foamAmount = 0.0;
    vec4 foamColor = vec4(1.0);
    if ((_1148.paramIntData0.x & 4u) > 0u)
    {
        if ((_1148.paramIntData0.x & 1u) > 0u)
        {
            foamAmount = 1.0 - min((waterDepth - _1148.waterParams1.y) / _1148.waterParams1.w, 1.0);
        }
        vec2 foamUV = ((uvFoam * _1148.waterParams4.w) + (waterDUDV * _1148.waterParams3.z)) + ((normal.xy * _1148.waterParams2.z) * _1148.waterParams3.z);
        if ((_1148.paramIntData0.x & 2u) > 0u)
        {
            foamColor *= mix(texture(waterFoamTex, foamUV + flowUV0), texture(waterFoamTex, foamUV + flowUV1), vec4(flowPhaseBlendFactor));
            foamAmount = max(foamAmount, clamp(flowIntensity, 0.0, 1.0) * _1148.waterParams2.x);
        }
        else
        {
            foamColor *= texture(waterFoamTex, foamUV);
        }
        foamColor.w *= foamColor.w;
        foamAmount = (foamAmount * foamColor.w) + foamAmount;
        foamAmount = (foamAmount * _1148.waterParams2.w) - (_1148.waterParams2.w - 1.0);
        foamAmount = clamp(foamAmount, 0.0, 1.0);
        normal = mix(normal, vec3(0.0, 0.0, 1.0), vec3(foamAmount));
    }
    float debrisUVScale = _1148.tint.w;
    vec2 debrisUV = (baseUV * debrisUVScale) + (normal.xy * _1148.waterParams2.z);
    vec4 debrisColor;
    if ((_1148.paramIntData0.x & 2u) > 0u)
    {
        debrisColor = mix(texture(waterDebrisTex, debrisUV + flowUV0), texture(waterDebrisTex, debrisUV + flowUV1), vec4(flowPhaseBlendFactor));
    }
    else
    {
        debrisColor = texture(waterDebrisTex, debrisUV);
    }
    vec3 _1692 = debrisColor.xyz * debrisTint.xyz;
    debrisColor = vec4(_1692.x, _1692.y, _1692.z, debrisColor.w);
    vec3 _1699 = foamColor.xyz * foamTint.xyz;
    foamColor = vec4(_1699.x, _1699.y, _1699.z, foamColor.w);
    float foamAlpha = foamAmount * foamTint.w;
    float debrisAlpha = debrisColor.w * debrisTint.w;
    translucency = max(translucency, foamAlpha);
    translucency = max(translucency, debrisAlpha);
    flrOutput.albedo.w = softShoreAmount;
    vec3 _1728 = mix(flrOutput.albedo.xyz, debrisColor.xyz, vec3(debrisAlpha));
    flrOutput.albedo = vec4(_1728.x, _1728.y, _1728.z, flrOutput.albedo.w);
    vec3 _1739 = mix(flrOutput.albedo.xyz, foamColor.xyz, vec3(foamAlpha));
    flrOutput.albedo = vec4(_1739.x, _1739.y, _1739.z, flrOutput.albedo.w);
    flrOutput.normalsTS = normal;
    normal = normalize(((flrInput.tangent.xyz * normal.x) + (flrInput.binormal * normal.y)) + (flrInput.normal * normal.z));
    vec3 param_22 = normal;
    vec3 param_23 = flrInput.normal;
    flrOutput.normals = vec4(encodeNormal(param_22), encodeNormal(param_23));
    if ((_1148.paramIntData0.x & 2u) > 0u)
    {
        vec3 _1797 = mix(texture(waterParameterTex, baseUV + flowUV0), texture(waterParameterTex, baseUV + flowUV1), vec4(flowPhaseBlendFactor)).xyz;
        flrOutput.parameter = vec4(_1797.x, _1797.y, _1797.z, flrOutput.parameter.w);
    }
    else
    {
        vec3 _1805 = texture(waterParameterTex, baseUV).xyz;
        flrOutput.parameter = vec4(_1805.x, _1805.y, _1805.z, flrOutput.parameter.w);
    }
    flrOutput.parameter.x = min(flrOutput.parameter.x, 1.0 - debrisAlpha);
    flrOutput.parameter.y = min(flrOutput.parameter.y, 1.0 - foamAlpha);
    flrOutput.parameter.y = min(flrOutput.parameter.y, 1.0 - debrisAlpha);
    vec3 materialParameter = _1148.waterParams4.xyz;
    flrOutput.parameter.x = clamp((flrOutput.parameter.x * clamp(materialParameter.x, 0.0, 1.0)) + clamp(materialParameter.x - 1.0, 0.0, 1.0), 0.0, 1.0);
    flrOutput.parameter.y = clamp((flrOutput.parameter.y * clamp(materialParameter.y, 0.0, 1.0)) + clamp(materialParameter.y - 1.0, 0.0, 1.0), 0.0, 1.0);
    flrOutput.parameter.z = 1.0 - clamp((1.0 - flrOutput.parameter.z) * materialParameter.z, 0.0, 1.0);
    flrOutput.parameter.w = translucency;
}

vec3 decodeNormal(vec2 e)
{
    vec3 v = vec3(e, (1.0 - abs(e.x)) - abs(e.y));
    if (v.z < 0.0)
    {
        vec2 param = v.xy;
        vec2 _266 = (vec2(1.0) - abs(v.yx)) * signNotZero(param);
        v = vec3(_266.x, _266.y, v.z);
    }
    return normalize(v);
}

void initLightingData(inout LightingData d, LightingDataDesc desc)
{
    d.L = vec3(0.0);
    d.V = vec3(0.0, 0.0, 1.0);
    d.energyDiffuseSpecular = vec2(0.0);
    d.diffuseColor = vec3(0.0);
    d.specularColor = vec3(0.0);
    d.R = vec3(0.0);
    d.H = vec3(0.0);
    d.NdL = 0.0;
    d.NdV = 0.0;
    d.NdH = 0.0;
    d.VdH = 0.0;
    d.LdH = 0.0;
    d.roughness2 = 0.0;
    d.roughness4 = 0.0;
    d.ssrSample = vec4(0.0);
    d.baseColor = desc.baseColor;
    d.roughness = desc.roughness;
    d.metalness = desc.metalness;
    d.occlusion = desc.occlusion;
    d.translucency = desc.translucency;
    d.materialBlendMask = desc.materialBlendMask;
    d.materialId = desc.materialId;
    d.materialData = desc.materialData;
    d.specular = desc.materialData.paramFloatData8.x;
    d.lightingWeights0 = desc.lightingWeights0;
    d.lightingWeights1 = desc.lightingWeights1;
    d.cameraPosWS = desc.cameraPosWS;
    d.posWS = desc.posWS;
    d.posWSa = desc.posWSa;
    d.posVS = desc.posVS;
    d.N = desc.N;
    d.NVtx = desc.NVtx;
    d.T = vec3(0.0);
    d.ambientOcclusion = desc.ambientOcclusion;
    d.emissive = desc.emissive;
    d.irradiance = desc.irradiance;
    d.posWSneighborX = vec3(0.0);
    d.posWSneighborY = vec3(0.0);
    d.time = 0.0;
    d.depthFixup = 1.0;
}

vec4 unpackUNorm4x8(uint p_PackedValue)
{
    return vec4(float(p_PackedValue & 255u), float((p_PackedValue >> uint(8)) & 255u), float((p_PackedValue >> uint(16)) & 255u), float((p_PackedValue >> uint(24)) & 255u)) * 0.00392160005867481231689453125;
}

SH9 decodeSH9(vec4 data[7])
{
    SH9 result;
    result.L[0] = data[0].xyz;
    result.L[1] = vec3(data[0].w, data[1].xy);
    result.L[2] = vec3(data[1].zw, data[2].x);
    result.L[3] = data[2].yzw;
    result.L[4] = data[3].xyz;
    result.L[5] = vec3(data[3].w, data[4].xy);
    result.L[6] = vec3(data[4].zw, data[5].x);
    result.L[7] = data[5].yzw;
    result.L[8] = data[6].xyz;
    return result;
}

SH9 decodeSH9(uvec4 data0[2], uvec4 data1)
{
    uint param = data0[0].x;
    vec4 tempCoeff = (unpackUNorm4x8(param) * 2.0) - vec4(1.0);
    float tempCoeffLen = unpackHalf2x16(data1.x & 65535u).x;
    vec4 coeffs[7];
    coeffs[0] = tempCoeff * tempCoeffLen;
    uint param_1 = data0[0].y;
    tempCoeff = (unpackUNorm4x8(param_1) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16((data1.x >> uint(16)) & 65535u).x;
    coeffs[1] = tempCoeff * tempCoeffLen;
    uint param_2 = data0[0].z;
    tempCoeff = (unpackUNorm4x8(param_2) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16(data1.y & 65535u).x;
    coeffs[2] = tempCoeff * tempCoeffLen;
    uint param_3 = data0[0].w;
    tempCoeff = (unpackUNorm4x8(param_3) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16((data1.y >> uint(16)) & 65535u).x;
    coeffs[3] = tempCoeff * tempCoeffLen;
    uint param_4 = data0[1].x;
    tempCoeff = (unpackUNorm4x8(param_4) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16(data1.z & 65535u).x;
    coeffs[4] = tempCoeff * tempCoeffLen;
    uint param_5 = data0[1].y;
    tempCoeff = (unpackUNorm4x8(param_5) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16((data1.z >> uint(16)) & 65535u).x;
    coeffs[5] = tempCoeff * tempCoeffLen;
    uint param_6 = data0[1].z;
    tempCoeff = (unpackUNorm4x8(param_6) * 2.0) - vec4(1.0);
    tempCoeffLen = unpackHalf2x16(data1.w & 65535u).x;
    coeffs[6] = tempCoeff * tempCoeffLen;
    vec4 param_7[7] = coeffs;
    return decodeSH9(param_7);
}

SH9 projectOntoSH9(vec3 n)
{
    SH9 sh;
    sh.L[0] = vec3(0.88622760772705078125);
    vec3 a1 = n.yzx * 0.48860299587249755859375;
    sh.L[1] = vec3(2.094399929046630859375) * a1.x;
    sh.L[2] = vec3(2.094399929046630859375) * a1.y;
    sh.L[3] = vec3(2.094399929046630859375) * a1.z;
    sh.L[4] = vec3(0.785398006439208984375) * ((1.09254801273345947265625 * n.x) * n.y);
    sh.L[5] = vec3(0.785398006439208984375) * ((1.09254801273345947265625 * n.y) * n.z);
    sh.L[6] = vec3(0.785398006439208984375) * (0.3153919875621795654296875 * (((3.0 * n.z) * n.z) - 1.0));
    sh.L[7] = vec3(0.785398006439208984375) * ((1.09254801273345947265625 * n.x) * n.z);
    sh.L[8] = vec3(0.785398006439208984375) * (0.546274006366729736328125 * ((n.x * n.x) - (n.y * n.y)));
    return sh;
}

vec3 shDotProduct(SH9 a, SH9 b)
{
    vec3 result = a.L[0] * b.L[0];
    result += (a.L[1] * b.L[1]);
    result += (a.L[2] * b.L[2]);
    result += (a.L[3] * b.L[3]);
    result += (a.L[4] * b.L[4]);
    result += (a.L[5] * b.L[5]);
    result += (a.L[6] * b.L[6]);
    result += (a.L[7] * b.L[7]);
    result += (a.L[8] * b.L[8]);
    return result;
}

vec3 sampleSH(uvec4 data0[2], uvec4 data1, vec3 dir)
{
    uvec4 param[2] = data0;
    uvec4 param_1 = data1;
    SH9 sh = decodeSH9(param, param_1);
    vec3 param_2 = dir;
    SH9 dirSH = projectOntoSH9(param_2);
    SH9 param_3 = dirSH;
    SH9 param_4 = sh;
    return max(shDotProduct(param_3, param_4), vec3(0.0));
}

void initLightingDataFromGBuffer(inout LightingData d)
{
    float adjRough = (d.roughness * 0.949999988079071044921875) + 0.0500000007450580596923828125;
    d.roughness2 = adjRough * adjRough;
    d.roughness4 = d.roughness2 * d.roughness2;
    d.metalness = mix(0.0, d.metalness, d.lightingWeights1.y);
    d.diffuseColor = d.baseColor - (d.baseColor * d.metalness);
    d.specularColor = mix(vec3(d.specular) * 0.07999999821186065673828125, d.baseColor, vec3(d.metalness));
}

void calculateLightingDataBase(inout LightingData d)
{
    d.V = normalize(d.cameraPosWS - d.posWSa);
    d.NdV = clamp(abs(dot(d.N, d.V)) + 9.9999999392252902907785028219223e-09, 0.0, 1.0);
    d.R = reflect(-d.V, d.N);
    d.R = normalize(mix(d.N, d.R, vec3((1.0 - d.roughness2) * (sqrt(1.0 - d.roughness2) + d.roughness2))));
}

float roughnessToMipIdx(float roughness)
{
    return max((max(roughness - 0.0500000007450580596923828125, 0.0) / 0.949999988079071044921875) * 7.0, 0.0);
}

vec3 envBRDFApprox(vec3 specularColor, float roughness, float NdV)
{
    vec4 r = (vec4(-1.0, -0.0274999998509883880615234375, -0.572000026702880859375, 0.02199999988079071044921875) * roughness) + vec4(1.0, 0.0425000004470348358154296875, 1.03999996185302734375, -0.039999999105930328369140625);
    float a = (min(r.x * r.x, exp2((-9.27999973297119140625) * NdV)) * r.x) + r.y;
    vec2 AB = (vec2(-1.03999996185302734375, 1.03999996185302734375) * a) + r.zw;
    AB.y *= clamp(50.0 * specularColor.y, 0.0, 1.0);
    return (specularColor * AB.x) + vec3(AB.y);
}

vec4 flrSampleLevelBindlessCube(sampler samplerState, vec3 normal, float lod, uint textureIdx)
{
    return textureLod(samplerCube(globalCubeTextures[nonuniformEXT(textureIdx)], samplerState), normal, lod);
}

vec2 computeFixedupRefractionUVs(sampler2D depthBuffer, vec2 screenUV, vec2 refractionDUDV, float screenspaceZ)
{
    vec2 refractionUV = screenUV + refractionDUDV;
    float refractionDepth = textureLod(depthBuffer, refractionUV, 0.0).x;
    if (refractionDepth > screenspaceZ)
    {
        refractionUV = screenUV;
    }
    return refractionUV;
}

float deviceDepthToLinear(float deviceDepth, float near, float far)
{
    return -((far * near) / ((deviceDepth * (far - near)) + near));
}

float nativeDepthToVolumeZ(float depth, float invDepthExp, float depthRange, vec2 nearFar)
{
    float param = depth;
    float param_1 = nearFar.x;
    float param_2 = nearFar.y;
    float depthLinear = -deviceDepthToLinear(param, param_1, param_2);
    return pow(clamp((depthLinear - nearFar.x) / depthRange, 0.0, 1.0) + 9.9999999392252902907785028219223e-09, invDepthExp);
}

vec3 cellCenterSSToUVW(inout vec3 cellCenter, float invDepthExp, float depthRange, vec2 nearFar)
{
    float param = cellCenter.z;
    float param_1 = invDepthExp;
    float param_2 = depthRange;
    vec2 param_3 = nearFar;
    cellCenter.z = nativeDepthToVolumeZ(param, param_1, param_2, param_3);
    return cellCenter;
}

void main()
{
    FlrInput flrInput;
    flrInput.posWS = inPosWS;
    flrInput.uv0 = inUV0;
    flrInput.normal = inNormal;
    flrInput.binormal = inBinormal;
    flrInput.tangent = inTangent;
    flrInput.pos = inPosition;
    flrInput.dynamicResolutionFactor = _1259.dynamicResolutionParameters.xy;
    FlrInput param = flrInput;
    FlrOutput param_1;
    flrMain(param, param_1);
    FlrOutput flrOutput = param_1;
    LightingDataDesc desc;
    desc.baseColor = flrOutput.albedo.xyz;
    desc.roughness = flrOutput.parameter.x;
    desc.metalness = flrOutput.parameter.y;
    desc.occlusion = flrOutput.parameter.z;
    desc.translucency = flrOutput.parameter.w;
    desc.lightingWeights0 = _1259.lightingWeights0;
    desc.lightingWeights1 = _1259.lightingWeights1;
    desc.cameraPosWS = _1259.cameraPositionWS.xyz;
    desc.posWS = inPosWS;
    
    //Fix here.
    vec3 posWSa = inPosWS;
    if (vk3d_params.custom_params.x!=1) {
        posWSa.x -= vk3d_params.stereo.x * vk3d_params.stereo.y*_1259.viewMatrix[0].x*_1259.invProjMatrix[0].x;
        posWSa.y -= vk3d_params.stereo.x * vk3d_params.stereo.y*_1259.viewMatrix[1].x*_1259.invProjMatrix[0].x;
        posWSa.z -= vk3d_params.stereo.x * vk3d_params.stereo.y*_1259.viewMatrix[2].x*_1259.invProjMatrix[0].x;
    }
    desc.posWSa = posWSa;
    
    desc.posVS = (_1259.viewMatrix * vec4(inPosWS, 1.0)).xyz;
    vec2 param_2 = flrOutput.normals.zw;
    desc.NVtx = decodeNormal(param_2);
    vec2 param_3 = flrOutput.normals.xy;
    desc.N = decodeNormal(param_3);
    desc.ambientOcclusion = 1.0;
    desc.emissive = vec3(0.0);
    desc.irradiance = vec3(0.0);
    desc.materialId = _1199.params0.w;
    desc.materialBlendMask = vec4(0.0);
    desc.materialData.paramIntData0 = uvec4(0u);
    desc.materialData.paramFloatData0 = vec4(0.0);
    desc.materialData.paramFloatData1 = vec4(0.0);
    LightingData d;
    LightingData param_4 = d;
    LightingDataDesc param_5 = desc;
    initLightingData(param_4, param_5);
    d = param_4;
    desc = param_5;
    d.T = inTangent.xyz;
    d.specular = _1148.paramData8.x;
    vec3 outLighting0 = vec3(1.0);
    vec3 outLighting1 = vec3(0.0);
    uvec4 param_6[2];
    param_6[0] = _1259.globalBackgroundSH.data0[0];
    param_6[1] = _1259.globalBackgroundSH.data0[1];
    uvec4 param_7 = _1259.globalBackgroundSH.data1;
    vec3 param_8 = d.N;
    outLighting0 = flrOutput.albedo.xyz * sampleSH(param_6, param_7, param_8);
    LightingData param_9 = d;
    initLightingDataFromGBuffer(param_9);
    d = param_9;
    LightingData param_10 = d;
    calculateLightingDataBase(param_10);
    d = param_10;
    uint specularIdToUse = _1148.paramImgIDs1.w;
    float param_11 = d.roughness;
    float specMipIdx = roughnessToMipIdx(param_11);
    vec3 param_12 = d.specularColor;
    float param_13 = d.roughness;
    float param_14 = d.NdV;
    vec3 envBRDF = envBRDFApprox(param_12, param_13, param_14);
    vec3 param_15 = d.R;
    float param_16 = specMipIdx;
    uint param_17 = specularIdToUse;
    vec3 envmapColor = flrSampleLevelBindlessCube(linearClampSampler, param_15, param_16, param_17).xyz;
    outLighting1 = envmapColor * envBRDF;
    vec3 screenSpacePos = inPosition.xyz / vec3(inPosition.w);
    vec2 screenUV = (screenSpacePos.xy * 0.5) + vec2(0.5);
    float opacity = flrOutput.parameter.w;
    vec3 refractionTint = mix(vec3(1.0), flrOutput.albedo.xyz, vec3(opacity));
    vec2 refractionDUDV = flrOutput.normalsTS.xy * 0.25;
    float refractionMipIdx = desc.roughness * 3.0;
    vec2 param_18 = screenUV;
    vec2 param_19 = refractionDUDV;
    float param_20 = screenSpacePos.z;
    vec2 refractionUV = computeFixedupRefractionUVs(depthBufferTex, param_18, param_19, param_20);
    vec3 refraction = textureLod(refractionTex, refractionUV, refractionMipIdx).xyz * refractionTint;
    vec3 _2099 = mix(refraction, outLighting0, vec3(opacity));
    outColor = vec4(_2099.x, _2099.y, _2099.z, outColor.w);
    vec3 _2105 = outColor.xyz + outLighting1;
    outColor = vec4(_2105.x, _2105.y, _2105.z, outColor.w);
    vec3 param_21 = vec3(screenUV, screenSpacePos.z);
    float param_22 = _1259.volumetricsParams2.y;
    float param_23 = _1259.volumetricsParams2.z;
    vec2 param_24 = _1259.nearFar.xy;
    
    //Fix here.
    param_21.x -= vk3d_params.stereo.x *(1-vk3d_params.stereo.y*param_21.z*0.0)*0.5;
    
    vec3 _2126 = cellCenterSSToUVW(param_21, param_22, param_23, param_24);
    vec3 scatteringUVW = _2126;
    vec4 volSample = textureLod(scatterBufferTex, scatteringUVW, 0.0);
    vec3 _2142 = mix(volSample.xyz, outColor.xyz, vec3(volSample.w));
    outColor = vec4(_2142.x, _2142.y, _2142.z, outColor.w);
    outColor.w = flrOutput.albedo.w;
}


