我们在画布的中心绘制一个正方形,你可以先看看最终的效果:
代码
下面是完整的代码,我们后续将对里面的内容进行讲解说明:
<canvas width=200 height=200 style="outline:1px solid gray;">
非常抱歉,您的浏览器不支持canvas!
</canvas>
<!-- 顶点着色器 -->
<script type='x-shader/x-vertex' id='vs'>
void main(){
gl_Position=vec4(0.0,0.0,0.0,1.0);
gl_PointSize=100.0;
}
</script>
<!-- 片段着色器 -->
<script type='x-shader/x-fragment' id='fs'>
void main(){
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
</script>
<script>
// 先获取gl
var gl = document.getElementsByTagName('canvas')[0].getContext('webgl');
// 定义一个把着色器字符串加载成着色器对象的函数
var loadShader = function (type, source) {
// 创建着色器对象
var shader = gl.createShader(type);
// 绑定资源
gl.shaderSource(shader, source);
// 编译着色器
gl.compileShader(shader);
return shader;
};
// 分别加载顶点着色器对象和片段着色器对象
var vertexShader = loadShader(gl.VERTEX_SHADER, document.getElementById('vs').innerHTML),
fragmentShader = loadShader(gl.FRAGMENT_SHADER, document.getElementById('fs').innerHTML);
// 创建一个着色器程序
var glProgram = gl.createProgram();
// 把前面创建的两个着色器对象添加到着色器程序中
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
// 把着色器程序链接成一个完整的程序
gl.linkProgram(glProgram);
// 使用这个完整的程序
gl.useProgram(glProgram);
// 绘制一个点
gl.drawArrays(gl.POINTS, 0, 1);
</script>
绘制流程
上面的流程看起来是不是很简单,无论是简单的3D还是复杂的3D,需要且需要按照上面的流程进行(当然,在细节上会有一些不同)。
记住这个流程,后续的说明也按照这个思路进行。
着色器
绘制的第一步,就是准备好两个着色器: 顶点着色器
和 片段着色器
。前者用于描述绘制的图形的点的位置,后者用于描述每个点的颜色。
可能这样说你会无法理解,其实简单的说就是:我们在绘图的时候,会一次性的把数据都传递给GPU,传递给GPU的数据需要一些"整理"后再使用,而着色器就是驻留在GPU上的这段"整理程序"。
我们传递的数据是什么?不就是点的位置和点的颜色吗。所以,着色器就分为了顶点着色器和片段着色器(有时候也叫片元着色器),前者处理点,后者处理颜色。
定义着色器
所以,让我们先看看这里的顶点着色器的具体代码:
void main(){
gl_Position=vec4(0.0,0.0,0.0,1.0);
gl_PointSize=100.0;
}
内置变量gl_Position表示点的位置,gl_PointSize表示点的大小。
我们这里为了简单,点的位置和大小是写死的,实际可以有更丰富的方式进行设置,这里先不说明了。
那么,点的颜色在哪里设置?没错,在片段着色器,看看具体代码:
void main(){
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
同样的存在一个内置变量,这里叫gl_FragColor, 其就表示点的颜色。
着色器生效
目前为止,上面的两个着色器只是两段字符串,还需调用webgl的方法生效(这里的代码比较固定,查看例子即可)。
数据
由于我们这里把数据写死了,因此不需要传递,就先不再赘述了。
绘制
我们这里写死的数据就一个点,由此直接:
gl.drawArrays(gl.POINTS, 0, 1);
这样,一个点就出来了。
除了绘制点,我们还可以绘制线和三角形,当然,绘制多个点、线或三角形的时候,也有更丰富的方法,此外,除了常规绘制方法,还有对应的更高效的索引绘制方法。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。