//Volumetric fix?
#version 450
#extension GL_EXT_nonuniform_qualifier : require

struct FlrInput
{
    vec2 uv0;
    vec4 pos;
};

struct FlrOutput
{
    vec4 emissive;
};

struct SH9Compressed
{
    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 = 26, std140) uniform PerMaterial
{
    uvec4 paramIntData0;
    vec4 paramData0;
    vec4 paramData1;
    vec4 paramData2;
    vec4 paramData3;
    vec4 paramData4;
    vec4 paramData5;
    vec4 paramData6;
    vec4 paramData7;
    vec4 paramData8;
    vec4 paramData9;
    uvec4 paramImgIDs0;
    uvec4 paramImgIDs1;
    uvec4 paramImgIDs2;
} _250;

layout(set = 0, binding = 28, 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;
} _286;

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

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

layout(set = 0, binding = 22) uniform sampler2D flowTex;
layout(set = 0, binding = 20) uniform sampler2D emissiveTex;
layout(set = 0, binding = 21) uniform sampler2D emissiveMaskTex;
layout(set = 0, binding = 23) uniform sampler3D scatterBufferTex;
layout(set = 2, binding = 0) uniform texture2D globalTextures[];
layout(set = 2, binding = 0) uniform textureCube globalCubeTextures[];
layout(set = 2, binding = 0) uniform texture3D global3DTextures[];
layout(set = 1, binding = 0) uniform sampler linearClampSampler;
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(location = 1) in vec2 inUV0;
layout(location = 6) in vec4 inPosition;
layout(location = 0) out vec4 outColor;
layout(location = 0) in vec3 inNormal;
layout(location = 2) in vec4 inTangent;
layout(location = 3) in vec3 inBinormal;

vec4 computeFlowData(inout vec2 flowSample, float time, float flowSpeed, float flowStrength)
{
    float l0 = length(flowSample);
    if (l0 < 0.00999999977648258209228515625)
    {
        flowSample = vec2(0.0);
    }
    vec2 flow = flowSample * flowStrength;
    vec2 scale = fract(vec2((time * flowSpeed) - 0.5, time * flowSpeed));
    return vec4(flow, scale);
}

vec4 computeFlowData(sampler2D _flowMap, vec2 _flowMapUV, float time, float flowSpeed, float flowStrength)
{
    vec2 flowSample = (texture(_flowMap, _flowMapUV).wy * 2.0) - vec2(1.0);
    vec2 param = flowSample;
    float param_1 = time;
    float param_2 = flowSpeed;
    float param_3 = flowStrength;
    vec4 _144 = computeFlowData(param, param_1, param_2, param_3);
    return _144;
}

vec4 computeFlowmapColor(sampler2D _inputTex, vec2 _inputUV, vec4 _flowData)
{
    vec2 scale = _flowData.zw;
    float flowLayerBlendFactor = abs((0.5 - scale.x) / 0.5);
    vec4 flowUV = _flowData.xyxy * scale.xxyy;
    vec4 val0 = texture(_inputTex, _inputUV + flowUV.xy);
    vec4 val1 = texture(_inputTex, _inputUV + flowUV.zw);
    return mix(val0, val1, vec4(flowLayerBlendFactor));
}

vec4 computeFlowmapColor(sampler2D _flowMap, sampler2D _inputTex, vec2 _flowMapUV, vec2 _inputUV, float time, float flowSpeed, float flowStrength)
{
    vec2 param = _flowMapUV;
    float param_1 = time;
    float param_2 = flowSpeed;
    float param_3 = flowStrength;
    vec4 flowData = computeFlowData(_flowMap, param, param_1, param_2, param_3);
    vec2 param_4 = _inputUV;
    vec4 param_5 = flowData;
    return computeFlowmapColor(_inputTex, param_4, param_5);
}

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 flrMain(FlrInput flrInput, inout FlrOutput flrOutput)
{
    vec2 uv = (flrInput.uv0 * _250.paramData0.zw) + _250.paramData0.xy;
    if ((_250.paramIntData0.x & 1u) > 0u)
    {
        uv = (flrInput.uv0 * _250.paramData0.zw) + (_250.paramData0.xy * _286.frameParameters0.x);
    }
    vec4 emissive = vec4(0.0);
    if ((_250.paramIntData0.x & 2u) > 0u)
    {
        vec2 param = flrInput.uv0;
        vec2 param_1 = uv;
        float param_2 = _286.frameParameters0.x;
        float param_3 = _250.paramData2.z;
        float param_4 = _250.paramData2.w;
        emissive = computeFlowmapColor(flowTex, emissiveTex, param, param_1, param_2, param_3, param_4);
    }
    else
    {
        emissive = texture(emissiveTex, uv);
    }
    vec4 emissiveMask = texture(emissiveMaskTex, flrInput.uv0);
    vec3 _342 = ((emissive.xyz * emissiveMask.xyz) * _250.paramData1.xyz) * _250.paramData2.x;
    flrOutput.emissive = vec4(_342.x, _342.y, _342.z, flrOutput.emissive.w);
    flrOutput.emissive.w = emissive.w * _250.paramData2.y;
    vec3 screenUV = flrInput.pos.xyz / vec3(flrInput.pos.w);
    vec2 _364 = (screenUV.xy * 0.5) + vec2(0.5);
    screenUV = vec3(_364.x, _364.y, screenUV.z);
    vec3 param_5 = screenUV;
    float param_6 = _286.volumetricsParams2.y;
    float param_7 = _286.volumetricsParams2.z;
    vec2 param_8 = _286.nearFar.xy;
    
    //Fix here.
    param_5.x -= vk3d_params.stereo.x *(1-vk3d_params.stereo.y*param_5.z*0.0)*0.5;
    
    vec3 _381 = cellCenterSSToUVW(param_5, param_6, param_7, param_8);
    vec3 scatteringUVW = _381;
    vec4 volSample = textureLod(scatterBufferTex, scatteringUVW, 0.0);
    float weight = (1.0 - volSample.w) * _286.volumetricsParams2.w;
    vec3 _404 = mix(flrOutput.emissive.xyz, volSample.xyz, vec3(weight));
    flrOutput.emissive = vec4(_404.x, _404.y, _404.z, flrOutput.emissive.w);
}

void main()
{
    FlrInput flrInput;
    flrInput.uv0 = inUV0;
    flrInput.pos = inPosition;
    FlrInput param = flrInput;
    FlrOutput param_1;
    flrMain(param, param_1);
    FlrOutput flrOutput = param_1;
    outColor = flrOutput.emissive;
}


