
#ifdef VERTEX_SHADER
layout (location = 0) in vec3 aPos;  // Vertex position
layout (location = 1) in vec4 aColor; // Vertex color
layout (location = 2) in vec2 aTexcoord; // Texture coords

uniform mat4 modelMatrix; // Model matrix,
uniform mat4 viewMatrix; // View matrix
uniform mat4 projectionMatrix; // Projection matrix

out vec4 vertexColor; // Output color to fragment shader
out vec2 texCoord; // Output texture coords

void main() {
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(aPos, 1.0f);
    vertexColor = aColor; // Pass color to fragment shader
    texCoord = aTexcoord; // Pass texture coords to fragment shader
}

#endif // VERTEX_SHADER

#ifdef FRAGMENT_SHADER
// Fragment Shader source

in vec4 vertexColor; // Input color from vertex shader
in vec2 texCoord; // Input texture coords
out vec4 FragColor; // Final output color

uniform sampler2D tex; // Texture sampler


float median(vec3 v) 
{
    return max(min(v.x, v.y), min(max(v.x, v.y), v.z));
}

float screenPxRange() {
    float pxRange = 2.0;
    vec2 unitRange = vec2(pxRange)/vec2(textureSize(tex, 0));
    vec2 screenTexSize = vec2(1.0)/fwidth(texCoord);
    return max(0.5*dot(unitRange, screenTexSize), 1.0);
}

void main() {
    vec3 msd = texture(tex, texCoord).rgb;
    
    float sd = median(msd.rgb);
    float screenPxDistance = screenPxRange()*(sd - 0.5);
    float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0);
    vec4 fgColor = vec4(vertexColor.rgb, opacity*vertexColor.a);
    vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);
    FragColor = mix(bgColor, fgColor, opacity);
}

#endif // FRAGMENT_SHADER