要在 Fragment Shader 中绘制一条线,我们应该检查当前像素 (UV) 是否在该线的位置上。 (仅使用片段着色器代码效率不高!这仅用于使用 glslsandbox 进行测试)
一个可接受的 UV 点应具备以下两个条件:
1- (uv, pt1) 之间的最大允许距离应小于 (pt1, pt2) 之间的距离。
在这种情况下,我们创建了一个以 pt2 为中心且radious = distance(pt2, pt1) 的假设圆,并且还防止绘制比距离(pt2, pt1) 更长的线。
2- 对于每个 UV,我们假设一个假设圆,其连接点位于线的 ptc 位置 (pt2,pt1)。
如果UV和PTC之间的距离小于线的刻度,我们选择这个UV作为线点。
在我们的代码中:
r = distance (uv, pt1) / distance (pt1, pt2) 给我们一个介于 0 和 1 之间的值。
我们在 pt1 和 pt2 之间插入一个点 (ptc),其值为 r
代码:
#ifdef GL_ES
precision mediump float;
#endif
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
float line(vec2 uv, vec2 pt1, vec2 pt2,vec2 resolution)
{
float clrFactor = 0.0;
float tickness = 3.0 / max(resolution.x, resolution.y); //only used for tickness
float r = distance(uv, pt1) / distance(pt1, pt2);
if(r <= 1.0) // if desired Hypothetical circle in range of vector(pt2,pt1)
{
vec2 ptc = mix(pt1, pt2, r); // ptc = connection point of Hypothetical circle and line calculated with interpolation
float dist = distance(ptc, uv); // distance betwenn current pixel (uv) and ptc
if(dist < tickness / 2.0)
{
clrFactor = 1.0;
}
}
return clrFactor;
}
void main()
{
vec2 uv = gl_FragCoord.xy / resolution.xy; //current point
//uv = current pixel
// 0 < uv.x < 1 , 0 < uv.x < 1
// left-down= (0,0)
// right-top= (1,1)
vec2 pt1 = vec2(0.1, 0.1); //line point1
vec2 pt2 = vec2(0.8, 0.7); //line point2
float lineFactor = line(uv, pt1, pt2, resolution.xy);
vec3 color = vec3(.5, 0.7 , 1.0);
gl_FragColor = vec4(color * lineFactor , 1.);
}