#include "mirage_util.slang"

struct ParamBuffer
{
    matrix transform;
};
ParameterBlock<ParamBuffer> param_buffer : register(b1);

struct PSInput {
    float4 position : SV_POSITION;   // 裁剪空间坐标
    float2 uv : TEXCOORD0;           // 传递UV
    float4 color : COLOR;            // 颜色
    float2 windowPos : TEXCOORD1;    // 窗口像素坐标
    float lineWidth : TEXCOORD2;     // 线段宽度
    float4 linePoints : TEXCOORD3;   // xy: 线段起点, zw: 线段终点 (窗口坐标)
};

// 优化的点到线段距离计算
float distanceToLine(float2 p, float2 a, float2 b) {
    float2 pa = p - a;
    float2 ba = b - a;
    float h = saturate(dot(pa, ba) / dot(ba, ba));
    return length(pa - h * ba);
}

[shader("vertex")]
PSInput vertex_main(VSInput input)
{
    PSInput output;
    
    // 保存原始窗口坐标，用于SDF计算
    output.windowPos = input.position;
    
    // 变换顶点位置到裁剪空间
    output.position = mul(float4(input.position, 0, 1.0), param_buffer.transform);
    
    // 传递标准属性
    output.uv = input.uv;
    output.color = input.color;
    
    // 传递线段特定参数
    output.lineWidth = input.param_a.x;
    output.linePoints = input.param_b; // 线段端点(窗口坐标)
    
    return output;
}

[shader("pixel")]
float4 pixel_main(PSInput input) : SV_TARGET
{
    // 获取窗口坐标下的当前像素位置和线段数据
    float2 pixelPos = input.windowPos;
    float2 lineStart = input.linePoints.xy;
    float2 lineEnd = input.linePoints.zw;
    float lineWidth = input.lineWidth;
    
    // 计算到线段的距离 (全部在窗口坐标系中)
    float dist = distanceToLine(pixelPos, lineStart, lineEnd);
    
    // 应用抗锯齿
    float halfWidth = lineWidth * 0.5;
    float aaWidth = max(1.0, fwidth(dist));
    
    // 平滑过渡 
    float alpha = 1.0 - smoothstep(halfWidth - aaWidth, halfWidth + aaWidth, dist);
    
    // 应用alpha到颜色
    float4 finalColor = input.color;
    finalColor.a *= alpha;
    
    // 完全透明则丢弃
    if (finalColor.a < 0.001) {
        discard;
    }

    return finalColor;
}
