1 在webgl里面表述几何体最关键的两种数据类型:
顶点和索引(vertices and indices.)
1.1 顶点是什么?
顶点定义了3D对象的角点,每一个顶点由三个元素组成x,y,z。
在webgl里面,它没有传递单独顶点到渲染管道的API,只能够传一组顶点去让webgl渲染管道执行渲染,而这个数组的通常是由
JavaScript Array完成的。
1.2 索引是什么?
它是一个顺序标签,就是告诉webgl依顺序去画。它也是通过JavasScript Array去进行存储的。
1.3 总结。
简单的来讲,在webgl里面有两种buffer去用来处理几何渲染。
一种叫做VBO(Vertex Buffer Objects)由顶点构成
另一种叫做IBOs(Indices Buffer Objects )由索引构成。
2 webgl的渲染流程:
2.1 结构介绍:
2.1.1 VBO(Vertex Buffer Objects):
我们可以看到,一个VBO对象里面,其实不仅仅报告坐标系(coodrdinates)也就是我们熟知的x,y,z,它还包含了color,normal.scalars,甚至是一些用户自定义的properties,因为我们知道,比如,你看到的一个游戏角色里面人脸的皮肤的颜色,是否光滑,是否包含法线(层次感,更加立体).
2.1.2 Vertex Shader
Vertex Shader会操作每一个顶点,不仅仅是位置,还有它的颜色,法线,甚至是自定义的属性。比如,你看到的水的流动,其实就是Vertex Shader通过操作它的顶点进行(如傅里叶波动)给你带来的视觉盛宴。
这是一个在网上找到的水流波动的例子:
http://www.artvily.com/palette?sample=palette&clip=noise_01
2.1.3 Fragment Shader
每三个顶点会产生一个Triangle,而这样一个Triangle其实就是一个surface element.而我们通常会称它为fragment(片元),因为我们处理的这些fragment通常会显示在你的屏幕里面,所以他也是众所周知的“像素(pixels)”
Fragment Shader的存在意义主要在于计算fragment也就是screen pixel的颜色,比如下面这张图:
我们可以看到,在Vertex shader里面,定义了three Vertexs,但是,由他们组成Triangle在没被Fragment Shader处理时,其实,他们本身是,嗯,没有颜色的,也就是pixel没有颜色,现在,after Fragment Shader process 我们发现,这种fragment染上了绿色。
2.1.4 FrameBuffer
FrameBuffer采用了双缓存结构(two-dimensional buffer),它包含所有经过Fragment Shader处理的Framents.
它也是Rendring pipline 的目的地。
2.1.5 Attributes,uniforms,varyings
Attributes,uniforms,varyings是着色器编程中经常用到的三种类型的变量。
Attributes是顶点着色器中的输入变量,如顶点坐标、顶点颜色等。由于顶点着色器将会在每个顶点上都被调用,所以每次顶点着色器被调用时的输入变量attributes都是不同的。
Uniforms 是在顶点着色器和片元着色器中都能被使用的输入变量。在一个渲染循环中unifroms通常是不变的常量。如灯源位置。
Varyings用来由顶点着色器向片元着色器传递数据。
关于这三个,最好还是不要用中文意思去翻译它,我们就把它当成三个符号,好吗=。=
3 使用Webgl渲染第一个几何体
3.1 过程
3.1.1创建Javascripts Array
var vertices =
[-50.0, 50.0, 0.0,
-50.0,-50.0, 0.0,
50.0,-50.0, 0.0,
50.0, 50.0, 0.0];
1.需要注意的是,这是四个顶点,我们如果要建立IBO,的索引范围是0,1,2,3哦!
3.1.2 分配缓存(两个过程,让我们创建了一个VBO)
var myBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, myBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
1.在这里,我们不得不强调,Webgl是一个状态机的事实,也就是说,当你绑定一个buffer的时候,除非你解绑,你之后的操作都是针对于这个buffer的。一定要注意哟!
2.we will use Float32Array for VBOs and UInt16Array for IBOs
3.我们来看绑定buffer的两种类型
gl.ARRAY_BUFFER: Vertex data
gl.ELEMENT_ARRAY_BUFFER: Index data
4.我们来看缓存解绑的一个demo:
gl.bindBuffer(gl.ARRAY_BUFFER, null);
5.设定完buffer以后请解绑哟!
3.1.3 创建一个IBO
indices =
[0, 1, 2,
0, 2, 3,
0, 3, 4]
coneIBO = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, coneIBO);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices),
gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
3.1.4 我们的第一个渲染效果:(鉴于直接啃本书太过困难,我们先不用这个,从下一章节开始,我们介绍three.js)