当前位置: 首页 > news >正文

(五)WebGL中vertexAttribPointer方法的使用详解

vertexAttribPointer 是 WebGL 中用于定义如何在顶点着色器中访问顶点数据的一种方法。它的作用是告诉 WebGL 如何解释和从当前绑定的缓冲区中获取顶点数据。

在 WebGL 中,顶点数据通常存储在一个缓冲区对象中,这些数据包括位置、颜色、法线、纹理坐标等。然后,使用 vertexAttribPointer 来定义这些数据如何映射到着色器中的顶点属性。

我们将通过一个简单的 WebGL 示例,详细讲解 vertexAttribPointer 的使用。我们将创建一个渲染一个简单三角形的程序,展示如何使用 vertexAttribPointer 设置顶点属性。

代码示例

1. HTML 基础结构

这部分与之前一样。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebGL vertexAttribPointer 示例(包含颜色)</title>
</head>
<body><canvas id="webglCanvas" width="500" height="500"></canvas><script src="app.js"></script>
</body>
</html>
2. JavaScript 代码

我们将在 app.js 中修改数据,传递顶点位置和颜色,同时更新顶点着色器和片段着色器。

// 获取Canvas元素并初始化WebGL上下文
const canvas = document.getElementById("webglCanvas");
const gl = canvas.getContext("webgl");// 检查WebGL是否可用
if (!gl) {console.error("无法初始化WebGL!");
}// 定义顶点着色器代码
const vsSource = `attribute vec4 a_position;  // 顶点位置attribute vec4 a_color;     // 顶点颜色varying vec4 v_color;       // 从顶点着色器传递到片段着色器的颜色变量void main() {gl_Position = a_position;  // 设置顶点的位置v_color = a_color;         // 将颜色传递到片段着色器}
`;// 定义片段着色器代码
const fsSource = `precision mediump float;varying vec4 v_color;  // 接收来自顶点着色器的颜色void main() {gl_FragColor = v_color; // 输出顶点颜色}
`;// 创建着色器
function createShader(type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {console.error("Shader编译失败: ", gl.getShaderInfoLog(shader));return null;}return shader;
}// 创建程序
function createProgram(vertexShaderSource, fragmentShaderSource) {const vertexShader = createShader(gl.VERTEX_SHADER, vertexShaderSource);const fragmentShader = createShader(gl.FRAGMENT_SHADER, fragmentShaderSource);const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {console.error("Program链接失败: ", gl.getProgramInfoLog(program));return null;}return program;
}// 创建着色器程序
const program = createProgram(vsSource, fsSource);// 获取属性和均匀变量的位置
const a_position = gl.getAttribLocation(program, "a_position");
const a_color = gl.getAttribLocation(program, "a_color");
const v_color = gl.getAttribLocation(program, "v_color");  // 片段着色器接收的颜色gl.useProgram(program);// 定义包含位置和颜色的顶点数据
const vertices = new Float32Array([// 顶点1 位置(x, y) 和颜色(r, g, b, a)0.0,  0.5,  1.0, 0.0, 0.0, 1.0, // 红色// 顶点2 位置(x, y) 和颜色(r, g, b, a)-0.5, -0.5,  0.0, 1.0, 0.0, 1.0, // 绿色// 顶点3 位置(x, y) 和颜色(r, g, b, a)0.5, -0.5,  0.0, 0.0, 1.0, 1.0  // 蓝色
]);// 创建并绑定缓冲区
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 设置顶点位置属性指针
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.enableVertexAttribArray(a_position);// 设置颜色属性指针
gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(a_color);// 清除背景,并绘制三角形
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置清除颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

3. 代码解析

1. 顶点数据的结构

在这个例子中,每个顶点不仅包含位置坐标,还包含颜色信息。我们将这些数据存储在一个 Float32Array 中:

const vertices = new Float32Array([// 顶点1 位置(x, y) 和颜色(r, g, b, a)0.0,  0.5,  1.0, 0.0, 0.0, 1.0, // 红色// 顶点2 位置(x, y) 和颜色(r, g, b, a)-0.5, -0.5,  0.0, 1.0, 0.0, 1.0, // 绿色// 顶点3 位置(x, y) 和颜色(r, g, b, a)0.5, -0.5,  0.0, 0.0, 1.0, 1.0  // 蓝色
]);

