news 2026/10/16 2:44:47

GLSL mat2 详解:2×2 浮点矩阵的声明、初始化与 The Book of Shaders 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GLSL mat2 详解:2×2 浮点矩阵的声明、初始化与 The Book of Shaders 实战

【免费下载链接】thebookofshaders

Step-by-step guide through the abstract and complex universe of Fragment Shaders.

项目地址:https://gitcode.com/gh_mirrors/th/thebookofshaders
点击查看免费下载

mat2是 GLSL(OpenGL Shading Language)内置的 2 行 2 列浮点矩阵类型,是片段着色器中实现坐标旋转、缩放等空间变换的基础工具。本文以 The Book of Shaders 项目 glossary 词条 为核心,系统讲解mat2的声明方式、初始化规则、元素与列的访问语法,并结合仓库中 第 08 章 及其 .frag 源码给出可直接运行的旋转、缩放实战代码。读完本文,你将掌握mat2的完整语法,并能在自己的着色器中构造旋转矩阵与缩放矩阵。

mat2是什么

mat2表示一个由浮点数构成的 2×2 矩阵,即 2 行 2 列、共 4 个float元素。它是 GLSL 矩阵家族中最小的成员,同族类型还包括mat3(3×3)与mat4(4×4)。

在 The Book of Shaders 的 glossary 中,mat2被描述为 "2x2 floating point matrix"。与普通变量不同,矩阵可以被当作"作用于向量的一组规则":将向量与矩阵相乘,就能以确定的方式平移、旋转或缩放该向量。这也是 第 08 章 "2D Matrices" 的主题——用mat2变换坐标空间,从而移动、旋转画布上的图形。

声明与初始化:四种写法

mat2可以采用以下方式声明并初始化(以下代码完整来自 glossary/mat2 词条):

mat2 aMat2 = mat2(1.0, 0.0, // 第 1 列 0.0, 1.0); // 第 2 列 mat2 bMat2 = mat2(1.0); mat2 cMat2 = mat2(aVec2, bVec2); mat2 dMat2 = mat2(aVec3, aFloat);

关键点在于GLSL 矩阵采用列主序(column-major)构造:构造函数中的参数按"第 1 列 → 第 2 列"的顺序依次填充,注释中标明的"1. column / 2. column"正是这一约定的体现。具体可分为三种初始化方式:

  1. 逐分量指定:mat2(1.0, 0.0, 0.0, 1.0)依次给出 4 个元素,前两个属于第 1 列,后两个属于第 2 列;上面aMat2得到的就是单位矩阵。
  2. 单个标量:mat2(1.0)只给一个值,该值会被同时赋给主对角线上的元素([0][0]与[1][1]),其余元素为 0,因此bMat2同样等价于单位矩阵。
  3. 向量与标量组合:mat2(aVec2, bVec2)表示把两个vec2分别作为第 1 列和第 2 列;mat2(aVec3, aFloat)则混合使用向量与标量——GLSL 允许这种写法,多余的向量分量会被丢弃,不足的部分由后续标量补充。仓库中 mat3 词条 的示例mat3(aVec4, aVec3, bVec4, aFloat)印证了这种混合初始化模式同样适用于更大尺寸的矩阵。

元素与列的访问语法

初始化之后,既可以按"行、列"访问单个元素,也可以按列整体读取或写入一个vec2(代码同样来自 glossary/mat2 词条):

mat2 aMat2; aMat2[1][1] = 1.0; // 写入第 2 行第 2 列 float aFloat = aMat2[1][1]; // 读取单个元素 aMat2[0] = vec2(1.0); // 整列赋值:把第 1 列整体设为 vec2(1.0) vec2 aVec2 = aMat2[0]; // 按列读取

两条规则需要牢记:

  • 单个元素:使用矩阵[列][行]的下标语法,索引从 0 开始,aMat2[1][1]定位到右下角元素。
  • 整列访问:aMat2[0]返回一个vec2,对应第 1 列的两个元素;由于列主序布局,第 0 列恰好就是内存中的前两个浮点数,读取效率很高。

相关类型与函数

mat2经常与同族类型及矩阵专用函数配合使用:

  • mat3:3×3 浮点矩阵,用于二维坐标的 3×3 齐次变换或颜色空间转换。
  • mat4:4×4 浮点矩阵,支持三维空间中的平移、旋转、缩放。
  • matrixCompMult():对两个矩阵做逐分量相乘,result[i][j] = x[i][j] * y[i][j];它与 GLSL 中*运算符的矩阵乘法(行列点积)语义不同,切勿混淆。

仓库实战:用 mat2 构造旋转与缩放矩阵

仅了解语法还不够,第 08 章 的源码演示了mat2最典型的用途——构造 2D 旋转矩阵。在 08/matrices.frag 中可以看到标准写法:

mat2 rotate2D(float angle){ return mat2(cos(angle),-sin(angle), sin(angle),cos(angle)); }

注意构造参数的排列:cos(angle), -sin(angle)构成第 1 列,sin(angle), cos(angle)构成第 2 列——这正是二维旋转矩阵[[cosθ, -sinθ], [sinθ, cosθ]]的列主序填充结果。

由于我们的图形通常绘制在画布中心vec2(0.5)附近,而旋转矩阵是绕原点vec2(0.0)生效的,因此需要遵循"平移 → 旋转 → 平移回去"三步流程。08/cross-rotate.frag 给出了完整实现:

mat2 rotate2d(float _angle){ return mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); st -= vec2(0.5); // 1. 把空间平移到原点 st = rotate2d( sin(u_time)*PI ) * st; // 2. 用 mat2 旋转坐标空间 st += vec2(0.5); // 3. 平移回原位置 color += vec3(cross(st,0.4)); gl_FragColor = vec4(color,1.0); }

图中展示的正是"先平移到原点、旋转、再移回"这一流程:直接用rotate2d的结果去乘st向量(st = rotate2d(...) * st),mat2就完成了对坐标空间的整体旋转,而u_time驱动的sin(u_time)*PI让角度随时间变化,产生往复摆动的动画效果。

同理可构造缩放矩阵。在 08/cross-scale.frag 中:

mat2 scale(vec2 _scale){ return mat2(_scale.x,0.0, 0.0,_scale.y); }

该矩阵把_scale.x、_scale.y分别放在主对角线[0][0]与[1][1]上,对角元素控制 x、y 两个方向的缩放比例;调用时同样遵循平移—缩放—平移的次序,例如st = scale(vec2(sin(u_time)+1.0)) * st。

从源码结构看,仓库中大量示例将旋转矩阵封装为"以原点为中心旋转一个vec2"的辅助函数,例如 09/checks.frag 与 09/rotatedtiles.frag 中的rotate2D,它们在内部完成"减 0.5 → 乘以矩阵 → 加 0.5"的完整流程,并在平铺(tile)空间中旋转每个单元格:

vec2 rotate2D (vec2 _st, float _angle) { _st -= 0.5; _st = mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle)) * _st; _st += 0.5; return _st; }

