attribute 与 uniform 本质区别(WebGL)

attribute 与 uniform 本质区别(WebGL)

都是给着色器传数据,核心差异:数据给谁用、多久变一次、谁负责迭代、内存模型

1. 核心本质

特性 attribute uniform
作用对象 顶点着色器专用 顶点着色器 + 片元着色器都能用
数据频率 逐顶点变化 一次绘制调用内全局不变
数据源 顶点缓冲区 VBO(GPU 显存数组) CPU 单次上传的常量值
迭代方式 GPU 自动遍历每个顶点,每个顶点拿到自己的 attribute 一次 drawCall,所有顶点 / 片元共用同一个值
典型数据 顶点坐标、法线、UV、顶点颜色 变换矩阵、光照颜色、纹理单元、全局参数

attribute

  1. 存放在顶点缓冲区对象 VBO,是一组数组,数组长度 = 顶点数量。
  2. gl.drawArrays/drawElements 的时候,GPU 会自动循环:每处理 1 个顶点,从 VBO 读出当前顶点对应那一组 attribute 数据送入顶点着色器。

例:画三角形 3 个顶点,position 属性数组有 3 组数据,顶点 0 拿第 0 组,顶点 1 拿第 1 组,顶点 2 拿第 2 组。

  1. 只能在顶点着色器声明 ,不能直接在片元着色器用;想给片元,需要通过varying/in输出传递。

uniform

  1. drawCall 整个绘制批次里,全部顶点、全部片元拿到完全相同的值。
  2. 由 CPU 调用gl.uniformXXX()把数值传给 GPU,不是从 VBO 读取。
  3. 顶点、片元着色器都可以直接声明使用。
  4. 一次 draw 调用内部值固定;想要变,CPU 重新调用 uniform 接口修改,再执行下一次 draw。

2. 形象类比

画一个三角形(3 个顶点)

  • attribute:每个人的个人信息。3 个人(顶点),每人有自己的坐标、uv,每个人拿到属于自己那一份。
  • uniform:全局公共设置。比如灯光颜色、投影矩阵,三个人全部共用同一套参数。

3. 关键易错点

  1. ❌ uniform 不能传数组当顶点数据流。uniform 数组只是 "一堆全局常量",不会随顶点自动迭代。大量顶点数据必须走 attribute+VBO。

  2. attribute 数量有限(WebGL1 一般最多 8 个 attribute 槽位);uniform 数量上限更高。

  3. attribute 来自显存 VBO,CPU 只上传一次,之后多次 draw 复用;uniform 每次修改都要 CPU‑GPU 拷贝。

  4. 数据流动:

    CPU内存 → gl.bufferData → VBO显存 → attribute → 顶点着色器

    CPU内存 → gl.uniform* → GPU寄存器 → uniform → 顶点/片元着色器

4. 极简示例

顶点着色器

复制代码
// 逐顶点,每个顶点不一样
attribute vec3 aPos;
attribute vec2 aUv;

// 全局统一,所有顶点一样
uniform mat4 uMvpMatrix;

// 传给片元
varying vec2 vUv;

void main(){
    gl_Position = uMvpMatrix * vec4(aPos,1.0);
    vUv = aUv;
}

片元着色器

复制代码
precision mediump float;
varying vec2 vUv;
// uniform片元也能用
uniform vec3 uLightColor;
uniform sampler2D uTexture;

void main(){
    gl_FragColor = texture2D(uTexture,vUv)*vec4(uLightColor,1.0);
}

5. 什么时候选哪个

  • ✅ 每个顶点不一样 → attribute(位置、uv、法线、顶点色)
  • ✅ 整个物体 / 整个绘制批次全部共用同一个值 → uniform(矩阵、光源、材质颜色、纹理)

补充 WebGL2

WebGL2 语法把attribute改成in(顶点输入),varying改成out/in,逻辑本质完全不变 ;uniform关键字不变。

相关推荐
八荒启·交互动画2 天前
Web特效025—用 Canvas 2D 做Web特效的定义与边界:这支画笔能做到哪一步
前端·webgl·网页特效·八荒启-交互动画·八荒启
Bruce_Liuxiaowei4 天前
网页版 DeepSeek “harness desktop“ WebGL 上下文创建失败排查实录
开发语言·javascript·webgl
像我这样帅的人丶你还8 天前
📱iPhone Duo 开屏动画咋实现的?
javascript·webgl·three.js
夏天要喝冰可乐8 天前
Antigravity + Blender MCP(下):3D 智慧仓储数字孪生进阶实战
前端·webgl·three.js
夏天要喝冰可乐8 天前
Antigravity + Blender MCP(上):打造3D 智慧仓储数字孪生
前端·webgl·three.js
supermapsupport14 天前
SuperMap iClient3D for WebGL 交互式栅格信息查询
webgl·supermap
八荒启·交互动画17 天前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
八荒启·交互动画17 天前
Web特效019-Web特效的定义与边界核心算法手写一遍:先跑起来,再谈高级效果
前端·webgl·网页特效·八荒启-交互动画·八荒启
八荒启·交互动画17 天前
Web特效011—Web特效的定义与边界为什么忽快忽慢:时间、频率与采样的秘密
webgl·网页特效·八荒启-交互动画·八荒启·web特效
八荒启·交互动画18 天前
Web特效008—一个 `getContext(‘webgl‘)`,浏览器到底交出了什么?
webgl·八荒启-交互动画