WebGL - 颜色和纹理

首先,将顶点座标传入着色器,需要遵循以下几步

  • 1、创建缓冲区对象;
  • 2、将缓冲区对象绑定到target上;
  • 3、将顶点座标数据写入缓冲区对象;
  • 4、将缓冲区对象分配给对应得 attribute变量;
  • 5、开启 attribute变量;

1、非座标数据传入顶点着色器

所以将多个顶点相关得数据通过传冲去对象传入顶点着色器,其实只需要每种数据重复以上步骤即可;

首先,需要再顶点着色器中定义可以接收顶点大小得变量,此处片元着色器和之前一致;

attribute vec4 a_Position;
attribute float a_PointSize;
void main(){
    gl_Position = a_Position;
    gl_PointSize = a_PointSize;
}

然后就需要重复以上5个步骤,将顶点大小数据传递给顶点着色器

var sizes = new Float32Array([10.0, 20.0, 30.0]);//此处需要传递的单精度浮点

此时,再webgl系统中就存在两个缓冲区,一个是顶点位置数据,一个事顶点大小数据,因此 通过为顶点得每种数据建立一个缓冲区,然后分配给对应得 attribute 变量,就可以向顶点着色器传递多份逐顶点得数据信息

2、gl.vertexAttribPointer得步进和偏移参数

使用多个缓冲区对象向顶点着色器传递多种数据,比较适合数据量不大得情况,但是数据较大就不适合了,但是webgl允许 将顶点得各种信息打包到一个缓冲区对象中;

var verticesSizes = new Float32Array([
    // 两种数据打包到同一个缓冲区对象中去
    // 顶点位置 和 尺寸数据
    0.0, 0.5, 10.0,  // 第一个点
    0.5, -0.5, 20.0, // 第二个点
    -0.5, -0.5, 30.0 // 第三个点
]);

那么 webgl怎么区分里面得数据那个部分是顶带你位置和尺寸呢?

因为Float32Array是类型化数组,可以通过静态属性BYTES_PER_ELEMENT获得数组中每个元素所占得字节数;

Float32Array 的情况下返回4

详细请参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Float32Array

var FSIZE = verticesSize.BYTES_PER_ELEMENT;

1、将位置数据分配给 attribute变量

// 将缓冲区对象分配给attribute变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 3, 0);

2、将顶点大小数据分配给 attribute变量

gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE * 3, FSIZE * 2);

下面来看下方法gl.vertexAttribPointer(location,size,type,normalize,stride,offset)参数

  • 1、location 待分配的 attribute变量的存储位置;
  • 2、size 指定缓冲区中,每个顶点的分量个数;
  • 3、type 指定数据格式;
  • 4、normalize true或者false表明是否将非浮点型的数据归一化到[0,1]或者[-1,1];
  • 5、stride指定两个顶点间的字节数,默认为0;
  • 6、offset指定缓冲区对象中的偏移量(以字节为单位),即attribute变量从缓冲区中的何处开始存储,若从起始位置,则参数为0;

再来看下类型化数组中的数据

var verticesSizes = new Float32Array([
    // 两种数据打包到同一个缓冲区对象中去
    // 顶点位置 和 尺寸数据
    0.0, 0.5, 10.0,  // 第一个点
    0.5, -0.5, 20.0, // 第二个点
    -0.5, -0.5, 30.0 // 第三个点
]);

如果想要获取每个顶点的数据,参数stride需要是 字节数乘以第一个顶点的数据个数,所以是 SIZE * 3,前三个数据是一个顶点的信息;

但是怎么区分顶点位置和大小信息呢?

那就需要设置最后一个参数,偏移量参数 offset 距首个元素的偏移距离,从0开始;

顶点位置数据是前两个数据,因此距离首个元素的偏移距离是 0;

顶点大小数据是每个顶点数据的第三个数据,因此距离首个元素的偏移距离是2;

3、修改顶点颜色

首先,需要了解顶点着色器 如何向 片元着色器传递数据;

将顶点着色器中的数据传递给片元着色器,需要通过 varying变量, varying变量存在的作用就是,从顶点着色器向片元着色器传递数据;

下面来看着色器代码

1、顶点着色器

attribute vec4 a_Position;
attribute vec4 a_Color; //用于接收外部的顶点颜色信息
varying vec4 v_Color;// 声明 varying 变量
void main(){
    gl_Position = a_Position;
    gl_PointSize = 10.0;//设置顶点大小
    v_Color = a_Color;//将顶点颜色赋值给varying变量
}

2、片元着色器

precision mediump float; //声明浮点数精度
void main(){
    gl_FragColor = v_Color;//从顶点着色器接收颜色数据
}

varying 变量只能是 float 类型的

webgl如果顶点着色器与片元着色器中有类型和命名都相同的 varying 变量 那么顶点着色器赋值给该变量的值就会被自动的传入片元着色器

所以顶点着色器中的 v_color中的值被传递给了,片元着色器中的v_Color变量;

4、几何形状的装配和光栅化

  • 图形装配过程:这一步骤的任务是,将孤立的顶点座标装配成集合图形,集合图形的类别是由 gl.drawArrays()方法的第一个参数决定;
  • 光栅化过程:这一步的任何是,将装配好的集合图形转化为片元;

变量 gl_Position实际上是 几何图形装配阶段输入的数据,注意,集合图形装配过程又被称为 图元装配过程,因为被装配的基本图形 (点,线,面)又被称为 图元,图元就是图形的基本元素;

片元其实就是像素,那么显示在屏幕上的图形,就是通过将图形转换为 片元,这个过程是 光栅化

光栅化过程结束后,程序就会 逐片元 的调用片元着色器,也就是说有多少个片元(像素)就会调用多少次片元着色器,每调用一次就处理一个片元,直到最后一个片元被处理后,浏览器就会显示最终的效果;

光栅化 过程中,生成的片元都是带有座标信息的,调用片元着色器时,这些座标信息也随着片元传了进去,因此可以通过片元着色器中的内置变量来访问片元的座标

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章