内容简介:今天我们一起来做一个三原色的旋转,为了更好的体现效果呢,我没有使用图片作为背景,闲言少叙,我们直接看效果。图中就是我们要实现的效果,有红蓝绿三种颜色的圆圈在旋转,我们需要解决的主要问题有如何使用webgl来画一个模糊的圆圈,如何使三个圆圈绕一点旋转。同时如果你喜欢的话还可以自己做一个延伸,例如时刻更改旋转的中心等等,这样效果会更佳的丰富,我在这里呢就不做延伸了。
今天我们一起来做一个三原色的旋转,为了更好的体现效果呢,我没有使用图片作为背景,闲言少叙,我们直接看效果。
图中就是我们要实现的效果,有红蓝绿三种颜色的圆圈在旋转,我们需要解决的主要问题有如何使用webgl来画一个模糊的圆圈,如何使三个圆圈绕一点旋转。
同时如果你喜欢的话还可以自己做一个延伸,例如时刻更改旋转的中心等等,这样效果会更佳的丰富,我在这里呢就不做延伸了。
基础的构建我在这里就不在赘述了,你可以看一下我的另一篇基础构建的文章,在此我们直接进入最核心的webgl的片元着色器代码。
一 webgl画出一个圆圈
precision mediump float; varying vec2 uv; uniform float time; void main(){ vec3 color; float blur = 15.0; color.b = 1.0 - (pow(uv.x - 0.5,2.0) + pow(uv.y - 0.8,2.0))*blur; gl_FragColor = vec4(color, 1.0 ); } 复制代码
我们使用上面的代码就轻松的构建出了一个圆,接下来我们就看一下这个轻松画出圆的原理。
首先我们定义了一个vec3类型的变量,这个变量的作用就是用来存储我们改变以后的色值的。
接着我们定义了一个float类型的blur变量,此变量的作用是用来控制画出圆的模糊距离。
color.b = 1.0 - (pow(uv.x - 0.5,2.0) + pow(uv.y - 0.8,2.0))*blur; 复制代码
这句代码是画出圆的关键点,我们使用具体的坐标事例来说明。
图中的坐标系中我们定义了我们想要画圆的点A(0.5,0.8),其坐标你可以在上面的公式找到。
我们分别将W,X,U点带入公式看一下。
pow函数是平方函数,pow(x,y)会返回x的y次方。
W => 1.0-(pow(0.5 - 0.5, 2.0) + pow(0.77 - 0.8, 2.0))*15.0 => 0.865
X => 1.0-(pow(0.5 - 0.5, 2.0) + pow(0.4 - 0.8, 2.0))*15.0 => -1.4 U => 1.0-(pow(0.1 - 0.5, 2.0) + pow(0.1 - 0.8, 2.0))*15.0 => -8.75
我们在整个二维平面上面,距离A点越远的点最后计算出来的值就越大。
在webgl中rgba的取值范围是在0.0~1.0。
也就是说从A点为圆心,距离A越远的点计算出来的值会越小,也就会呈现黑色,距离A点越近的点就会月靠近1.0这个数值,也就会呈现蓝色。
二 画出三色圆
一个圆的画法我们已经知道了,那么我们画出来三个圆。
precision mediump float; varying vec2 uv; uniform float time; void main(){ vec3 color; float blur = 15.0; color.r = 1.0 - (pow(uv.x - 0.24,2.0) + pow(uv.y - 0.35,2.0))*blur; color.g = 1.0 - (pow(uv.x - 0.75,2.0) + pow(uv.y - 0.35,2.0))*blur; color.b = 1.0 - (pow(uv.x - 0.5,2.0) + pow(uv.y - 0.8,2.0))*blur; gl_FragColor = vec4(color, 1.0 ); } 复制代码
上面我们使用和画蓝色圆同样的方式画出了三色圆,那么接下来就是让三色圆进行转动了。
三 转动三色圆
precision mediump float; varying vec2 uv; uniform float time; void main(){ vec3 color; float blur = 15.0; vec2 rotateCenter = vec2(0.5, 0.5); vec2 circleA = vec2(rotateCenter.x + 0.3*cos(radians(90.0+time)), rotateCenter.y + 0.3*sin(radians(90.0+time))); vec2 circleB = vec2(rotateCenter.x + 0.3*cos(radians(210.0+time)), rotateCenter.y + 0.3*sin(radians(210.0+time))); vec2 circleC = vec2(rotateCenter.x + 0.3*cos(radians(-30.0+time)), rotateCenter.y + 0.3*sin(radians(-30.0+time))); color.r = 1.0 - (pow(uv.x - circleB.x,2.0) + pow(uv.y - circleB.y,2.0))*blur; color.g = 1.0 - (pow(uv.x - circleC.x,2.0) + pow(uv.y - circleC.y,2.0))*blur; color.b = 1.0 - (pow(uv.x - circleA.x,2.0) + pow(uv.y - circleA.y,2.0))*blur; gl_FragColor = vec4(color, 1.0 ); } 复制代码
我们首先定义三色圆的旋转中心,我定义的是rotateCenter(0.5,0.5),接下来我们要将三色圆的圆心和这个点关联起来。
上面图中A点是蓝色圆的圆心,B点是红色圆的圆心,C点是绿色圆的圆心,O点是圆的圆心,同时也是三角形的中心。
我们可以根据初高中的知识知道: A(x1,y1),o(x0,y0)
x1 = x0 + r*cos(degrees*PI/180)
y1 = y0 + r*sin(degrees*PI/180)
vec2(rotateCenter.x + 0.3*cos(radians(90.0)), rotateCenter.y + 0.3*sin(radians(90.0))) 复制代码
在代码中rotateCenter.x就是x0
rotateCenter.y就是y0
0.3就是r也就是圆的半径
degrees*PI/180我们使用webgl的内置三角函数radians(90.0)进行计算,其中90.0就是A点相对于O点的角度。
这样我们就将ABC三个点和O点关联上了,此时只要我们再时时的改变ABC三点相对于O点的角度值,这样就可以达到旋转的效果了。
vec2 circleA = vec2(rotateCenter.x + 0.3*cos(radians(90.0+time)), rotateCenter.y + 0.3*sin(radians(90.0+time))); 复制代码
在上面我们在radians(90.0+time)的参数中添加了一个变量time,这个time会从0开始一直加1,这样ABC三个点就会时时的改变相对于O点的角度,进而完成旋转。
color.b = 1.0 - (pow(uv.x - circleA.x,2.0) + pow(uv.y - circleA.y,2.0))*blur; 复制代码
最后我们将时时旋转的三色圆中心坐标传给颜色画圆的计算公式,这样就完成了。
旋转的方式你可以自己手动的更改,并且画圆那里使用2次方还是1次方你都可以进行更改,你会得到不一样的效果,篇幅的原因我就不一个个举例子了。
color.b = 1.0 - (pow(uv.x - circleA.x,2.0) + pow(uv.y - circleA.x,2.0))*blur; 复制代码
嗯,怕你感觉对实现的效果失望,你只需要将color.b那里的旋转中新都设置成x就会出现上面的效果,更多的效果你可以自己尝试一下。
最后附上代码地址: gitee.com/wangtao_it_…
此次的代码是项目下面的rotateRGB.html
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- matlab练习程序(渲染三原色)
- 华为 HC 的三原色:技术突破、思想输出,和未来智能世界的领导力初现
- leetcode - 189. 旋转数组
- 【Leetcode】61.旋转链表
- 圆环旋转加显隐的加载效果
- 通过优雅的方式强制旋转屏幕
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。