//Shadows VS 3.
#version 450
#extension GL_EXT_nonuniform_qualifier : require

struct FlrInput
{
    vec3 position;
    vec2 uv0;
    vec3 normal;
    vec4 tangent;
    vec4 color;
    uvec4 blendIndices;
    vec4 blendWeights;
    uint instanceIndex;
    uint instancingBufferOffset;
    uint skinningBufferOffset;
};

struct FlrOutput
{
    vec4 position;
    vec2 uv0;
    vec3 posWS;
    vec3 normal;
    vec4 tangent;
    vec3 binormal;
    vec4 color;
    vec4 prevPosition;
};

struct IndirectionData
{
    uint globalInstanceIndex;
};

struct VegetationSkinningBufferEntry
{
    mat3x4 transform;
    vec4 tint;
};


// 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 = 1, std140) uniform PerFrame
{
    vec4 frameParameters0;
    vec4 frameParameters1;
    vec4 projectionOffsets;
} _32;

layout(set = 0, binding = 7, std430) readonly buffer InstanceIndirectionBuffer
{
    IndirectionData _InstanceIndirectionBuffer[];
} _69;

layout(set = 0, binding = 5, std430) readonly buffer InstancingBuffer
{
    mat3x4 _InstancingBuffer[];
} _86;

layout(set = 0, binding = 0, std140) uniform PerInstance
{
    mat4 worldMatrix;
    mat4 prevWorldMatrix;
    uvec4 params0;
} _125;

layout(set = 0, binding = 3, std140) uniform PerView
{
    mat4 viewProjMatrix;
    mat4 prevViewProjMatrix;
    vec4 cameraPositionWS;
} _171;

layout(set = 0, binding = 2, std140) uniform PerMaterial
{
    uvec4 paramIntData0;
    vec4 tint;
    vec4 parameters0;
    vec4 uvTransform;
    vec4 paramData3;
    vec4 normalParams;
    vec4 paramData5;
    vec4 paramData6;
    vec4 paramData7;
    vec4 paramData8;
    vec4 paramData9;
    uvec4 paramImgIDs0;
    uvec4 paramImgIDs1;
    uvec4 paramImgIDs2;
} _311;

layout(set = 0, binding = 4, std430) readonly buffer SkinningBuffer
{
    mat3x4 _SkinningBuffer[];
} _315;

layout(set = 0, binding = 6, std430) readonly buffer VegetationSkinningBuffer
{
    VegetationSkinningBufferEntry _VegetationSkinningBuffer[];
} _320;

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

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 = 0) in vec4 inPosition;
layout(location = 1) in vec2 inUV0;
layout(location = 4) in uvec4 inBlendIndices;
layout(location = 5) in vec4 inBlendWeights;
layout(location = 2) in vec4 inNormal;
layout(location = 3) in vec4 inTangent;
layout(location = 6) in vec4 inColor;
layout(location = 1) out vec2 outUV0;
layout(location = 4) out vec3 outPosWS;

void flrMain(FlrInput flrInput, inout FlrOutput flrOutput)
{
    flrOutput.color = flrInput.color;
    uint currFrameID = floatBitsToUint(_32.frameParameters0.w);
    uint prevFrameID = (currFrameID + 1u) % 2u;
    vec3 localPos = flrInput.position;
    vec3 prevLocalPos = flrInput.position;
    vec3 localNormal = flrInput.normal;
    vec3 localTangent = flrInput.tangent.xyz;
    vec3 objectPositionWS = vec3(0.0);
    uint instanceIndex = _69._InstanceIndirectionBuffer[flrInput.instanceIndex + flrInput.instancingBufferOffset].globalInstanceIndex;
    mat3x4 instanceWorldMatrix = _86._InstancingBuffer[instanceIndex];
    localPos = vec4(localPos, 1.0) * instanceWorldMatrix;
    prevLocalPos = localPos;
    localNormal = vec4(localNormal, 0.0) * instanceWorldMatrix;
    localTangent = vec4(localTangent, 0.0) * instanceWorldMatrix;
    objectPositionWS = vec4(objectPositionWS, 1.0) * instanceWorldMatrix;
    vec3 normalWS = normalize((_125.worldMatrix * vec4(localNormal, 0.0)).xyz);
    vec3 posWS = (_125.worldMatrix * vec4(localPos, 1.0)).xyz;
    vec3 prevPosWS = (_125.prevWorldMatrix * vec4(prevLocalPos, 1.0)).xyz;
    vec3 prevNormalWS = normalize((_125.prevWorldMatrix * vec4(localNormal, 0.0)).xyz);
    flrOutput.position = _171.viewProjMatrix * vec4(posWS, 1.0);
    flrOutput.normal = normalWS;
    vec3 _192 = normalize((_125.worldMatrix * vec4(localTangent, 0.0)).xyz);
    flrOutput.tangent = vec4(_192.x, _192.y, _192.z, flrOutput.tangent.w);
    flrOutput.tangent.w = flrInput.tangent.w;
    flrOutput.binormal = cross(flrOutput.normal, flrOutput.tangent.xyz) * flrInput.tangent.w;
    flrOutput.prevPosition = vec4(0.0);
    flrOutput.posWS = posWS;
    flrOutput.uv0 = flrInput.uv0;
    flrOutput.prevPosition = _171.prevViewProjMatrix * vec4(prevPosWS, 1.0);
}

void main()
{
    FlrInput flrInput;
    flrInput.instanceIndex = uint(gl_InstanceIndex);
    flrInput.position = inPosition.xyz;
    flrInput.uv0 = inUV0;
    flrInput.blendIndices = inBlendIndices;
    flrInput.blendWeights = inBlendWeights;
    flrInput.normal = inNormal.xyz;
    flrInput.tangent = inTangent;
    flrInput.color = inColor;
    flrInput.skinningBufferOffset = _125.params0.x;
    flrInput.instancingBufferOffset = _125.params0.y;
    FlrInput param = flrInput;
    FlrOutput param_1;
    flrMain(param, param_1);
    FlrOutput flrOutput = param_1;
    gl_Position = flrOutput.position;

// Vk3DVision (http://3dsurroundgaming.com/) - Stereo Injection
//if (gl_Position.w!=1) {
//gl_Position.x += vk3d_params.stereo.x * (gl_Position.w - vk3d_params.stereo.y);
//} 
    outUV0 = flrOutput.uv0;
    outPosWS = flrOutput.posWS;
}



