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关键字不变。

相关推荐
新的瑞拉公主1 天前
Unity游戏发布微信小游戏:从构建到提审
unity·webgl·微信小游戏·开放数据域
慧都小妮子3 天前
实时大屏掉帧排查:WebGL 图表库选型的 5 项可实测检查
webgl·scichart.js·实时大屏掉帧·前端图表选型
❀͜͡傀儡师3 天前
移动端 360° 商品展示方案:从 20MB 雪碧图到 800KB 丝滑视频
ffmpeg·webgl·sprite
平行云3 天前
国产GPU云渲染适配实战:驱动兼容、编码调优与多路并发
unity·ue5·webrtc·webgl·实时云渲染·云桌面·像素流送
平行云6 天前
实时云渲染信创架构解析:从GPU池化到全栈适配的技术演进
linux·unity·docker·ue5·webgl·数字孪生·实时云渲染
yyt3630458418 天前
KLineChartQuant:GLSL 的精度问题及 RTC 解法
前端·vue.js·react.js·交互·图形渲染·webgl·数据可视化
灵境(虚幻知音)9 天前
WebGL 不支持>1px的线绘制,那 Cesium 的带宽度的线是怎么画出来的?
webgl·cesium·着色器
云登指纹浏览器10 天前
浏览器指纹检测原理演进:从Canvas到WebGL的4轮风控升级
webgl
前端老爷更车13 天前
从 `renderer.render()` 到地面上的阴影:Three.js 阴影渲染全流程源码解析
webgl
Highcharts.js15 天前
Highcharts 渲染方式解析:SVG 默认渲染与 Boost 模块的 WebGL 加速,以及它与其他可视化库的不同
svg·webgl·可视化·canvas·highcharts·渲染方式