#type vertex
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;

out vec2 TexCoords;

void main() {
TexCoords = aTexCoords;    
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 
}

#type fragment
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;

uniform sampler2D noise;

uniform float t;
uniform float vPosition;
uniform float vSpeed;
uniform float hSpeed;
uniform float order;
uniform float intensity;
uniform float gaze;

uniform float coreIntensity;
uniform float borderIntensity;
uniform float smokeIntensity;

uniform vec3 coreColor;
uniform vec3 borderColor;
uniform vec3 smokeColor;

float fbm(vec2 at, float n) {
float s = sin(0.45);
float c = cos(0.45);
mat2 r = mat2(vec2(s, c), vec2(-c, s));

float f = 0.0;
float amp = 1.0;
for (int i = 0; i < n; i++) {
f += amp * texture(noise, at).z;
at *= 2.0;
at = r * at;
amp *= 0.5;
}
return f;
}

void main() {
vec2 uv = TexCoords;

uv.x *= 2.5;

uv.y -= vPosition;

vec2 off = vec2(-hSpeed/100.0, -vSpeed/100.0) * t * sign(uv.y);

float distX = fbm(uv * 0.05 + t * 0.01, order);
float distY = fbm(uv * 0.05 + t * 0.01 + 50.0, order);
vec2 distortion = (vec2(distX, distY * 0.7) - 0.5) * 0.005;

float bottom = pow(abs(1.0 - uv.y), 1.3);

float f = fbm(uv * 0.03 + off * 0.5 + distortion * bottom, order);
f += fbm(uv * 0.03 + off, order) * 0.2;;

f -= pow(abs(uv.y), intensity);
f = max(f, 0.0);

float core = pow(f -  0.1, coreIntensity);
float border = pow(f - 0.05, borderIntensity);
float smoke = pow(f, smokeIntensity);

smoke -= border;
border -= core;

vec3 col;
col  = coreColor   * core;
col += borderColor * border;
col += smokeColor  * smoke;

col.rgb += pow((1.0 - abs(uv.y)), 1.0/gaze);

// Output to screen
FragColor = vec4(col.rgb, 1.0);
}