GLSL——绘制平面图形(一)

6 篇文章 2 订阅
5 篇文章 0 订阅

画圆

在上一期讲述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);
    }
}

 效果图

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值