尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
The Book of Shaders 第 08 章精读:用 GLSL 二维矩阵(mat2)实现片元着色器中的平移、旋转与缩放
【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载本篇技术指南围绕开源着色器教程仓库 The Book of Shaders 的第 08 章「2D Matrices二维矩阵」展开核心主题是在片元着色器中一切形状变换的本质都是移动坐标系本身而矩阵mat2/mat3/mat4正是完成这类坐标变换的数学工具。读完本文你将掌握 GLSL 矩阵的声明与初始化方式、mat2平移/旋转/缩放矩阵的构造公式以及如何把「先平移 → 变换 → 再平移回来」的复合变换套路直接用于以 cross-translate.frag、cross-rotate.frag、cross-scale.frag 为代表的实时交互示例最终还能将矩阵思维迁移到 YUV 色彩空间转换等非几何领域。为什么是「移动坐标系」而不是「移动物体」上一章第 07 章《Shapes》我们学会了在归一化坐标st gl_FragCoord.xy/u_resolution.xy上借助smoothstep构造方框、十字等形状。要让这些形状动起来最直观的直觉是「把图形挪到别的位置」但在片元着色器里没有物体可言——每一个片元都独立计算颜色它只知道自己当前的坐标。因此本章给出的核心技巧是平移形状 平移整个坐标空间。具体做法非常朴素直接给保存每个片元位置的st变量加上一个向量整个坐标系就会随之移动从而形状相对画布发生了位移。这正是 cross-translate.frag 中的做法vec2 translate vec2(cos(u_time), sin(u_time)); st translate * 0.35;其中u_time是片元着色器内置的动画时间变量cos(u_time)与sin(u_time)构成一个单位圆轨迹*0.35把位移幅度限制在画布的 35% 范围内十字形便沿圆周运动。用示意图可以直观理解坐标系整体被偏移图形在屏幕上的位置随之改变。交互验证方式在 cross-translate.frag 中取消第 35 行color vec3(st.x, st.y, 0.0);的注释就能把当前的坐标值直接画成背景颜色亲眼看到「空间本身在移动」——画面会呈现随坐标变化的渐变而十字叠加其上。动手练习让运动「有意思」原文档给出一个开放式练习结合u_time与造型函数第 05 章介绍过的 easing / shaping 函数让十字按某种你感兴趣的真实运动规律移动——比如波浪的起伏、钟摆的摆动、弹跳的球、加速的汽车或刹车的自行车。实现要点是先记录或想象目标运动曲线再用sin、pow、smoothstep等函数去逼近它例如钟摆可用sin(u_time)的绝对值做往返、弹跳球可用abs(sin(u_time))制造落地反弹的视觉节奏。GLSL 矩阵基础mat2 / mat3 / mat4 与乘法要实现比平移更复杂的旋转与缩放需要引入矩阵。原文档明确说明矩阵是按行列组织的数字集合向量按照一套精确规则与矩阵相乘从而按特定方式修改向量取值。GLSL 原生支持二、三、四维浮点方阵mat22x2 矩阵mat33x3 矩阵mat44x4 矩阵。GLSL 同时支持矩阵乘法*运算符即线性代数意义上的矩阵相乘与逐分量相乘函数matrixCompMult()。两者语义完全不同matrixCompMult(x, y)的结果矩阵第i行第j列等于x[i][j] * y[i][j]对应元素相乘而*是矩阵乘法行列内积。矩阵的类型以列优先column-major存储声明时可逐列提供数值也可只给一个对角值或用向量与标量混合构造例如 glossary 中mat2的声明示例mat2 aMat2 mat2(1.0, 0.0, // 第 1 列 0.0, 1.0); // 第 2 列 mat2 bMat2 mat2(1.0); // 对角均为 1.0 mat2 cMat2 mat2(aVec2, bVec2);元素访问也支持按列下标或分量两种方式如aMat2[1][1]或aMat2[0]取出第一列组成的vec2。这部分细节在 glossary/mat2/README.md、glossary/mat3/README.md、glossary/mat4/README.md 中有完整描述。旋转rotate2d 与「平移到中心再旋转」矩阵最有趣的能力是旋转坐标系。基于旋转矩阵公式可以构造绕原点vec2(0.0)旋转的二维旋转矩阵mat2 rotate2d(float _angle){ return mat2(cos(_angle), -sin(_angle), sin(_angle), cos(_angle)); }但按照第 07 章绘制形状的方式十字形是绘制在画布中心的对应位置是vec2(0.5)而不是vec2(0.0)。如果直接应用上面的旋转矩阵十字会绕着画布左下角原点旋转而不是绕自身中心旋转。因此标准套路是三步走见 cross-rotate.frag// 1. 先把空间从中心移到原点 st - vec2(0.5); // 2. 旋转空间 st rotate2d(sin(u_time) * PI) * st; // 3. 再移回原来的位置 st vec2(0.5);其中PI通过#define PI 3.14159265359定义sin(u_time) * PI让旋转角在-π到π之间往复摆动而不是单向转圈。配套练习取消 cross-rotate.frag 第 45 行color vec3(st.x, st.y, 0.0);的注释观察被旋转后的坐标空间长什么样把旋转前后的两行平移第 37、39 行注释掉观察后果十字会绕着画布角落旋转而非自身中心旋转坐标背景也会暴露旋转中心把旋转技巧用到上一节平移练习的动画中——这正是 cross-animated.frag 所演示的「旋转 平移」组合先平移到原点旋转、移回中心再叠加圆周平移让十字边转边走。缩放对角矩阵与尺度因子如果你用过 3D 建模软件或 Processing 中的pushMatrix/popMatrix就会知道矩阵同样用于缩放物体大小。按照前面的公式二维缩放矩阵就是对角线上放置缩放因子的对角矩阵mat2 scale(vec2 _scale){ return mat2(_scale.x, 0.0, 0.0, _scale.y); }cross-scale.frag 中的实际调用同样遵循「移中心 → 变换 → 移回」套路且缩放系数随时间脉动st - vec2(0.5); st scale(vec2(sin(u_time) 1.0)) * st; st vec2(0.5);注意vec2(sin(u_time) 1.0)的取值范围sin(u_time)在[-1, 1]加 1 后落在[0, 2]。当缩放因子趋近 0 时图形缩到不可见等于 1 时保持原大小大于 1 时放大——而且缩放会同时作用于图形与坐标网格。配套练习取消 cross-scale.frag 第 42 行注释观察坐标空间被缩放的实况注释掉第 37、39 行的前后平移观察缩放中心从图形中心变成画布原点后图形的「漂移」尝试把旋转矩阵与缩放矩阵相乘再作用于向量st rotate2d(angle) * scale(vec2(s)) * st;注意顺序至关重要——先构造复合矩阵先缩放后旋转再乘以坐标向量顺序不同结果截然不同综合运用已学的绘制、平移、旋转、缩放能力创作一个伪 UI / HUD抬头显示器风格的组合画面参考 ShaderToy 上 Ndel 的 HUD 类作品获取灵感。综合案例cross-animated.frag 中的复合变换cross-animated.frag 把三种变换串在一起是本章标准的「全家福」示例// 旋转部分移中心 → 旋转 → 移回 st - vec2(0.5); st rotate2d(sin(u_time * 0.5) * PI) * st; st vec2(0.5); // 平移部分整个空间再叠加圆周位移 vec2 translate vec2(cos(u_time), sin(u_time)); st translate * 0.35; // 绘制十字 color vec3(cross(st, 0.25));从源码结构看这里演示了变换的顺序性与可组合性先旋转再平移十字一边自旋一边沿圆周运动。若调换顺序先平移后旋转运动轨迹会完全不同——这正是矩阵乘法不满足交换律的直观体现也是练习「组合变换」时的最佳实验场。矩阵的非几何应用YUV 色彩空间转换矩阵不只是几何工具。原文档指出YUV 是模拟照片与视频编码常用的色彩空间利用人眼感知特性降低色度分量的带宽需求。RGB 与 YUV 之间的换算本质上就是一次 3x3 矩阵乘法——颜色可以被当作向量处理用矩阵「搬运」各分量数值。仓库中的 yuv.frag 给出了完整实现直接定义两个 3x3 矩阵// YUV to RGB matrix mat3 yuv2rgb mat3(1.0, 0.0, 1.13983, 1.0, -0.39465, -0.58060, 1.0, 2.03211, 0.0); // RGB to YUV matrix mat3 rgb2yuv mat3(0.2126, 0.7152, 0.0722, -0.09991, -0.33609, 0.43600, 0.615, -0.5586, -0.05639);主函数中把屏幕坐标重映射到[-1, 1]区间YUV 的 UV 分量正好落在该区间再作为三维向量的 y、z 分量与yuv2rgb矩阵相乘st - 0.5; // 从 0.0~1.0 变为 -0.5~0.5 st * 2.0; // 变为 -1.0~1.0 color yuv2rgb * vec3(0.5, st.x, st.y);固定 Y 亮度值为 0.5让 UV 随屏幕坐标变化最终画布呈现出连续的 YUV→RGB 色彩映射。这个例子证明凡是能用向量表达的数据几何坐标、颜色、纹理坐标都可以套用矩阵变换的同一套数学框架。拓展从 mat2 到 mat3 / mat4 的三维变换仓库中的 matrices.frag 把二维矩阵推广到三维与齐次坐标场景是理解本章主题边界的绝佳补充。该文件定义了绕 X/Y/Z 轴旋转的mat3与mat4版本rotateX3D/rotateX4D、rotateY3D/rotateY4D、rotateZ3D/rotateZ4D三维缩放矩阵scale4D(x, y, z)对角线放置缩放因子齐次坐标平移矩阵translate4D(x, y, z)——注意平移在 2x2 矩阵中无法表达必须升维到 4x4 齐次矩阵最后一行(x, y, z, 1.0)承担平移分量。从源码结构看二维旋转矩阵正是三维旋转矩阵在 Z 轴方向的特例rotateZ3D(psi)的左上 2x2 块与本章rotate2d完全一致。这意味着本章掌握的矩阵思维可以无缝升级到三维着色器编程。运行与实验方式在线交互本书网站本仓库即其镜像通过div classcodeAndCanvas datacross-translate.frag/div这类标记把每个示例嵌入页面配合 glslEditor 在线编辑器实时编辑运行第 04 章 README.md 介绍了 glslViewer、glslEditor、glslGallery 三件套的用法本地渲染可用 glslViewer 之类的命令行工具直接编译运行.frag文件glslViewer yourShader.frag yourInputImage.png --w 500 -h 500离线编辑.frag文件均为纯文本 GLSL 代码任何编辑器都能打开阅读配合上述工具即可逐行验证本章练习。小结本章从「移动坐标系而非物体」这一核心思想出发用三块矩阵完成了二维空间中最基本的三种变换变换矩阵形式仓库示例平移st translate加法即可无需矩阵cross-translate.frag旋转mat2(cos, -sin, sin, cos)cross-rotate.frag缩放mat2(sx, 0, 0, sy)对角矩阵cross-scale.frag所有变换都遵循「先平移到原点 → 施加变换 → 平移回原处」的三步套路且复合变换时矩阵乘法的顺序决定最终效果。这些能力是下一章用已学形状拼出程序化图案procedural patterns的基础。正如 SUMMARY.md 所总结的矩阵是操纵向量的强大工具掌握了它你就能自由地平移、缩放、旋转任何形状——而任何能用向量表达的东西颜色、UV、坐标都可以套用同一套方法。后续章节还会反复用到这一章建立的变换思维。赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐The Book of Shaders 第 08 章精讲用 2D 矩阵变换平移、旋转与缩放着色器图形The Book of Shaders 第 08 章精讲用 2D 矩阵变换平移、旋转与缩放着色器图形 本篇文章围绕《The Book of Shaders》第ModelScope 训练器基类解析从 BaseTrainer 与 DummyTrainer 理解训练器架构ModelScope 训练器基类解析从 BaseTrainer 与 DummyTrainer 理解训练器架构 导读 本文以 ModelScope 开源框架的官The Book of Shaders 第三章精讲GLSL uniform 与 gl_FragCoord 的片元着色器实战The Book of Shaders 第三章精讲GLSL uniform 与 gl_FragCoord 的片元着色器实战 本篇文章以《The Book of上一篇Rust版本管理终极指南高效切换工具链提升开发效率下一篇为什么选择Gigatoken6大核心优势让大模型训练效率提升80%创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

基于Flask的大学生体质测试系统:完整开发与部署实战

基于Flask的大学生体质测试系统:完整开发与部署实战

说起来这套 Python flask 大学生体质测试系统,是我帮某高校体育部做的一套内部管理工具。以前他们年度体测的数据全靠纸质表加 Excel 存,辅导员催数据靠打电话,体育老师统计成绩靠手动核对,每年体测季都是一场持久战。后来我花了几…

📅 2026/10/15 7:03:00
Qt5.9版本如何方便在子线程更新Ui

Qt5.9版本如何方便在子线程更新Ui

Qt5.10增加QMetaObject::invokeMethod接口lambda的重载&#xff0c;使用比较方便。碍于公司使用的依旧是5.9.7版本&#xff0c;所以按照Qt5.10的使用方式做一个类似的封装。实现如下 class FuncInvoker:public QObject { public:FuncInvoker(std::function<void()>& …

📅 2026/10/15 7:03:00
UE5.6/5.7 MetaHuman C++编译报错排查:模块依赖与版本匹配实战指南

UE5.6/5.7 MetaHuman C++编译报错排查:模块依赖与版本匹配实战指南

说实话&#xff0c;第一次在 UE5.6 上往项目里接 MetaHuman 的时候&#xff0c;我差点被编译报错劝退。明明代码逻辑还没怎么写&#xff0c;构建输出窗口里先堆了三四十条红色错误&#xff0c;扫一眼全是跟 MetaHumanSDK、ControlRig、RigLogic 相关的头文件找不到、符号无法解…

📅 2026/10/15 6:58:00
MORE NEWS

更多资讯

📰

微信小程序投票系统怎么从零搭建?以活动评选为例的完整流程

从技术视角看&#xff0c;在微信生态里"创建一个投票活动"&#xff0c;本质是配置一套活动数据结构 报名审核状态机 防刷策略 数据导出能力。本文以「活动评选」场景为例&#xff0c;梳理从创建到发布的完整流程&#xff0c;并以投票帮小程序作为落地实践案例。 …

📰

T型三电平逆变器VSG自适应控制与并离网切换优化

1. 项目背景与核心价值电力电子变换器在新能源发电系统中扮演着关键角色&#xff0c;而T型三电平逆变器因其高效率、低损耗的特性&#xff0c;在中大功率场合得到广泛应用。传统逆变器控制策略在并离网切换过程中常面临暂态冲击大、同步性能差等问题&#xff0c;这正是虚拟同步…

📰

COMSOL电弧熔池耦合仿真技术与焊接工艺优化

1. 电弧熔池耦合仿真技术概述在工业制造领域&#xff0c;电弧熔池耦合过程是焊接、金属增材制造等工艺的核心物理现象。通过COMSOL Multiphysics对这一多物理场过程进行建模仿真&#xff0c;可以深入理解熔池动态行为、优化工艺参数并预测成形质量。这种仿真技术能够同时考虑电…

📰

外贸找客户别再手扒谷歌地图了:我用一个 AI 专家一句话拿到海外商户名单

前言&#xff1a;开发客户最贵的成本&#xff0c;是"找名单"做外贸和跨境电商的朋友应该都有这个体会&#xff1a;真正吃掉时间的不是谈单&#xff0c;而是找名单。流程大概是这样的——打开谷歌地图&#xff0c;输入「LED wholesaler 某个城市」&#xff0c;然后一…

📰

《小王子》第十六章的文学分析与哲学启示

1. 章节背景与文学价值解析《小王子》第十六章作为圣埃克苏佩里这部经典作品的关键转折点&#xff0c;描绘了主人公来到地球后的首个深刻观察。这一章通过地理学家角色引出了全书核心命题——成年人世界与孩童视角的本质冲突。开篇用"第七颗行星是地球"的平淡陈述&am…

📰

用电器分析识别装置:电流波形特征提取与分类器实战

简介&#xff1a;这份PDF是2021年全国大学生电子设计竞赛本科组H题「用电器分析识别装置」的完整赛题文档&#xff0c;面向备战电赛的高校学生与指导教师&#xff0c;帮助读者快速掌握题目任务、指标约束与评分细则。资源包共1个PDF文件&#xff0c;约315KB&#xff0c;内容为官…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