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

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

struct FlrOutput
{
    vec4 color;
    vec2 motionVector;
};

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 = 30, std140) uniform PerMaterial
{
    uvec4 paramIntData0;
    vec4 hologram_color;
    vec4 materialParamData0;
    vec4 materialParamData1;
    vec4 materialParamData2;
    vec4 materialParamData3;
} _510;

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

layout(set = 0, binding = 33, std140) uniform PerRenderPass
{
    vec4 viewportSize;
} _576;

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

layout(set = 0, binding = 20) uniform sampler2D planeYTex;
layout(set = 0, binding = 21) uniform sampler2D planeUTex;
layout(set = 0, binding = 22) uniform sampler2D planeVTex;
layout(set = 0, binding = 23) uniform sampler2D normalTex;
layout(set = 0, binding = 25) 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(set = 0, binding = 24) uniform sampler2D dissolveTex;
layout(set = 0, binding = 26) uniform sampler2D depthTex;

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

vec2 mod289(vec2 x)
{
    return x - (floor(x * 0.00346020772121846675872802734375) * 289.0);
}

vec3 mod289(vec3 x)
{
    return x - (floor(x * 0.00346020772121846675872802734375) * 289.0);
}

vec3 permute(vec3 x)
{
    vec3 param = ((x * 34.0) + vec3(1.0)) * x;
    return mod289(param);
}

float snoise(vec2 v)
{
    vec2 i = floor(v + vec2(dot(v, vec2(0.3660254180431365966796875))));
    vec2 x0 = (v - i) + vec2(dot(i, vec2(0.211324870586395263671875)));
    vec2 i1 = mix(vec2(0.0, 1.0), vec2(1.0, 0.0), bvec2(x0.x > x0.y));
    vec4 x12 = x0.xyxy + vec4(0.211324870586395263671875, 0.211324870586395263671875, -0.57735025882720947265625, -0.57735025882720947265625);
    vec2 _385 = x12.xy - i1;
    x12 = vec4(_385.x, _385.y, x12.z, x12.w);
    vec2 param = i;
    i = mod289(param);
    vec3 param_1 = vec3(i.y) + vec3(0.0, i1.y, 1.0);
    vec3 param_2 = (permute(param_1) + vec3(i.x)) + vec3(0.0, i1.x, 1.0);
    vec3 p = permute(param_2);
    vec3 m = max(vec3(0.5) - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3(0.0));
    m *= m;
    m *= m;
    vec3 x = (fract(p * vec3(0.024390242993831634521484375)) * 2.0) - vec3(1.0);
    vec3 h = abs(x) - vec3(0.5);
    vec3 ox = floor(x + vec3(0.5));
    vec3 a0 = x - ox;
    m *= (vec3(1.792842864990234375) - (((a0 * a0) + (h * h)) * 0.8537347316741943359375));
    vec3 g;
    g.x = (a0.x * x0.x) + (h.x * x0.y);
    vec2 _496 = (a0.yz * x12.xz) + (h.yz * x12.yw);
    g = vec3(g.x, _496.x, _496.y);
    return 130.0 * dot(m, g);
}

vec4 decodeYUVtoRGB(vec3 yuv)
{
    float y = yuv.x + (-0.0625);
    float u = yuv.y + (-0.5);
    float v = yuv.z + (-0.5);
    vec4 color = vec4(1.0);
    float luma = 1.164000034332275390625 * y;
    color.x = luma + (1.5959999561309814453125 * v);
    color.y = (luma - (0.813000023365020751953125 * v)) - (0.3910000026226043701171875 * u);
    color.z = luma + (2.0179998874664306640625 * u);
    color.x = pow(clamp(color.x, 0.0, 1.0), 2.2000000476837158203125);
    color.y = pow(clamp(color.y, 0.0, 1.0), 2.2000000476837158203125);
    color.z = pow(clamp(color.z, 0.0, 1.0), 2.2000000476837158203125);
    return color;
}

vec4 decodeYUVtoRGB(sampler2D texY, sampler2D texU, sampler2D texV, vec2 uv)
{
    vec3 yuv = vec3(0.0);
    yuv.x = texture(texY, uv).x;
    yuv.y = texture(texU, uv).x;
    yuv.z = texture(texV, uv).x;
    vec3 param = yuv;
    return decodeYUVtoRGB(param);
}

float getLuminance(vec3 color)
{
    return dot(color, vec3(0.2125999927520751953125, 0.715200006961822509765625, 0.072200000286102294921875));
}

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

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;
}