每个顶点由 6 个值组成,其中前 2 个值是顶点的位置(x, y),后 4 个值是颜色信息(r, g, b, a)。例如,第一个顶点的位置是 (0.0, 0.5),颜色是红色 (1.0, 0.0, 0.0, 1.0)

2. 设置顶点位置属性指针
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.enableVertexAttribArray(a_position);
  • a_position: 顶点着色器中的位置属性。
  • 2: 每个顶点的属性数量,这里是 2 个(x, y)。
  • gl.FLOAT: 数据类型是浮点数。
  • false: 不进行标准化,直接使用浮点数值。
  • 6 * Float32Array.BYTES_PER_ELEMENT: 每个顶点总共有 6 个浮点数(2 个位置坐标和 4 个颜色值),因此步长是 6 个浮点数的字节数。
  • 0: 顶点数据的起始偏移量,表示从数据的开始位置读取。
3. 设置颜色属性指针
gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 6 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(a_color);
  • a_color: 顶点着色器中的颜色属性。
  • 4: 每个顶点的颜色数据包含 4 个浮点数(r, g, b, a)。
  • 6 * Float32Array.BYTES_PER_ELEMENT: 步长与顶点位置数据一样。
  • 2 * Float32Array.BYTES_PER_ELEMENT: 偏移量为 2 个浮点数,即从位置数据后开始读取颜色数据。
4. 顶点着色器和片段着色器
  • 顶点着色器
    接收位置和颜色数据,并将颜色传递到片段着色器。

    attribute vec4 a_position;  // 顶点位置
    attribute vec4 a_color;     // 顶点颜色
    varying vec4 v_color;       // 从顶点着色器传递到片段着色器的颜色变量
    void main() {gl_Position = a_position;  // 设置顶点的位置v_color = a_color;         // 将颜色传递到片段着色器
    }
    
  • 片段着色器
    接收来自顶点着色器的颜色并将其输出为最终的片段颜色。

    precision mediump float;
    varying vec4 v_color;  // 接收来自顶点着色器的颜色
    void main() {gl_FragColor = v_color; // 输出顶点颜色
    }
    
5. 渲染三角形
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置清除颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);

在这个例子中,我们通过 gl.drawArrays 渲染一个包含 3 个顶点的三角形,每个顶点都有位置和颜色数据。

总结

  • 通过 vertexAttribPointer 可以指定顶点属性的位置和格式,我们在这个示例中将位置和颜色数据一起传递。
  • a_positiona_color 分别对应顶点着色器中的位置和颜色属性。
  • 顶点数据的布局包含位置和颜色信息,在 vertexAttribPointer 中通过偏移量来分别指示位置和颜色数据的起始位置。
  • 顶点着色器将颜色传递给片段着色器,片段着色器最终渲染三角形。

这样,你可以在 WebGL 中渲染带有颜色的三角形,并通过 vertexAttribPointer 控制如何传递和使用顶点数据。


http://www.mrgr.cn/news/83084.html

相关文章:

  • docker+ffmpeg+nginx+rtmp 拉取摄像机视频
  • 数据库中的 DDL、DML 和 DCL
  • C++语言的函数实现
  • 2025年1月4日蜻蜓q旗舰版st完整开源·包含前后端所有源文件·开源可商用可二开·优雅草科技·优雅草kir|优雅草星星|优雅草银满|优雅草undefined
  • 计算机毕业设计Python+卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
  • 韩国机场WebGIS可视化集合Google遥感影像分析
  • Linux系统中解决端口占用问题
  • STM32内置Flash
  • Vue3组件通讯——自定义事件(子->父)
  • C++和Python中负数取余结果的区别
  • python中的列表推导式详解
  • Django学习笔记之数据库(一)
  • 使用redis来进行调优有哪些方案?
  • 消息队列:原理、问题与设计全解析
  • Git撤销指定commit并更新远端仓库
  • 最近在盘gitlab.0.先review了一下docker
  • 总结2024,迎接2025
  • 江科大STM32入门——SPI通信笔记总结
  • leetcode热门100题1-4
  • 生成模型:变分自编码器-VAE
  • 导航技术的分类
  • 创建型模式-原型模式
  • MySQL笔记大总结20250108
  • GDPU Android移动应用 重点习题集
  • 联邦学习LoRA:推理合并权重公式:以及变体
  • uni-app 资源引用(绝对路径和相对路径)方法汇总