
// Vk3DVision (http://3dsurroundgaming.com/) - Original Shader
#version 450

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

layout(set = 0, binding = 1, std140) uniform freqLow_vertexUniforms_ubo
{
    vec4 globalviewfwd;
    vec4 particlestscalebias;
} freqLow_vertexUniforms;

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

layout(location = 12) in vec2 in_VmtrTC;
layout(location = 0) in vec4 in_Position;
layout(location = 2) in vec4 in_Normal;
layout(location = 9) in vec4 in_Tangent;
layout(location = 13) in vec4 in_VmtrSB;
layout(location = 2) out vec4 vofi_TexCoord0;
layout(location = 1) in vec2 in_TexCoord;
layout(location = 4) in vec2 in_TexCoord1;
layout(location = 3) out vec4 vofi_TexCoord1;
layout(location = 3) in vec4 in_Color;
layout(location = 0) out vec4 vofi_Color;
layout(location = 4) out vec4 vofi_TexCoord2;
layout(location = 5) out vec4 vofi_TexCoord3;
layout(location = 6) out vec4 vofi_TexCoord4;
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);
}

vec3 DecodeParticleNormal(vec3 vertexN, vec3 camFront, float particle_curvature)
{
    vec3 normal = ((vertexN / vec3(255.0)) * 2.0) - vec3(1.0);
    return mix(-camFront, normal, vec3(particle_curvature));
}

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

float SRGBlinearApprox(float value)
{
    return value * ((value * ((value * 0.305306017398834228515625) + 0.6821711063385009765625)) + 0.01252287812530994415283203125);
}

vec3 SRGBlinearApprox(vec3 sRGB)
{
    float param = sRGB.x;
    vec3 outLinear;
    outLinear.x = SRGBlinearApprox(param);
    float param_1 = sRGB.y;
    outLinear.y = SRGBlinearApprox(param_1);
    float param_2 = sRGB.z;
    outLinear.z = SRGBlinearApprox(param_2);
    return outLinear;
}

vec4 SRGBlinearApprox(vec4 sRGBA)
{
    vec3 param = sRGBA.xyz;
    vec4 outLinear = vec4(SRGBlinearApprox(param), 1.0);
    float param_1 = sRGBA.w;
    outLinear.w = SRGBlinearApprox(param_1);
    return outLinear;
}

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()
{
    vec2 atlasTilePos = vec2(in_VmtrTC.x, in_VmtrTC.y);
    gl_Position = vec4((atlasTilePos * 2.0) - vec2(1.0), vec2(0.0, 1.0));
    vec4 param = vec4(in_Position.xyz, 1.0);
    vec4 param_1 = freqHigh_vertexUniforms.modelmatrixx;
    vec3 worldPos;
    worldPos.x = dot4(param, param_1);
    vec4 param_2 = vec4(in_Position.xyz, 1.0);
    vec4 param_3 = freqHigh_vertexUniforms.modelmatrixy;
    worldPos.y = dot4(param_2, param_3);
    vec4 param_4 = vec4(in_Position.xyz, 1.0);
    vec4 param_5 = freqHigh_vertexUniforms.modelmatrixz;
    worldPos.z = dot4(param_4, param_5);
    float emmissiveMul = (in_Normal.x * 10.0) + 1.0;
    float alphaMul = (in_Normal.y * 10.0) + 1.0;
    float alphaFade = in_Normal.w;
    float eyeDist = gl_Position.w;
    bool facingCamera = in_Tangent.y > 0.0;
    float frameFrac = in_Tangent.z;
    float depthAlphaMul = in_Tangent.w;
    float particle_curvature = in_Tangent.x;
    vec3 param_6 = in_VmtrSB.xyz;
    vec3 param_7 = freqLow_vertexUniforms.globalviewfwd.xyz;
    float param_8 = particle_curvature;
    vec3 normal = DecodeParticleNormal(param_6, param_7, param_8);
    float thickness = ((1.0 - depthAlphaMul) * 127.0) / eyeDist;
    vec2 _286 = (in_TexCoord * freqLow_vertexUniforms.particlestscalebias.x) + vec2(freqLow_vertexUniforms.particlestscalebias.y);
    vofi_TexCoord0 = vec4(_286.x, _286.y, vofi_TexCoord0.z, vofi_TexCoord0.w);
    vec2 _297 = (in_TexCoord1 * freqLow_vertexUniforms.particlestscalebias.x) + vec2(freqLow_vertexUniforms.particlestscalebias.y);
    vofi_TexCoord0 = vec4(vofi_TexCoord0.x, vofi_TexCoord0.y, _297.x, _297.y);
    vofi_TexCoord1.x = 0.0;
    vofi_TexCoord1.y = depthAlphaMul;
    vofi_TexCoord1.z = frameFrac;
    vofi_TexCoord1.w = alphaFade;
    float param_9 = abs(eyeDist) / ((1.0 - depthAlphaMul) * 127.0);
    float particleFade = saturate(param_9);
    vec4 param_10 = in_Color;
    vec4 vtxcol = SRGBlinearApprox(param_10);
    vofi_Color = vec4(vtxcol.xyz.x, vtxcol.xyz.y, vtxcol.xyz.z, vofi_Color.w);
    vofi_Color.w = (particleFade * vtxcol.w) * alphaMul;
    vofi_TexCoord2 = vec4(worldPos, 0.0);
    vofi_TexCoord3 = vec4(normal, 0.0);
    vofi_TexCoord4 = vec4(dot(vec4(in_Position.xyz, 1.0), freqHigh_vertexUniforms.mvpmatrixx), dot(vec4(in_Position.xyz, 1.0), freqHigh_vertexUniforms.mvpmatrixy), dot(vec4(in_Position.xyz, 1.0), freqHigh_vertexUniforms.mvpmatrixz), dot(vec4(in_Position.xyz, 1.0), freqHigh_vertexUniforms.mvpmatrixw));
    bool _391 = freqHigh_vertexUniforms.gpuambientparms.x > 0.0;
    bool _397;
    if (_391)
    {
        _397 = freqHigh_vertexUniforms.gpuambientparms.y > 0.0;
    }
    else
    {
        _397 = _391;
    }
    if (_397)
    {
        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_11 = (worldPos - vec3(AMBIENT_MIN_WORLD)) * leafWidth;
        vec3 normSamplePoint = saturate(param_11);
        vec4 atlasSample = vec4(0.0);
        uvec3 octantIndices = uvec3(0u);
        for (uint i = 0u; i < 10u; i++)
        {
            vec3 atlasQuadrant = vec3(0.5) + floor(vec3(2.0) * normSamplePoint);
            vec4 atlasTC = vec4(atlasPixelSize * (vec3(octantIndices) + atlasQuadrant), 0.0);
            vec4 param_12 = atlasTC;
            atlasSample = tex3Dlod(samp_ambientatlas, param_12);
            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_13 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 0.0), 0.0);
        vec4 sampleSHR = tex3Dlod(samp_ambientshatlas, param_13) * freqHigh_vertexUniforms.gpuambientparms.y;
        vec4 param_14 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 1.0), 0.0);
        vec4 sampleSHG = tex3Dlod(samp_ambientshatlas, param_14) * freqHigh_vertexUniforms.gpuambientparms.y;
        vec4 param_15 = vec4(shTC.xy, shTC.z + (atlasSHCubeSize.z * 2.0), 0.0);
        vec4 sampleSHB = tex3Dlod(samp_ambientshatlas, param_15) * 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;
}

