WebGL 进入三维世界

1.观察目标点和上方向canvas

    为了肯定观察者的状态,你须要获取两项信息:视点,即观察者的位置;观察目标点(look-at point),即被观察目标所在的点,它能够用来肯定视线。此外,由于咱们须要把观察到的景象绘制到屏幕上,还须要知道上方向(up direction)。有了这三项信息,就能够肯定观察者的状态了。数组

image

    视点:观察者所在的三维空间中位置,视线的起点。视点坐标通常用(eyeX, eyeY, eyeZ)表示。
    观察目标点:被观察目标所在的点。只有同时知道观察目标点和视点,才能算出视线方向。观察目标点的坐标用(atX、atY、atZ)表示。
    上方向:最终绘制在屏幕上的影像中的向上方向。用(upX,upY,upZ)表示。函数

2.建立视图矩阵(view matrix)3d

    咱们能够用视点、观察目标点、上方向三个矢量建立一个视图矩阵。coun-matrix.js提供的Matrix4.setLookAt()函数能够根据上述三个矢量,建立出视图矩阵。函数定义为Matrix4.setLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, upX, upY, upZ)。参数:
    eyeX,eyeY, eyeZ:指定视点
    atX, atY, atZ:指定观察者
    upX, upY, upZ:指定上方向,若是上方向是Y轴正方向那么矢量就是(0, 1, 0)。code

3.模型矩阵orm

    咱们知道,若是想旋转图形,就须要用旋转矩阵乘以旋转前的顶点坐标:
    <旋转后顶点坐标> = <旋转矩阵> * <原始顶点坐标>对象

    用视图矩阵乘以旋转后的顶点坐标,就能够得到“从视点看上去”的旋转后的顶点坐标:blog

    <‘从视点看上去’的旋转后顶点坐标> = <视图矩阵> * <旋转矩阵> * <原始顶点坐标>索引

    除了旋转矩阵,还能够用平移、缩放等基本变换矩阵或它们的组合,这时矩阵被称为模型矩阵(model matrix)。这样就能够写成:ip

    <视图矩阵>*<模型矩阵>*<原始顶点坐标>

4.模型视图矩阵

    视图矩阵和模型矩阵相乘的积被称为模型视图矩阵(model view matrix)。变换后结果可写为:

    <模型视图矩阵>*<顶点坐标>

5.可视空间

    除了水平和垂直范围内的限制,WebGL还限制观察者的但是深度,即“可以看多远”。全部这些限制,包括水平视角、垂直视角、可视深度,定义了可视空间(view volume)。若是咱们没有显示地指定可视空间,默认的但是深度又不够圆,因此有些图形某些部分看不到。

    有两种类型的可视空间:

    长方形但是空间,也称盒状空间,由正射投影(orthogrphic projection)产生。

    四棱锥/金字塔但是空间,由透视投影(perspective projection)产生。

6.盒状可视空间

    盒状可视空间以下图所示。可视空间由先后两个矩形表面肯定,分别称为近裁剪面(near clipping plane)和远裁剪面(far clipping plane),前者的四个顶点为(right、top、-near)、(-left、top、-near)、(-left、-bottom,-near)、(right、-bottom、-near),然后者的四个顶点为(right、top、far)、(-left、top、far)、(-left,-bottom、far)、(right、-bottom、far)。

7.正射投影矩阵和视图矩阵运算

    若是程序涉及两个矩阵。在顶点着色器中,咱们须要用视图矩阵乘以顶点坐标,获得顶点在视图坐标系下的坐标,再左乘正射投影矩阵并赋值给gl_Position。计算过程以下:

    <正射投影矩阵> * <视图矩阵> * <顶点坐标>

8.透视投影可视空间

    透视投影可视空间如图所示。就像盒状可视空间那样,透视投影可视空间也有视点、视线、近裁剪面、远裁剪面。

image    不管是透视投影可视空间仍是盒状可视空间,咱们都用投影矩阵来表示它,可是定义矩阵的参数不一样。Matrix4对象的setPerspective()方法可用来定义透视投影可视空间。

    定义了透视投影可视空间的矩阵被称为透视投影矩阵(perspective projection matrix)。

9.隐藏面消除

    WebGL提供了隐藏面消除(hidden surface removal)功能。这个功能会帮助咱们消除那些被遮挡的表面(隐藏面),你能够放心地绘制场景而没必要估计个物体在缓冲区中的顺序。开启隐藏面消除功能。须要遵循如下两步:

    1.开启隐藏面消除功能

    gl.enable(gl.DEPTH_TEST);

    2.在绘制以前,清除深度缓冲区

    gl.clear(gl.DEPTH_BUFFER_BIT);

    在清理深度缓冲区的同时还要清理颜色缓冲区,全部能够用按位或(|)链接gl.DEPTH_BUFFER_BIT和gl.COLOR_BUFFER_BIT:

    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

10.gl.enable(cap)

    开启cap表示的功能(capability)。参数:

    cap:指定须要开启的功能,有多是如下几个:gl.DEPTH_TEST隐藏面消除,g.BLEND混合,gl.POLYGON_OFFSET_FILL多边形移位等

11.gl.diable(cap)

    关闭cap表示的功能。参数:

    cap:与gl.enable()相同

12.深度冲突(Z fighting)

    当几何图形或物体的两个表面极为接近时,使得表面看上去斑斑驳驳的。这种现象被称为深度冲突。下图左边是深度冲突的效果:

image

    WebGL提供一种被称为多边形偏移(polygon offset)机制解决这个问题。该机制自动在Z值加上一个偏移量。启动该机制只须要两行代码:

    1.启动多边形编译

gl.enable(gl.POLYGON_OFFSET_FILL);

    2.在绘制以前指定用来计算偏移量的参数

gl.polygonOffset(1.0, 1.0);

13.gl.polygonOffset(factor, units)

    指定加到每一个顶点绘制后的Z值上的偏移量,偏移量按照公式“m*factor+r*units”计算,其中m表示顶点所在表面相对于观察者的视线的角度,而r表示硬件可以区分两个z值之差的最小值。

14.gl.drawElements(mode, count, type, offset)

    执行着色器,按照mode参数指定的方式,根据绑定到gl.ELEMENT_ARRAY_BUFFER的缓冲区中的顶点索引值绘制图形。参数:

    mode:指定绘制的方式,可接收如下常量符号:gl.POINTS、gl.LINES、gl.LINE_STRIP、gl.LINE_LOOP、gl.TRIANGLES、gl.TRIANGLES_STRIP、gl.TRIANGLES_FAN

    count:指定绘制顶点的个数(整形数)

    type:指定索引数组类型:gl.UNSIGNED_BYTE或gl.UNSIGNED_SHORT

    offset:指定索引数组开始绘制的位置,以字节为单位

15.gl.readPixels(x, y, width, height, format, type, pixels)

    从颜色缓冲区中读取由x、y、width、height参数肯定的矩形块中的全部像素值,并保存在pixels指定的数组中。参数:

    x,y:指定颜色缓冲区中矩形块左上角的坐标,同时也是读取的第一个像素的坐标

    width,height:指定矩形块的宽度和高度,以像素为单位

    format:指定像素值得颜色格式,必须为gl.RGBA

    type:指定像素值的数据格式,必须为gl.UNSIGNED_BYTE

    pixels:指定用来接收像素数据的Uint8Array类型化数组

    读取的x,y的原点是从左下角开始,而不是从左上角开始。加入canvas长、宽分别为100、30,那么右下角的坐标为(100, 0)。

相关文章
相关标签/搜索