#version 450


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

layout(set = 0, binding = 1, std140) uniform freqLow_vertexUniforms_ubo
{
    vec4 vertexxyzscale;
    vec4 vertexxyzbias;
    vec4 globalvieworigin;
    vec4 vertexstscalebias;
} freqLow_vertexUniforms;

layout(set = 0, binding = 0, std140) uniform freqHigh_vertexUniforms_ubo
{
    vec4 hardwareskinning;
    vec4 mvpmatrixx;
    vec4 mvpmatrixy;
    vec4 mvpmatrixz;
    vec4 mvpmatrixw;
    vec4 modelmatrixx;
    vec4 modelmatrixy;
    vec4 modelmatrixz;
    vec4 skinoffsets;
    vec4 gpuambientparms;
} freqHigh_vertexUniforms;

layout(set = 0, binding = 2, std140) uniform matrices_ubo
{
    vec4 matrices[768];
} _198;

layout(set = 0, binding = 3) uniform sampler3D samp_ambientatlas;
layout(set = 0, binding = 4) uniform sampler3D samp_ambientshatlas;

layout(location = 0) in vec4 in_Position;
layout(location = 2) in vec4 in_Normal;
layout(location = 9) in vec4 in_Tangent;
layout(location = 3) in vec4 in_Color;
layout(location = 3) out vec4 vofi_TexCoord1;
layout(location = 4) out vec4 vofi_TexCoord2;
layout(location = 5) out vec4 vofi_TexCoord3;
layout(location = 6) out vec4 vofi_TexCoord4;
layout(location = 2) out vec4 vofi_TexCoord0;
layout(location = 1) in vec2 in_TexCoord;
layout(location = 10) out vec4 vofi_TexCoord8;
layout(location = 11) out vec4 vofi_TexCoord9;
layout(location = 12) out vec4 vofi_TexCoord10;

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

float dot3(vec4 a, vec4 b)
{
    return dot(a.xyz, b.xyz);
}

vec3 saturate(vec3 v)
{
    return clamp(v, vec3(0.0), vec3(1.0));
}

vec4 tex3Dlod(sampler3D image, vec4 texcoord)
{
    return textureLod(image, texcoord.xyz, texcoord.w);
}

