作者:桑榆
QQ:934440653
图形绘制流程
当图形数据通过整WebGL流水线后,GPU把结果写入到WebGL绘制缓存(drawing buffer)的内存中。也可以把绘制缓存看成WebGL的帧缓存。它与帧缓存一样,也具有一个颜色缓存、Z-缓存和模版缓存。绘制缓存中的内容在传送到物理帧缓存之前,需要与HTML页面中的其他内容进行结合;物理缓存中的实际结果直接显示在屏幕上。
1. 顶点着色器
写入顶点着色器的varing变量的值是对片段进行线性插值得到的。
(1) gl.bindAttribLocation()
在执行链接之前将属性,绑定到索引上,定义了索引后,在绘制过程中直接使用这个索引。
let v3PositionIndex = 0;
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");
webgl.linkProgram(programObject);
(2) gl.getAttribLocation()
由webgl自己决定某个属性要使用那个索引,在链接完成之后,用该方法得到某个属性的通用属性索引。
var triangleVerties = [
0.0 ,0.5,0.0,
-0.5,-0.5,0.0,
0.5,-0.5,0.0
];
let vertexBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER , vertexBuffer );
gl.bufferData( gl.ARRAY_BUFFER , new Float32Array( triangleVerties ) , gl.STATIC_DRAW );
let v_position = gl.getAttribLocation(gl.program, 'aVertexPosition');
gl.vertexAttribPointer( v_position , 3 ,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray( v_position );
2. 图元装配
把已经着色的顶点装配成三角形、线段或精灵等几何图元。在这一阶段会对每个图元进行视锥剔除,不在视锥内的图元在这个阶段就被丢弃。
3. 光栅化
将图元转换为片段,把片段传送给片段着色器,可以把片元看做最终渲染在屏幕上的像素,这一过程叫做光栅化操作。
4. 片元着色器
不是所有的片段都会称为绘制缓存中的像素,因为逐片段操作可能会在流水线的最后几个步骤中丢弃某些片段。因此WebGL需要区分片段和像素,把最终能写入到绘制缓存中的片元称为像素。
片段着色器的数量是多余顶点着色器的。如下图:
5. 逐片段操作
包括了裁剪测试、多重采样片段运算、模板测试、深度缓存测试、融合、抖动。
来自片段着色器的每个片段都可以以不同方式影响绘制中的每一个像素。具体取决于逐片操作的条件和结果。可以手动的启用或者禁止这些处理。
5.1 裁剪测试
确定片元是否位于裁剪矩形中,如不在,则被丢弃,而且不会到达绘制缓存。裁剪矩形由一个左下角的坐标、一个高度、一个宽度决定的,片段位于裁剪矩形中则通过测试。
5.2 多重采样片段操作
修改片段的alpha值和覆盖(coverage),作为抗锯齿的一个措施。抗锯齿:用来改善多边形外框的外观使他们看起来没有锯齿——即在屏幕是的到一个光滑的结果。
5.3 深度缓存测试
当开启深度测试后,在深度缓冲区内,每个片元会比较其中已存在的片元深度,如果深度大于已存在的则剔除(舍弃),如果小于已存在的则显示;当通过深度测试的片元,则对该片元进行深度写入,如果开启深度写入,则该片元更新写入到缓存区内,否则不写入,深度测试过程结束。
5.4 融合
把片段的颜色与已经在颜色缓存中相应位置的片段的颜色进行组合(创建透明对象时,就需要使用融合技术)。
5.5 抖动
位于绘制缓存之前的最后一步操作时抖动。颜色缓存是用有限的二进制位数表示每个颜色。抖动用来以某种方式排列颜色,得到比实际更多的颜色。当颜色缓存可用的颜色数有限时,抖动就非常有用。