画圆
在上一期讲述smoothstep的时候,已经讲了如何绘制圆和圆环,在这里不做赘述,详情参照链接smoothstep画圆
画椭圆
画椭圆可以理解为对正圆进行x轴方向或者y轴方向的拉伸
对x轴拉伸
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
//横坐标乘以纵横比写在vertexshader中
// texCoord0.x *= (200.0/100.0);
//圆心
vec2 center = vec2(0.35, 0.5);
//x轴拉伸
texCoord0.x *= 0.7;
//半径
float radio = 0.3;
//定义边缘区间
float blur = 0.025;
float d = distance(texCoord0, center);
float d1 = 1.-smoothstep(radio - blur, radio, d);
gl_FragColor = vec4(vec3(d1, 0., 0.), 1.);
}
效果图
对y轴拉伸
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
//横坐标乘以纵横比写在vertexshader中
// texCoord0.x *= (200.0/100.0);
//圆心
vec2 center = vec2(0.5, 0.35);
//x轴拉伸
texCoord0.y *= 0.7;
//半径
float radio = 0.3;
//定义边缘区间
float blur = 0.025;
float d = distance(texCoord0, center);
float d1 = 1.-smoothstep(radio - blur, radio, d);
gl_FragColor = vec4(vec3(d1, 0., 0.), 1.);
}
效果图
画矩形
绘制矩形,就是在坐标限定在矩形四条边范围内着色,
利用if语句画矩形
void main()
{
precision mediump float;
//上下边界
float top = 0.8;
float bottom = 0.2;
//左右边界
float left = 0.2;
float right = 0.8;
float pct = 0.;
if (texCoord0.x > left && texCoord0.x < right && texCoord0.y > bottom && texCoord0.y < top)
{
pct = 0.;
}
else
{
pct = 1.;
}
gl_FragColor = vec4(vec3(pct), 1.);
}
效果图
利用smoothstep函数,对边距进行着色,除边距以外的就是矩形
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
float padding = 0.2;
//上边距为白色
float topColor = smoothstep(1. - padding, 1. - padding, texCoord0.y);
//左边距为白色
float leftColor = 1. - smoothstep(padding, padding, texCoord0.x);
//下边距为白色
float buttomColor = 1. - smoothstep(padding, padding, texCoord0.y);
//右边距为白色
float rightColor = smoothstep(1. - padding, 1. - padding, texCoord0.x);
float color = rightColor + leftColor + buttomColor + topColor;
gl_FragColor = vec4(vec3(color), 1.);
}
效果图
使用smoothstep好处是,可以通过调整参数去除锯齿效果
平行四边形
画平行四边形,就意味着某两条边的间距是倾斜的,有两条边是倾斜的直线,相当于倾斜的边的直线满足方程ax+by-c=0,根据这个公式来描绘倾斜的边,参数b可以调整倾斜的角度,参数c可调整平行四边形的面积,以水平方向的平行四边形为例:
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
float padding = 0.2;
//上边距为白色
float topColor = smoothstep(1. - padding, 1. - padding, texCoord0.y);
//左边距为白色
float leftColor = 1. - smoothstep(padding-0.018, padding, texCoord0.x + texCoord0.y*0.3-0.1);
//下边距为白色
float buttomColor = 1. - smoothstep(padding, padding, texCoord0.y);
//右边距为白色
float rightColor = smoothstep(1. - padding-0.018, 1. - padding, texCoord0.x + texCoord0.y*0.3-0.1);
float color = rightColor + leftColor + buttomColor + topColor;
gl_FragColor = vec4(vec3(color), 1.);
}
效果图
以竖直方向的平行四边形为例
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
float padding = 0.2;
//上边距为白色
float topColor = smoothstep(1. - padding - 0.018, 1. - padding, texCoord0.y + texCoord0.x*0.3 - 0.1);
//左边距为白色
float leftColor = 1. - smoothstep(padding - 0.018, padding, texCoord0.x);
//下边距为白色
float buttomColor = 1. - smoothstep(padding - 0.018, padding, texCoord0.y + texCoord0.x*0.3 - 0.1);
//右边距为白色
float rightColor = smoothstep(1. - padding - 0.018, 1. - padding, texCoord0.x);
float color = rightColor + leftColor + buttomColor + topColor;
gl_FragColor = vec4(vec3(color), 1.);
}
效果图
画直线
相当于画两个大的矩形,中间留有空白间隔开,如,画一条0.01像素宽的直线,那么只需要花两个颜色相反的大小为0.49的矩形,并对这两个矩形进行混合,如下:
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
//顶部是白色的矩形
float top = smoothstep(0.49, 0.5, texCoord0.y);
//顶部黑色的矩形
float bottom = smoothstep(0.49, 0.5, 1. - texCoord0.y);
//将两个混合
float color = top * bottom;
gl_FragColor = vec4(vec3(color), 1.);
}
效果图
画斜线
和画平行四边形一样,转换成二元一次方程的方式即可,如下:
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
//顶部是白色的矩形
float top = smoothstep(0.49, 0.5, texCoord0.y + texCoord0.x*0.2);
//顶部黑色的矩形
float bottom = smoothstep(0.49, 0.5, 1. - texCoord0.y - texCoord0.x*0.2);
//将两个混合
float color = top * bottom;
gl_FragColor = vec4(vec3(color), 1.);
}
效果图
除此之外,也可以利用点到直线的距离进行绘制,已知两个点,根据两点式计算出直线的方程,并计算出点到直线的距离,根据点到直线的距离和线宽进行直线的绘制,如下:
varying mediump vec2 texCoord0;
void main()
{
precision mediump float;
//定义两个点
vec2 center1 = (0.2, 0.2);
vec2 center2 = (0.8, 0.8);
//两个点的半径
float r1 = 0.03;
float r2 = 0.03;
vec3 cirColor1 = vec3(1., 0., 0.);
vec3 LineColor = vec3(0., 0., 0.);
//线宽
float lineWidth = 0.01;
//画两个点之间的直线
float k = (center1.y - center2.y) / (center1.x - center2.x);
float b = center1.y - k * center1.x;
float d = abs(k * texCoord0.x - texCoord0.y + b) / sqrt(k * k + 1);
if (d <= lineWidth)
{
gl_FragColor = vec4(LineColor, 1.);
}
else
{
gl_FragColor = vec4(1., 1., 1., 1);
}
//画两个点
if (length(texCoord0 - center1) <= r1 || length(texCoord0 - center2) <= r2)
{
gl_FragColor = vec4(cirColor1, 1);
}
}
效果图