更多应用场景

mat2的作用远不止图形旋转,仓库中的其他示例展示了它的多样化用途:

  • 减少噪声轴向偏差:13/clouds.frag 在分形布朗运动(fBm)的迭代中构造固定角度的旋转矩阵mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50)),每轮迭代用_st = rot * _st * 2.0 + shift旋转输入坐标,以削弱噪声采样在 x/y 轴上的方向性偏差。
  • CMYK 半调网点:00/cmyk-halftone.frag 中的rotm()函数返回一个mat2旋转矩阵,为青、品红、黄、黑四个颜色通道分别叠加不同的旋转角(15°、75°、0°、45°),实现经典印刷中的半调网角(halftone screen angle)效果:
mat2 rotm (in float r) { float cr = cos(r); float sr = sin(r); return mat2(cr,-sr, sr,cr); }
  • 颜色空间变换:虽然 08/yuv.frag 使用的是mat3,但它展示了矩阵在 GLSL 中的另一类应用——把颜色当作向量,通过矩阵乘法在 RGB 与 YUV 颜色空间之间转换,这也是matrixCompMult()与矩阵乘法容易混淆时最值得对比的示例。

小结

mat2以 4 个浮点数承载二维线性变换:按列主序构造、支持标量/向量混合初始化、可按[列][行]或整列访问。在 The Book of Shaders 中,它是"平移、旋转、缩放"三大空间操作的核心载体,其旋转矩阵mat2(cos(a), -sin(a), sin(a), cos(a))在 第 08 章 及 第 09 章平铺模式 等后续章节中被反复使用。想进一步了解更大尺寸矩阵与矩阵函数,可继续阅读 mat3、mat4 与 matrixCompMult() 词条。

【免费下载链接】thebookofshaders

Step-by-step guide through the abstract and complex universe of Fragment Shaders.

项目地址:https://gitcode.com/gh_mirrors/th/thebookofshaders
点击查看免费下载
上一篇:UE Viewer 使用指南:如何把虚幻引擎游戏里的模型和贴图完整导出
下一篇:Prisma 1.8 升级指南:Management API 迁移、管理数据库 Schema 重命名与新增 migrations 配置

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 2:44:43

流媒体下载实操:跑通 N_m3u8DL-RE 从点播到直播

流媒体下载实操:跑通 N_m3u8DL-RE 从点播到直播 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8DL-RE N_m…

作者头像 李华
网站建设 2026/10/16 2:44:13

Visual Studio 2022 安装教程:从下载到配置,新手避坑完整指南

如果你第一次接触 Visual Studio,大概率会在安装这一步被绕晕:下载器只有几兆,点开之后却要下载好几个 GB,各种“工作负载”“单个组件”看得一头雾水,装完了又不知道选哪个项目模板。我从第一次装到帮别人排查安装问题…

作者头像 李华
网站建设 2026/10/16 2:44:07

安卓离线唐诗三百首应用开发:从数据设计到背诵模式全解析

1. 项目概述与核心动机很多人第一次听到“安卓 唐诗三百首”这个组合时,第一反应往往是“这不就是个本地数据库加列表页面吗?”说实话,三年前我也是这么想的。直到我真正接手了一个类似的项目需求——某个文化类创业团队想做一个面向中小学生…

作者头像 李华
网站建设 2026/10/16 2:44:04

RedisInsight 安装部署完整指南:10 分钟连上你的第一个 Redis

RedisInsight 安装部署完整指南:10 分钟连上你的第一个 Redis 【免费下载链接】RedisInsight Redis GUI by Redis 项目地址: https://gitcode.com/GitHub_Trending/re/RedisInsight 你还在终端里逐条敲 redis-cli 吗?RedisInsight 是 Redis 官方的…

作者头像 李华
网站建设 2026/10/16 2:43:31

你的PC能玩Switch吗?Ryujinx模拟器5分钟安装与流畅运行完整指南

你的PC能玩Switch吗?Ryujinx模拟器5分钟安装与流畅运行完整指南 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx Ryujinx是C#编写的开源任天堂Switch模拟器,能在…

作者头像 李华