77 lines
2.5 KiB
GLSL
77 lines
2.5 KiB
GLSL
#version 300 es
|
||
|
||
precision mediump float;
|
||
|
||
layout(std140)uniform Uniforms{
|
||
float startTimestamp; // Unix 时间戳开始
|
||
float endTimestamp; // Unix 时间戳结束
|
||
float currentTimestamp; // 当前时间戳
|
||
float radius;
|
||
float d;
|
||
float timelineStartX; // 时间轴在屏幕上的开始X坐标
|
||
float timelineEndX; // 时间轴在屏幕上的结束X坐标
|
||
float padding1; // 填充以对齐到8字节边界
|
||
vec2 viewportSize;
|
||
float zoomLevel; // 当前缩放级别
|
||
float panOffset; // 当前平移偏移
|
||
};
|
||
|
||
struct Instant{
|
||
vec2 position;
|
||
vec4 color;
|
||
};
|
||
|
||
in Instant i_instant;
|
||
|
||
out vec4 FragColor;
|
||
|
||
float sdVesica(vec2 p,float r,float d)
|
||
{
|
||
p=abs(p);
|
||
float b=sqrt(r*r-d*d);// can delay this sqrt by rewriting the comparison
|
||
return((p.y-b)*d>p.x*b)?length(p-vec2(0.,b))*sign(d)
|
||
:length(p-vec2(-d,0.))-r;
|
||
}
|
||
|
||
void main(){
|
||
// 从实例数据中获取时间戳(存储在position.x中)和Y坐标(存储在position.y中)
|
||
float timestamp = i_instant.position.x;
|
||
float centerY = i_instant.position.y;
|
||
|
||
// 计算时间戳在时间轴范围内的相对位置(0-1)
|
||
float timeProgress = (timestamp - startTimestamp) / (endTimestamp - startTimestamp);
|
||
|
||
// 考虑缩放和平移,计算屏幕X坐标
|
||
float timelineWidth = timelineEndX - timelineStartX;
|
||
float scaledTimelineWidth = timelineWidth * zoomLevel;
|
||
float screenX = timelineStartX + panOffset + timeProgress * scaledTimelineWidth;
|
||
|
||
// 如果vesica在屏幕外,提前丢弃
|
||
if (screenX < -radius*2.0 || screenX > viewportSize.x + radius*2.0) {
|
||
discard;
|
||
}
|
||
|
||
// 计算vesica在屏幕上的实际位置
|
||
vec2 vesicaCenter = vec2(screenX, centerY);
|
||
vec2 p = gl_FragCoord.xy - vesicaCenter;
|
||
float sdf = sdVesica(p, radius, d);
|
||
|
||
// 使用fwidth计算像素梯度,实现自适应反锯齿
|
||
float fw = fwidth(sdf);
|
||
|
||
// 在高分屏下增强反锯齿效果 (可根据需要调整系数)
|
||
float aaWidth = max(fw, 0.5); // 确保最小反锯齿宽度
|
||
|
||
// 使用smoothstep创建平滑边缘,aaWidth控制反锯齿宽度
|
||
float alpha = 1.0 - smoothstep(-aaWidth, aaWidth, sdf);
|
||
|
||
// 如果完全透明就丢弃片段以提高性能
|
||
if (alpha < 0.001) {
|
||
discard;
|
||
}
|
||
|
||
// 使用实例颜色并应用计算出的alpha
|
||
vec3 color = i_instant.color.rgb;
|
||
FragColor = vec4(color, alpha * i_instant.color.a);
|
||
}
|