void main()
{
    vec4 localPosition = (in_Position * freqLow_vertexUniforms.vertexxyzscale) + freqLow_vertexUniforms.vertexxyzbias;
    vec4 localNormal = (in_Normal * 2.0) - vec4(1.0);
    vec4 localTangent = (in_Tangent * 2.0) - vec4(1.0);
    localTangent.w = (floor((in_Tangent.w * 255.100006103515625) / 128.0) * 2.0) - 1.0;
    float morphScale = 0.0;
    if (freqHigh_vertexUniforms.hardwareskinning.x != 0.0)
    {
        vec4 tempPosition = localPosition;
        vec4 matX = vec4(0.0);
        vec4 matY = vec4(0.0);
        vec4 matZ = vec4(0.0);
        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);
        uvec4 indices = uvec4(in_Color * 255.0);
        for (uint i = 0u; i < 4u; i++)
        {
            matX += (_198.matrices[(indices[i] * 3u) + 0u] * weights[i]);
        }
        for (uint i_1 = 0u; i_1 < 4u; i_1++)
        {
            matY += (_198.matrices[(indices[i_1] * 3u) + 1u] * weights[i_1]);
        }
        for (uint i_2 = 0u; i_2 < 4u; i_2++)
        {
            matZ += (_198.matrices[(indices[i_2] * 3u) + 2u] * weights[i_2]);
        }
        vec4 param = tempPosition;
        vec4 param_1 = matX;
        localPosition.x = dot4(param, param_1);
        vec4 param_2 = tempPosition;
        vec4 param_3 = matY;
        localPosition.y = dot4(param_2, param_3);
        vec4 param_4 = tempPosition;
        vec4 param_5 = matZ;
        localPosition.z = dot4(param_4, param_5);
        localPosition.w = 1.0;
        vec4 tempNormal = localNormal;
        vec4 param_6 = tempNormal;
        vec4 param_7 = matX;
        localNormal.x = dot3(param_6, param_7);
        vec4 param_8 = tempNormal;
        vec4 param_9 = matY;
        localNormal.y = dot3(param_8, param_9);
        vec4 param_10 = tempNormal;
        vec4 param_11 = matZ;
        localNormal.z = dot3(param_10, param_11);
        vec4 tempTangent = localTangent;
        vec4 param_12 = tempTangent;
        vec4 param_13 = matX;
        localTangent.x = dot3(param_12, param_13);
        vec4 param_14 = tempTangent;
        vec4 param_15 = matY;
        localTangent.y = dot3(param_14, param_15);
        vec4 param_16 = tempTangent;
        vec4 param_17 = matZ;
        localTangent.z = dot3(param_16, param_17);
    }
    vec3 _327 = cross(localNormal.xyz, localTangent.xyz) * localTangent.w;
    vec4 localBitangent;
    localBitangent = vec4(_327.x, _327.y, _327.z, localBitangent.w);
    localBitangent.w = 0.0;
    vec4 param_18 = localPosition;
    vec4 param_19 = freqHigh_vertexUniforms.mvpmatrixx;
    gl_Position.x = dot4(param_18, param_19);
    vec4 param_20 = localPosition;
    vec4 param_21 = freqHigh_vertexUniforms.mvpmatrixy;
    gl_Position.y = dot4(param_20, param_21);
    vec4 param_22 = localPosition;
    vec4 param_23 = freqHigh_vertexUniforms.mvpmatrixz;
    gl_Position.z = dot4(param_22, param_23);
    vec4 param_24 = localPosition;
    vec4 param_25 = freqHigh_vertexUniforms.mvpmatrixw;
    gl_Position.w = dot4(param_24, param_25);
    vec4 param_26 = localTangent;
    vec4 param_27 = freqHigh_vertexUniforms.modelmatrixx;
    vofi_TexCoord1.x = dot3(param_26, param_27);
    vec4 param_28 = localBitangent;
    vec4 param_29 = freqHigh_vertexUniforms.modelmatrixx;
    vofi_TexCoord1.y = dot3(param_28, param_29);
    vec4 param_30 = localNormal;
    vec4 param_31 = freqHigh_vertexUniforms.modelmatrixx;
    vofi_TexCoord1.z = dot3(param_30, param_31);
    vofi_TexCoord1.w = morphScale;
    vec4 param_32 = localTangent;
    vec4 param_33 = freqHigh_vertexUniforms.modelmatrixy;
    vofi_TexCoord2.x = dot3(param_32, param_33);
    vec4 param_34 = localBitangent;
    vec4 param_35 = freqHigh_vertexUniforms.modelmatrixy;
    vofi_TexCoord2.y = dot3(param_34, param_35);
    vec4 param_36 = localNormal;
    vec4 param_37 = freqHigh_vertexUniforms.modelmatrixy;
    vofi_TexCoord2.z = dot3(param_36, param_37);
    vofi_TexCoord2.w = 0.0;
    vec4 param_38 = localTangent;
    vec4 param_39 = freqHigh_vertexUniforms.modelmatrixz;
    vofi_TexCoord3.x = dot3(param_38, param_39);
    vec4 param_40 = localBitangent;
    vec4 param_41 = freqHigh_vertexUniforms.modelmatrixz;
    vofi_TexCoord3.y = dot3(param_40, param_41);
    vec4 param_42 = localNormal;
    vec4 param_43 = freqHigh_vertexUniforms.modelmatrixz;
    vofi_TexCoord3.z = dot3(param_42, param_43);
    vofi_TexCoord3.w = 0.0;
    vec4 param_44 = localPosition;
    vec4 param_45 = freqHigh_vertexUniforms.modelmatrixx;
    vec4 globalPosition;
    globalPosition.x = dot4(param_44, param_45);
    vec4 param_46 = localPosition;
    vec4 param_47 = freqHigh_vertexUniforms.modelmatrixy;
    globalPosition.y = dot4(param_46, param_47);
    vec4 param_48 = localPosition;
    vec4 param_49 = freqHigh_vertexUniforms.modelmatrixz;
    globalPosition.z = dot4(param_48, param_49);
    globalPosition.w = 1.0;
    vofi_TexCoord4 = globalPosition - freqLow_vertexUniforms.globalvieworigin;
    vofi_TexCoord0 = ((in_TexCoord.xyxy * freqLow_vertexUniforms.vertexstscalebias.xyxy) + freqLow_vertexUniforms.vertexstscalebias.zwzw) + freqHigh_vertexUniforms.skinoffsets;
    vec3 worldPos = vofi_TexCoord4.xyz + freqLow_vertexUniforms.globalvieworigin.xyz;
    bool _497 = freqHigh_vertexUniforms.gpuambientparms.x > 0.0;
    bool _503;
    if (_497)
    {
        _503 = freqHigh_vertexUniforms.gpuambientparms.y > 0.0;
    }
    else
    {
        _503 = _497;
    }
    if (_503)
    {
        float AMBIENT_MIN_WORLD = -32768.0;
        float AMBIENT_MAX_WORLD = 32768.0;
        float ambientAtlasWidth = 256.0;
        float ambientAtlasHeight = 256.0;
        float ambientAtlasDepth = 32.0;
        float ambientSHAtlasWidth = 256.0;
        float ambientSHAtlasHeight = 256.0;
        float ambientSHAtlasDepth = 96.0;
        vec3 atlasSHPixelSize = vec3(1.0 / ambientSHAtlasWidth, 1.0 / ambientSHAtlasHeight, 1.0 / ambientSHAtlasDepth);
        vec3 atlasSHCubeSize = vec3(2.0 / ambientSHAtlasWidth, 2.0 / ambientSHAtlasHeight, 2.0 / ambientSHAtlasDepth);
        vec3 atlasPixelSize = vec3(1.0 / ambientAtlasWidth, 1.0 / ambientAtlasHeight, 1.0 / ambientAtlasDepth);
        float leafWidth = 1.0 / (AMBIENT_MAX_WORLD - AMBIENT_MIN_WORLD);
        vec3 param_50 = (worldPos - vec3(AMBIENT_MIN_WORLD)) * leafWidth;
        vec3 normSamplePoint = saturate(param_50);
        vec4 atlasSample = vec4(0.0);
        uvec3 octantIndices = uvec3(0u);
        for (uint i_3 = 0u; i_3 < 10u; i_3++)
        {
            vec3 atlasQuadrant = vec3(0.5) + floor(vec3(2.0) * normSamplePoint);
            vec4 atlasTC = vec4(atlasPixelSize * (vec3(octantIndices) + atlasQuadrant), 0.0);
            vec4 param_51 = atlasTC;
            atlasSample = tex3Dlod(samp_ambientatlas, param_51);
            normSamplePoint = fract(normSamplePoint * vec3(2.0));
            octantIndices = uvec3(atlasSample.zyx * vec3(255.0));
            if (atlasSample.w > 0.0)
            {
                break;
            }
        }
        uint ambientSHHashKey = (((uint(atlasSample.w * 255.0) << uint(24)) | (uint(atlasSample.z * 255.0) << uint(16))) | (uint(atlasSample.y * 255.0) << uint(8))) | uint(atlasSample.x * 255.0);
        uvec3 ambientSHKey = uvec3((ambientSHHashKey >> uint(19)) & 4095u, (ambientSHHashKey >> uint(7)) & 4095u, ambientSHHashKey & 127u);
        vec3 shQuadrant = vec3(2.0) * ((normSamplePoint * vec3(0.5)) + vec3(0.25));
        vec4 shTC = vec4(atlasSHPixelSize * (vec3(ambientSHKey) + shQuadrant), 0.0);
        vec4 param_52 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 0.0), 0.0);
        vec4 sampleSHR = tex3Dlod(samp_ambientshatlas, param_52) * freqHigh_vertexUniforms.gpuambientparms.y;
        vec4 param_53 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 1.0), 0.0);
        vec4 sampleSHG = tex3Dlod(samp_ambientshatlas, param_53) * freqHigh_vertexUniforms.gpuambientparms.y;
        vec4 param_54 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 2.0), 0.0);
        vec4 sampleSHB = tex3Dlod(samp_ambientshatlas, param_54) * freqHigh_vertexUniforms.gpuambientparms.y;
        vofi_TexCoord8 = vec4(sampleSHR.x, sampleSHG.x, sampleSHB.x, sampleSHR.y);
        vofi_TexCoord9 = vec4(sampleSHG.y, sampleSHB.y, sampleSHR.z, sampleSHG.z);
        vofi_TexCoord10 = vec4(sampleSHB.z, sampleSHR.w, sampleSHG.w, sampleSHB.w);
    }
    else
    {
        vofi_TexCoord8 = vec4(0.0);
        vofi_TexCoord9 = vec4(0.0);
        vofi_TexCoord10 = vec4(0.0);
    }
    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.stereo.y * 0.65) * 0.75;
}
else
{
    gl_Position.x += vk3d_params.stereo.x * (gl_Position.w - vk3d_params.stereo.y);
} 
}


