#version 300 es

precision highp float;


in vec2 v_originTexCoord;
out vec4 fragColor;

uniform sampler2D uMainTex;
uniform vec2 uTexelSize;
uniform vec3 edgeColor;
uniform float edgeWidth;
uniform float edgeThreshold;

void main()
{
    // Add early return when edgeWidth is 0
    if (edgeWidth <= 0.0) {
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
        return;
    }

    vec2 TexCoords = vec2(v_originTexCoord.x, 1.0 - v_originTexCoord.y);  // 调整纹理坐标

    // Sobel 算子的偏移量
    vec2 offsets[9];
    offsets[0] = vec2(-1.0,  1.0);
    offsets[1] = vec2( 0.0,  1.0);
    offsets[2] = vec2( 1.0,  1.0);
    offsets[3] = vec2(-1.0,  0.0);
    offsets[4] = vec2( 0.0,  0.0);
    offsets[5] = vec2( 1.0,  0.0);
    offsets[6] = vec2(-1.0, -1.0);
    offsets[7] = vec2( 0.0, -1.0);
    offsets[8] = vec2( 1.0, -1.0);

    // Sobel 算子 X 和 Y 方向的卷积核
    float kernelX[9];
    kernelX[0] = -1.0; kernelX[1] = 0.0; kernelX[2] = 1.0;
    kernelX[3] = -2.0; kernelX[4] = 0.0; kernelX[5] = 2.0;
    kernelX[6] = -1.0; kernelX[7] = 0.0; kernelX[8] = 1.0;

    float kernelY[9];
    kernelY[0] =  1.0; kernelY[1] =  2.0; kernelY[2] =  1.0;
    kernelY[3] =  0.0; kernelY[4] =  0.0; kernelY[5] =  0.0;
    kernelY[6] = -1.0; kernelY[7] = -2.0; kernelY[8] = -1.0;

    float depth[9];
    float alpha[9];  // 存储透明度数据
    vec2 texelOffset = uTexelSize * edgeWidth;  // 根据边缘宽度调整偏移量

    // 计算 Sobel 边缘强度和透明度梯度
    float sobelX = 0.0;
    float sobelY = 0.0;
    float alphaX = 0.0;
    float alphaY = 0.0;

    for (int i = 0; i < 9; i++)
    {
        // 计算纹理坐标，避免越界
        vec2 offsetCoord = TexCoords + offsets[i] * texelOffset;
        offsetCoord = clamp(offsetCoord, vec2(0.001), vec2(0.999)); // 确保坐标在有效范围内

        // 采样颜色和透明度
        vec4 texColor = texture(uMainTex, offsetCoord);
        depth[i] = texColor.r;  // 获取颜色信息
        alpha[i] = texColor.a;  // 获取透明度信息

        // Sobel X 和 Y 方向的卷积计算
        sobelX += depth[i] * kernelX[i];
        sobelY += depth[i] * kernelY[i];

        // 透明度的梯度
        alphaX += alpha[i] * kernelX[i];
        alphaY += alpha[i] * kernelY[i];
    }

    // 计算总的边缘强度
    float edge = length(vec2(sobelX, sobelY));
    float alphaEdge = length(vec2(alphaX, alphaY));

    // 综合考虑颜色边缘和透明度边缘的强度
    float totalEdge = max(edge, alphaEdge);  // 选择最强的边缘

    // 调整边缘强度（放大范围）
    edge = clamp(totalEdge * 20.0, 0.0, 1.0);

    // 改进的边缘处理（抗锯齿）：减小边缘过渡区的阈值，平滑过渡
    float edgeSmooth = smoothstep(edgeThreshold - 0.03, edgeThreshold + 0.03, edge);

    // 获取原图的颜色
    vec4 originalColor = texture(uMainTex, TexCoords);

    // 如果边缘强度足够，则显示边缘效果，否则显示白色内部
    if (edgeSmooth > 0.0) {
        // 计算边缘的颜色
        vec4 edgeColorFinal = vec4(edgeColor * edgeSmooth, 1.0);
        // 混合原图和边缘：根据边缘平滑度决定显示原图或边缘效果
        fragColor = mix(originalColor, edgeColorFinal, edgeSmooth);
    } else if (originalColor.a > 0.0) {
        // 非边缘区域且原图不透明的地方显示白色
        fragColor = vec4(0.05, 0.05, 0.05, originalColor.a);
    } else {
        // 完全透明的区域保持透明
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
    }
}