先看一下最终效果
这是二次Bezier曲线
这是三次Bezier曲线
我本人的ShaderToy个人主页链接,有兴趣可以看一下,还有一些RayMarching的内容https://www.shadertoy.com/profile/?show=shadershttps://www.shadertoy.com/profile/?show=shaders
其实光看动图就能够看明白这个曲线上的点都是由多条线段多次插值得到的
首先把我自己使用的画点函数和画线函数展示一下
//画点函数,uv,即屏幕上任意一点,p为需要绘制的点,size.x是点的半径,
//size.y是边缘模糊百分比,color是点颜色
vec3 DrawPoint(vec2 uv,vec2 p,vec2 size,vec3 color)
{
float d = length(uv-p);
d = smoothstep(size.x,size.x-size.y*size.x,d);
return d*color;
}
//length()函数,顾名思义,计算两个点的距离
smoothstep()详解如下图
所以我可以通过控制size.x以及size.y来控制点的大小,并且由于是smoothstep函数而不是step函数,所以这个点圆是光滑过渡的,而不是step的直接从0变成1。
再然后是画线函数
//画线函数,p为uv,即屏幕上任意一点,ab为线段两端点,size.x是线段宽,
//size.y是线段边缘模糊百分比,color是线段颜色
vec3 DrawLine(vec2 uv,vec2 a,vec2 b,vec2 size,vec3 color)
{
vec2 ap = uv-a;
vec2 ab = b-a;
float t = dot(ap,ab)/dot(ab,ab);//点p在线段上投影占ab的百分比,不理解可以看后面的图解
t = clamp(t,0.0,1.0);//如果点p到ab做垂线,垂足要是不在ab线段上就截断在ab线段上
//ap-ab*t表示点p-点p到线段ab的垂点,即d是点p到线段的距离
float d = length(ap-ab*t);
float s = smoothstep(size.x,size.x-size.y*size.x,d);
return s*color;
}
d = length(ap-ab*t),简单来说就是点p到垂足(点p到线段ab的垂足)的距离,不过因为点p到线段ab的垂足可能在a的右上方,也可能在b的左下方,所以用clamp来将垂足截断到a,b两个点上。最后乘以线段颜色color
既然画点和线段的函数都OK了,那么剩下的内容就不成问题了
//首先这是main函数里的全部代码,但不要急,我们一部分一部分看
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.y;
float w = iResolution.x/iResolution.y;
vec3 col = vec3(0.0f);
if(true) //为True画二次Bezier曲线
{
//Draw Three Point,三个控制点
vec2 a = vec2(0.1*w,0.15);
vec2 b =