vec2 getMotionVector(vec4 currPos, vec4 prevPos, vec4 projectionOffsets)
{
    vec2 currPosNDC = (currPos.xy / vec2(currPos.w)) + projectionOffsets.xy;
    vec2 prevPosNDC = (prevPos.xy / vec2(prevPos.w)) + projectionOffsets.zw;
    currPosNDC.y = 1.0 - currPosNDC.y;
    prevPosNDC.y = 1.0 - prevPosNDC.y;
    vec2 motionVector = (prevPosNDC - currPosNDC) * vec2(0.5, -0.5);
    motionVector = clamp(motionVector, vec2(-1.0), vec2(1.0));
    return motionVector;
}

void flrMain(FlrInput flrInput, inout FlrOutput flrOutput)
{
    float verticalJerkStrength = _510.materialParamData0.x;
    float xOffsetNoiseStrength = _510.materialParamData0.y;
    float chromaShiftStrength = _510.materialParamData0.z;
    float scanlineStrength = _510.materialParamData0.w;
    vec2 uvScrollSpeed = _510.materialParamData1.xy;
    float scanlineScrollSpeed = _510.materialParamData1.z;
    float scrollBarSpeed = _510.materialParamData2.x;
    float scrollBarTiling = _510.materialParamData2.y;
    float scrollBarPower = _510.materialParamData2.z;
    float scrollBarStrength = _510.materialParamData2.w;
    float materialOpacity = _510.materialParamData3.x;
    float materialIntensity = _510.materialParamData3.y;
    float globalTime = _564.frameParameters0.x + 0.0;
    vec2 screenUV2 = flrInput.pos.xy * _576.viewportSize.zw;
    vec2 screenUVworld = flrInput.posWS.xy * 0.0040000001899898052215576171875;
    vec2 uvAnim = (uvScrollSpeed * globalTime) * 0.100000001490116119384765625;
    vec2 uv = flrInput.uv0 + uvAnim;
    vec2 param = vec2(globalTime * 1.5, 5.0);
    float vertJerk = 1.0 - step(snoise(param), 0.60000002384185791015625);
    vec2 param_1 = vec2(globalTime * 5.5, 5.0);
    float vertJerk2 = 1.0 - step(snoise(param_1), 0.20000000298023223876953125);
    float jerks = (((abs(sin(globalTime) * 4.0) * vertJerk) * vertJerk2) * 0.300000011920928955078125) * verticalJerkStrength;
    vec4 colorShift = _510.hologram_color;
    vec3 _643 = colorShift.xyz * (1.0 + (jerks * 0.4000000059604644775390625));
    colorShift = vec4(_643.x, _643.y, _643.z, colorShift.w);
    vec2 param_2 = vec2(globalTime * 15.0, screenUV2.y * 80.0);
    float fuzzOffset = snoise(param_2);
    vec2 param_3 = vec2(globalTime * 1.0, screenUV2.y * 25.0);
    float largeFuzzOffset = snoise(param_3);
    fuzzOffset = step(fuzzOffset, 0.25);
    largeFuzzOffset = step(largeFuzzOffset, 0.25);
    float xOffset = (((fuzzOffset * 0.0030000000260770320892333984375) + (largeFuzzOffset * 0.0040000001899898052215576171875)) + (jerks * 0.02999999932944774627685546875)) * xOffsetNoiseStrength;
    vec2 uvFuzz = vec2(uv.x - xOffset, uv.y);
    float chromaShift = min((xOffset * 0.5) + 0.00200000009499490261077880859375, 0.00999999977648258209228515625) * chromaShiftStrength;
    vec2 uvR = vec2(uvFuzz.x - chromaShift, uvFuzz.y) + uvScrollSpeed;
    vec2 uvG = vec2(uvFuzz.x, uvFuzz.y) + uvScrollSpeed;
    vec2 uvB = vec2(uvFuzz.x + chromaShift, uvFuzz.y) + uvScrollSpeed;
    vec2 param_4 = uvR;
    vec4 albedo = decodeYUVtoRGB(planeYTex, planeUTex, planeVTex, param_4);
    float albedoA = albedo.w;
    float albedoR = albedo.x;
    vec2 param_5 = uvG;
    float albedoG = decodeYUVtoRGB(planeYTex, planeUTex, planeVTex, param_5).y;
    vec2 param_6 = uvB;
    float albedoB = decodeYUVtoRGB(planeYTex, planeUTex, planeVTex, param_6).z;
    vec4 color = vec4(albedoR, albedoG, albedoB, 1.0);
    vec3 param_7 = color.xyz;
    vec3 _770 = mix(color.xyz, colorShift.xyz * getLuminance(param_7), vec3(_510.hologram_color.w));
    color = vec4(_770.x, _770.y, _770.z, color.w);
    float scrollBarVertical = fract((screenUVworld.y * scrollBarTiling) + (globalTime * scrollBarSpeed));
    vec2 scrollBarVec = vec2(vec2(0.5) - vec2(0.5, scrollBarVertical));
    float scrollBar = (1.0 - (clamp(1.0 - pow(dot(scrollBarVec, scrollBarVec), scrollBarPower), 0.0, 1.0) * 1.0)) * scrollBarStrength;
    vec4 normalValue = texture(normalTex, flrInput.uv0);
    vec4 param_8 = normalValue;
    vec3 normal = decodeNormalMap(param_8);
    normal = normalize(((flrInput.tangent.xyz * normal.x) + (flrInput.binormal * normal.y)) + (flrInput.normal * normal.z));
    float transparency = ((clamp(scrollBar + 0.4000000059604644775390625, 0.0, 1.0) + 0.100000001490116119384765625) * materialOpacity) * albedoA;
    float scanlineScroll = (globalTime * 30.0) * scanlineScrollSpeed;
    float scanline = (sin(((screenUV2.y * _576.viewportSize.y) * 2.0) + scanlineScroll) * 0.07999999821186065673828125) * scanlineStrength;
    vec3 _865 = color.xyz - vec3(scanline);
    color = vec4(_865.x, _865.y, _865.z, color.w);
    color *= materialIntensity;
    color.w = clamp(transparency, 0.0, 1.0);
    flrOutput.color = color;
    vec3 screenUV = flrInput.pos.xyz / vec3(flrInput.pos.w);
    vec2 _888 = (screenUV.xy * 0.5) + vec2(0.5);
    screenUV = vec3(_888.x, _888.y, screenUV.z);
    vec3 param_9 = screenUV;
    float param_10 = _564.volumetricsParams2.y;
    float param_11 = _564.volumetricsParams2.z;
    vec2 param_12 = _564.nearFar.xy;
    
    //Fix here.
    param_9.x -= vk3d_params.stereo.x *(1-vk3d_params.stereo.y*param_9.z*0.0)*0.5;
    
    vec3 _905 = cellCenterSSToUVW(param_9, param_10, param_11, param_12);
    vec3 scatteringUVW = _905;
    vec4 volSample = textureLod(scatterBufferTex, scatteringUVW, 0.0);
    float weight = (1.0 - volSample.w) * _564.volumetricsParams2.w;
    vec3 _928 = mix(flrOutput.color.xyz, volSample.xyz, vec3(weight));
    flrOutput.color = vec4(_928.x, _928.y, _928.z, flrOutput.color.w);
    vec4 param_13 = flrInput.pos;
    vec4 param_14 = flrInput.prevPos;
    vec4 param_15 = _564.projectionOffsets;
    flrOutput.motionVector = getMotionVector(param_13, param_14, param_15);
}

float packUInt16(uint i)
{
    return 1.52587890625e-05 * float(i);
}

void main()
{
    float normalSign = gl_FrontFacing ? 1.0 : (-1.0);
    FlrInput flrInput;
    flrInput.pos = inPosition;
    flrInput.uv0 = inUV0;
    flrInput.posWS = inPosWS;
    flrInput.normal = inNormal * normalSign;
    flrInput.tangent = inTangent * normalSign;
    flrInput.binormal = inBinormal * normalSign;
    flrInput.prevPos = inPrevPosition;
    FlrInput param = flrInput;
    FlrOutput param_1;
    flrMain(param, param_1);
    FlrOutput flrOutput = param_1;
    outColor = flrOutput.color;
    outMotionVector = vec4(flrOutput.motionVector.x, flrOutput.motionVector.y, outMotionVector.z, outMotionVector.w);
    outMotionVector = vec4(outMotionVector.x, outMotionVector.y, vec2(0.0).x, vec2(0.0).y);
    if (outColor.w > 0.0500000007450580596923828125)
    {
        uint param_2 = 8192u;
        outMotionVector.w = packUInt16(param_2);
    }
}


