#version 450 core

// inputs
layout (location = 0) in vec4 vPos0;
layout (location = 1) in vec4 vPos1;

layout (location = 2) in vec4 vColor0;
layout (location = 3) in vec4 vColor1;

uniform vec2    g_layerWeights;
uniform float   g_time;
uniform mat4    m_proj;
uniform mat4    m_rotate;

// outputs
out vec4 color;

mat2 rotate(float a) {return mat2(cos(a), -sin(a), sin(a), cos(a));}

vec3 rotateXYZ(vec3 o, vec3 a) {
    o.yz *= rotate(a.x);
    o.zx *= rotate(a.y);
    o.xy *= rotate(a.z);
    return o;
}

float rand(vec3 co){
    return fract(sin(dot(co, vec3(12.9898, 78.233, 16.4495))) * 43758.5453)-.5;
}

const mat3 magic = 0.001*mat3(vec3(111, 3141, 2718), vec3(4524, 6455, 6723), vec3(4367, 453, 354));

void main(){
    vec3 blendPos = (vPos0 * g_layerWeights.x + vPos1 * g_layerWeights.y).xyz;

    // get uniform rand 
    mat3 seed = mat3(gl_InstanceID*magic[0], gl_InstanceID*magic[1], gl_InstanceID*magic[2]);

    vec3 randPos = 20*pow(rand(vec3(seed[0].z, seed[2].y, seed[1].x)), 0.3)*normalize(vec3(
        rand(vec3(seed[0].x, seed[1].y, seed[2].z)),
        rand(vec3(seed[1].x, seed[0].z, seed[2].y)),
        rand(vec3(seed[2].y, seed[1].x, seed[0].z))
    ));
    
	vec3 rotator = vec3(
    	g_time*0.3+0.30*cos(gl_InstanceID*0.005),
    	g_time*0.3+0.21*cos(gl_InstanceID*0.03),
    	g_time*0.3+0.13*cos(gl_InstanceID*0.05)
    );
    // rotate each instance
    blendPos = rotateXYZ(blendPos, vec3(seed[0].y, seed[2].x, seed[1].z) + rotator);
	blendPos += 0.*vec3(
    	sin(g_time*1.2+0.30*cos(gl_VertexID*0.004)),
    	cos(g_time*1.2+0.23*cos(gl_VertexID*0.014)),
    	sin(g_time*1.2+0.28*cos(gl_VertexID*0.004))
    );

    gl_Position = m_proj * vec4(blendPos.xyz + randPos, 1.0);
    color = (vColor0 * g_layerWeights.x + vColor1 * g_layerWeights.y);
    
}


