// Gun SCOPE X
#version 460


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

layout(set = 1, binding = 0, std140) uniform _instanceUniforms_ubo
{
    vec4 modelmatrixx;
    vec4 modelmatrixy;
    vec4 modelmatrixz;
    vec4 modelmatrixw;
    vec4 matricesinstanceindices;
    vec4 color;
    vec4 instancefactor;
    vec4 colorscale;
} _instanceUniforms;

layout(set = 0, binding = 0, std140) uniform _viewUniforms_ubo
{
    vec4 viewprojectionmatrixx;
    vec4 viewprojectionmatrixy;
    vec4 viewprojectionmatrixz;
    vec4 viewprojectionmatrixw;
    vec4 time;
    vec4 fragmentpositiontoviewtexture;
    vec4 fogparms;
    vec4 lightscatteringres;
    vec4 lightscatteringparms;
    vec4 projectionmatrixz;
    vec4 globalvieworigin;
    vec4 frustumvectl;
    vec4 frustumvectr;
    vec4 resolutionscale;
    vec4 frustumvecbl;
    vec4 frustumvecbr;
    vec4 znearfar;
} _viewUniforms;

layout(set = 2, binding = 0, std140) uniform _surfaceUniforms_ubo
{
    vec4 vertexxyzscale;
    vec4 vertexxyzbias;
    vec4 matricessurfaceindices;
    vec4 factor;
    vec4 vertexstscalebias;
    vec4 tiling;
    vec4 tiling2;
    vec4 tiling3;
    vec4 tiling4;
    vec4 tiling5;
} _surfaceUniforms;

layout(set = 0, binding = 1, std430) restrict readonly buffer worldmatrices_b
{
    vec4 worldmatrices[];
} _210;

layout(push_constant, std430) uniform PushConstants
{
    int lodLevel;
    int modelIndex;
} pushConstants;

layout(set = 2, binding = 1) uniform sampler2D samp_transmap3;
layout(set = 0, binding = 2) uniform sampler3D samp_finallightscatteringpacked0map;
layout(set = 0, binding = 3) uniform sampler3D samp_finallightscatteringpacked1map;
layout(set = 0, binding = 4) uniform sampler3D samp_skylightinglutmap;
layout(set = 2, binding = 2) uniform sampler2D samp_transmap1;
layout(set = 2, binding = 3) uniform sampler2D samp_transmap2;
layout(set = 2, binding = 4) uniform sampler2D samp_transmap;

layout(location = 0) in vec4 in_Position;
layout(location = 3) in vec4 in_Color;
layout(location = 9) in vec4 in_Tangent;
layout(location = 2) in vec4 in_Normal;
layout(location = 1) in vec2 in_TexCoord;
layout(location = 2) out vec4 vofi_TexCoord0;
layout(location = 3) out vec4 vofi_TexCoord1;
layout(location = 4) out vec4 vofi_TexCoord2;

mat4 MatrixMul(mat4 m1, mat4 m2)
{
    return m1 * m2;
}

float dot4(vec4 a, vec4 b)
{
    return dot(a, b);
}

