在上一节,咱们成功运用webgl制作了一个点,这一节咱们就来完成让这个点动起来。
剖析:怎么让点动起来?
先复习下上节课的shader:
- vertex shader
void main() {
gl_Position = vec4(0.0,0.0,0.0, 1.0);
gl_PointSize = 10.0;
}
- fragment shader
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
运动的实质便是坐标的变化,咱们想要修正坐标,其实便是要修正gl_Position
,也便是说咱们需要在vertex shader界说一个变量,一起程序能够控制变量的值。
修正点的方位
由于shader运用的是glsl言语,这儿就需要用到attribute, attribute变量只能界说在vertex shader中,attribute更像是一个修饰符,表示这是一个能够被js代码修正的特点(为了方便了解暂时这么解说,更专业的解说你需要看glsl言语规范)。
-
vertex shader修正
attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos.x,a_pos.y,0.0, 1.0); gl_PointSize = 10.0; }
在shader中咱们界说了a_pos特点,然后将a_pos.x、a_pos.y分别传递给了gl_Position,当咱们经过代码修正a_pos后,gl_Postion也会随之改动。
-
在js代码中,咱们能够这样传递数据给a_pos
// 放到program之后,从vertex shader里边获取a_pos特点 const a_pos = gl.getAttribLocation(program, "a_pos"); // 设置a_pos特点值 gl.vertexAttrib2f(a_pos, 0.9, 0.9);
重新运行长须调查到点的方位烘托到了右上角,经过这个体现,不难推理出,webgl的坐标是[-1, 1]
完成:让点动起来!
原理也十分简略,不断的改动a_pos特点即可:
// ...
let x = -1;
setInterval(() => {
x += 0.1;
if (x > 1) {
x = -1;
}
gl.vertexAttrib2f(a_pos, x, 0);
gl.drawArrays(gl.POINTS, 0, 1);
}, 100)
这姿态,咱们就看到了一个红点,从左往右移动,完好的代码我放到了CodePen。
整体思路回顾:
-
vertex shader
增加attribute vec2 a_pos
,而且将a_pos的值赋给gl_Position
- 经过
getAttribLocation
获取a_pos
- 经过
vertexAttrib2f
设置a_pos
的值,并调用draw进行烘托制作 - 运用定时器,改动
a_pos
,从而完成点的移动作用
定时器的一个callback,咱们一般称为一帧,要制作出复杂的游戏画面,一般需要进行屡次的draw函数调用,在这一帧中咱们调用了几回draw函数,那么咱们一般就说drawcall是多少,drawcall是功能优化的一个十分重要的目标。
当然以上的代码十分的简陋,在实践项目中咱们也不会运用setInterval驱动烘托更新,由于无法确保100ms,可是这个思路是通用的。
游戏引擎其实便是一个死循环,每次循环开始都要擦除上一次的制作成果,然后计算出当时帧的制作数据,屡次调用draw函数进行烘托,希望到这儿,能让你对游戏引擎有更深层次的了解。
拓宽
上边的代码中,咱们如果要制作多个不同颜色、不同方位、不同巨细的点,就比较麻烦,而且数据量比较多,webgl当然考虑到了这种情况,所以产生了buffer
的概念,而且能够经过gl.vertexAttribPointer
进行数据的绑定,这儿就不再展开了,留给你自己探索了。