webgl入门实例-07顶点缓冲区基本概念
WebGL 顶点缓冲区 (Vertex Buffer)
顶点缓冲区(Vertex Buffer)是WebGL中存储顶点数据的主要机制,它允许您高效地将大量顶点数据发送到GPU。
基本概念
顶点缓冲区用于存储:
- 顶点位置坐标
- 顶点颜色
- 纹理坐标
- 法线向量
- 其他顶点属性数据
创建和使用顶点缓冲区
1. 创建顶点数据
// 示例:三角形的三个顶点,每个顶点包含位置和颜色
const vertices = [// 位置(x,y) 颜色(r,g,b)0.0, 0.5, 1.0, 0.0, 0.0, // 顶点1 (红色)-0.5, -0.5, 0.0, 1.0, 0.0, // 顶点2 (绿色)0.5, -0.5, 0.0, 0.0, 1.0 // 顶点3 (蓝色)
];
2. 创建并绑定顶点缓冲区
// 创建缓冲区对象
const vertexBuffer = gl.createBuffer();// 绑定缓冲区为当前使用的ARRAY_BUFFER
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);// 将数据传入缓冲区
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
3. 设置顶点属性指针
// 获取着色器中属性位置
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
const colorAttributeLocation = gl.getAttribLocation(program, "a_color");// 启用属性
gl.enableVertexAttribArray(positionAttributeLocation);
gl.enableVertexAttribArray(colorAttributeLocation);// 告诉WebGL如何从缓冲区读取数据
const stride = 5 * Float32Array.BYTES_PER_ELEMENT; // 每个顶点5个浮点数(x,y,r,g,b)// 位置属性
gl.vertexAttribPointer(positionAttributeLocation, // 属性位置2, // 每个顶点的大小(2个分量x,y)gl.FLOAT, // 数据类型false, // 是否归一化stride, // 步长(到下一个顶点的字节数)0 // 偏移量
);// 颜色属性
gl.vertexAttribPointer(colorAttributeLocation, // 属性位置3, // 每个顶点的大小(3个分量r,g,b)gl.FLOAT, // 数据类型false, // 是否归一化stride, // 步长2 * Float32Array.BYTES_PER_ELEMENT // 偏移量(跳过前2个浮点数x,y)
);
4. 绘制图形
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);
顶点缓冲区的类型
WebGL中有两种主要缓冲区类型:
ARRAY_BUFFER
- 用于顶点数据ELEMENT_ARRAY_BUFFER
- 用于索引数据(与索引缓冲区配合使用)
使用多个顶点缓冲区
您可以使用多个顶点缓冲区来存储不同类型的顶点属性:
// 位置数据
const positions = [0.0, 0.5,-0.5, -0.5,0.5, -0.5
];// 颜色数据
const colors = [1.0, 0.0, 0.0,0.0, 1.0, 0.0,0.0, 0.0, 1.0
];// 创建位置缓冲区
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);// 创建颜色缓冲区
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
性能考虑
- 静态数据:使用
gl.STATIC_DRAW
表示数据不会或很少改变 - 动态数据:使用
gl.DYNAMIC_DRAW
表示数据会频繁改变 - 流数据:使用
gl.STREAM_DRAW
表示数据每帧都会改变
顶点数组对象(VAO)
在更复杂的应用中,可以使用顶点数组对象来封装顶点属性状态:
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);// 设置所有顶点属性...
// (位置、颜色、纹理坐标等)// 绘制时只需绑定VAO
gl.bindVertexArray(vao);
gl.drawArrays(gl.TRIANGLES, 0, 3);
顶点缓冲区是WebGL渲染的基础,合理使用可以显著提高渲染性能,特别是在处理复杂3D模型时。