void main()
{
    mat4 modelMatrix = mat4(vec4(_instanceUniforms.modelmatrixx), vec4(_instanceUniforms.modelmatrixy), vec4(_instanceUniforms.modelmatrixz), vec4(_instanceUniforms.modelmatrixw));
    mat4 viewProjectionMatrix = mat4(vec4(_viewUniforms.viewprojectionmatrixx), vec4(_viewUniforms.viewprojectionmatrixy), vec4(_viewUniforms.viewprojectionmatrixz), vec4(_viewUniforms.viewprojectionmatrixw));
    mat4 param = modelMatrix;
    mat4 param_1 = viewProjectionMatrix;
    mat4 mvpMatrixT = MatrixMul(param, param_1);
    vec4 mvpMatrixX = mvpMatrixT[0];
    vec4 mvpMatrixY = mvpMatrixT[1];
    vec4 mvpMatrixZ = mvpMatrixT[2];
    vec4 mvpMatrixW = mvpMatrixT[3];
    vec3 tempPosition = in_Position.xyz;
    vec4 localPosition;
    localPosition.x = (tempPosition.x * _surfaceUniforms.vertexxyzscale.x) + _surfaceUniforms.vertexxyzbias.x;
    localPosition.y = (tempPosition.y * _surfaceUniforms.vertexxyzscale.y) + _surfaceUniforms.vertexxyzbias.y;
    localPosition.z = (tempPosition.z * _surfaceUniforms.vertexxyzscale.z) + _surfaceUniforms.vertexxyzbias.z;
    localPosition.w = 1.0;
    if (_surfaceUniforms.matricessurfaceindices.z != 0.0)
    {
        vec4 tempPosition_1 = localPosition;
        vec4 matX = vec4(0.0);
        vec4 matY = vec4(0.0);
        vec4 matZ = vec4(0.0);
        uvec4 indices = uvec4(uint(_instanceUniforms.matricesinstanceindices.x + _surfaceUniforms.matricessurfaceindices.x)) + uvec4(in_Color * 255.0);
        if (_surfaceUniforms.matricessurfaceindices.z == 1.0)
        {
            uint index = indices.x;
            matX = _210.worldmatrices[(index * 3u) + 0u];
            matY = _210.worldmatrices[(index * 3u) + 1u];
            matZ = _210.worldmatrices[(index * 3u) + 2u];
        }
        else
        {
            float hiweight = in_Tangent.w * 255.100006103515625;
            vec4 weights;
            weights.y = hiweight - (floor(hiweight / 128.0) * 128.0);
            float packedWeights = in_Normal.w * 255.100006103515625;
            weights.z = floor(packedWeights / 16.0);
            weights.w = packedWeights - (weights.z * 16.0);
            weights.y *= 0.00393700785934925079345703125;
            weights.z *= 0.02222222276031970977783203125;
            weights.w *= 0.01666666753590106964111328125;
            weights.x = 1.0 - ((weights.y + weights.z) + weights.w);
            for (uint i = 0u; i < 4u; i++)
            {
                matX += (_210.worldmatrices[(indices[i] * 3u) + 0u] * weights[i]);
            }
            for (uint i_1 = 0u; i_1 < 4u; i_1++)
            {
                matY += (_210.worldmatrices[(indices[i_1] * 3u) + 1u] * weights[i_1]);
            }
            for (uint i_2 = 0u; i_2 < 4u; i_2++)
            {
                matZ += (_210.worldmatrices[(indices[i_2] * 3u) + 2u] * weights[i_2]);
            }
        }
        vec4 param_2 = tempPosition_1;
        vec4 param_3 = matX;
        localPosition.x = dot4(param_2, param_3);
        vec4 param_4 = tempPosition_1;
        vec4 param_5 = matY;
        localPosition.y = dot4(param_4, param_5);
        vec4 param_6 = tempPosition_1;
        vec4 param_7 = matZ;
        localPosition.z = dot4(param_6, param_7);
        localPosition.w = 1.0;
    }
    vec4 param_8 = localPosition;
    vec4 param_9 = mvpMatrixX;
    gl_Position.x = dot4(param_8, param_9);
    vec4 param_10 = localPosition;
    vec4 param_11 = mvpMatrixY;
    gl_Position.y = dot4(param_10, param_11);
    vec4 param_12 = localPosition;
    vec4 param_13 = mvpMatrixZ;
    gl_Position.z = dot4(param_12, param_13);
    vec4 param_14 = localPosition;
    vec4 param_15 = mvpMatrixW;
    gl_Position.w = dot4(param_14, param_15);
    vec4 param_16 = vec4(in_Position.xyz, 1.0);
    vec4 param_17 = _instanceUniforms.modelmatrixx;
    vec3 worldPos;
    worldPos.x = dot4(param_16, param_17);
    vec4 param_18 = vec4(in_Position.xyz, 1.0);
    vec4 param_19 = _instanceUniforms.modelmatrixy;
    worldPos.y = dot4(param_18, param_19);
    vec4 param_20 = vec4(in_Position.xyz, 1.0);
    vec4 param_21 = _instanceUniforms.modelmatrixz;
    worldPos.z = dot4(param_20, param_21);
    float timeOffset = _instanceUniforms.color.w * 7.33300018310546875;
    float globalTime = _viewUniforms.time.x + timeOffset;
    vec2 tableCoord1 = vec2((globalTime * _surfaceUniforms.factor.x) * _instanceUniforms.instancefactor.x, 0.25);
    float tableTexture1 = textureLod(samp_transmap3, vec4(tableCoord1, 0.0, 0.0).xy, vec4(tableCoord1, 0.0, 0.0).w).x;
    vec2 tempTexCoord = in_TexCoord;
    vec4 decodedTexcoord0;
    decodedTexcoord0.x = (tempTexCoord.x * _surfaceUniforms.vertexstscalebias.x) + _surfaceUniforms.vertexstscalebias.z;
    decodedTexcoord0.y = (tempTexCoord.y * _surfaceUniforms.vertexstscalebias.y) + _surfaceUniforms.vertexstscalebias.w;
    decodedTexcoord0 = vec4(decodedTexcoord0.x, decodedTexcoord0.y, decodedTexcoord0.xy.x, decodedTexcoord0.xy.y);
    decodedTexcoord0 = vec4(decodedTexcoord0.x, decodedTexcoord0.y, vec2(0.0, 1.0).x, vec2(0.0, 1.0).y);
    float time1 = _viewUniforms.time.x * _surfaceUniforms.tiling.w;
    float timeFloor1 = floor(time1 * _surfaceUniforms.tiling.y) / _surfaceUniforms.tiling.y;
    timeFloor1 = fract(timeFloor1);
    float timeFloor2 = floor((time1 * 0.5) * _surfaceUniforms.tiling.x) / _surfaceUniforms.tiling.x;
    timeFloor2 = fract(timeFloor2);
    vec4 param_22 = decodedTexcoord0;
    vec4 param_23 = vec4(1.0 / _surfaceUniforms.tiling.x, 0.0, 0.0, _surfaceUniforms.tiling.z * tableTexture1);
    vofi_TexCoord0.x = dot4(param_22, param_23);
    vec4 param_24 = decodedTexcoord0;
    vec4 param_25 = vec4(0.0, 1.0 / _surfaceUniforms.tiling.y, 0.0, timeFloor1);
    vofi_TexCoord0.y = dot4(param_24, param_25);
    vec4 param_26 = decodedTexcoord0;
    vec4 param_27 = vec4(1.0, 0.0, 0.0, 0.0);
    vofi_TexCoord1.z = dot4(param_26, param_27);
    vec4 param_28 = decodedTexcoord0;
    vec4 param_29 = vec4(0.0, 1.0, 0.0, 0.0);
    vofi_TexCoord1.w = dot4(param_28, param_29);
    float timeStatic = globalTime * _surfaceUniforms.tiling2.w;
    timeStatic = fract(timeStatic);
    vec4 param_30 = decodedTexcoord0;
    vec4 param_31 = vec4(_surfaceUniforms.tiling2.x, 0.0, 0.0, timeStatic * 0.3300000131130218505859375);
    vofi_TexCoord0.z = dot4(param_30, param_31);
    vec4 param_32 = decodedTexcoord0;
    vec4 param_33 = vec4(0.0, _surfaceUniforms.tiling2.y, 0.0, timeStatic);
    vofi_TexCoord0.w = dot4(param_32, param_33);
    float timeSync = globalTime * _surfaceUniforms.tiling3.w;
    timeSync = fract(timeSync);
    vec4 param_34 = decodedTexcoord0;
    vec4 param_35 = vec4(1.0, 0.0, 0.0, 0.0);
    vofi_TexCoord1.x = dot4(param_34, param_35);
    vec4 param_36 = decodedTexcoord0;
    vec4 param_37 = vec4(0.0, _surfaceUniforms.tiling3.y, 0.0, timeSync);
    vofi_TexCoord1.y = dot4(param_36, param_37);
    float timeDisto = globalTime * _surfaceUniforms.tiling4.w;
    timeDisto = fract(timeDisto);
    vec4 param_38 = decodedTexcoord0;
    vec4 param_39 = vec4(1.0, 0.0, 0.0, 0.0);
    vofi_TexCoord2.x = dot4(param_38, param_39);
    vec4 param_40 = decodedTexcoord0;
    vec4 param_41 = vec4(0.0, _surfaceUniforms.tiling4.y, 0.0, timeDisto);
    vofi_TexCoord2.y = dot4(param_40, param_41);
    vec4 param_42 = decodedTexcoord0;
    vec4 param_43 = vec4(_surfaceUniforms.tiling5.x, 0.0, 0.0, 0.0);
    vofi_TexCoord2.z = dot4(param_42, param_43);
    vec4 param_44 = decodedTexcoord0;
    vec4 param_45 = vec4(0.0, _surfaceUniforms.tiling5.y, 0.0, 0.0);
    vofi_TexCoord2.w = dot4(param_44, param_45);
    gl_Position.y = -gl_Position.y;

// Vk3DVision (http://3dsurroundgaming.com/) - Stereo Injection
if(vk3d_params.custom_params.z != 0)
    {
        if (gl_Position.w > vk3d_params.custom_params.z)
            gl_Position.x += vk3d_params.stereo.x * (gl_Position.w - vk3d_params.stereo.y); 
        else
            gl_Position.x += vk3d_params.stereo.x * (gl_Position.w - vk3d_params.custom_params.w) *0.75;
    }
    else
    {
        gl_Position.x += vk3d_params.stereo.x * (gl_Position.w - vk3d_params.stereo.y); 
    }
}


