【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载导读本文是开源着色器教材《The Book of Shaders》第一章《入门》Getting started的技术解读面向已经具备编程经验、想进入 GPU 渲染世界的开发者。你将理解片元着色器Fragment Shader到底是什么、为什么它能以惊人的速度处理像素这两个核心问题并掌握并行计算parallel processing、线程thread、GLSL 标准等关键概念为后续章节亲手编写第一个着色器程序打下理论基础。读完本文你不仅能解释 GPU 为何快还能理解为什么 GLSL 代码的写法与传统 CPU 程序如此不同。什么是 Fragment Shader片元着色器从逐笔绘画到一次成像如果你有使用计算机绘图工具例如Paint的经验就会知道传统流程是这样的先画一个圆再画一个矩形、一条线、几个三角形……直到最终拼出想要的图像。这个过程非常像用手逐字写信或写书——它是一系列一条接一条执行的指令属于串行的创作方式。Shader着色器同样是一组指令但区别在于这些指令是对屏幕上的每一个像素同时执行的。这意味着你写的代码必须根据像素在屏幕上的位置产生不同的行为。在第一章之前的引言00/README.md中作者把着色器比喻为图形界的古腾堡印刷机印刷术让文字从逐字手抄变成整页批量复制而 Fragment Shader 让图像从逐笔绘制变成全屏像素并行计算。与印刷机类似你的着色器程序本质上就是一个数学函数它接收一个像素的**位置position作为输入返回这个像素的颜色color**作为输出。一旦编译完成它就会以极快的速度运行——这就是 Fragment Shader 的基本心智模型位置 → 颜色的纯函数映射。与 CPU 程序的本质差异理解这一点非常重要传统 CPU 程序是一次处理一个数据、按顺序完成任务而 Fragment Shader 是同时处理全部数据每个像素、每个像素独立执行同一段代码。因此编写着色器时你思考的不是流程步骤而是给定任意坐标这个点应该呈现什么颜色这一通用规则——这也就是后续章节中作者反复强调的写一个能根据像素位置改变结果的通用函数所需的抽象能力。为什么 Shader 这么快——并行计算的奇迹CPU 的串行流水线隐喻想象计算机的 CPU 是一条巨大的工业管道每个任务就像通过管道的工件类似工厂流水线有些任务更大需要更多时间和能量即需要更多算力processing power。由于计算机的架构这些任务被迫串行执行——每个任务必须等前一个任务完成后才能开始。现代计算机通常拥有多个处理器核心例如 2、4 或 8 核它们像多条小管道一样并行工作。每一条这样的管道就是一个线程thread。像素计算量规模惊人的数学题游戏和其他图形应用需要的算力远超普通程序因为它们必须逐像素做海量运算屏幕上每一个像素都要被计算而在 3D 游戏中还要额外计算几何与透视。让我们用文档中的数字来直观感受这个规模老式800×600屏幕每帧需处理480,000个像素即每秒14,400,000次计算现代2560×1440屏幕、60 FPS每秒达到221,356,800次计算。这个量级足以压垮任何单个微处理器。图形工程师如何解决这个问题GPU用大量小处理器替代少数大处理器答案就是并行处理。与其拥有几个又大又强的微处理器管道不如让大量微型处理器同时并行工作——这正是显卡上 GPU图形处理单元的架构。文档中用一个非常形象的比喻把这些微型处理器想象成一张管道桌把每个像素的数据想象成乒乓球。每秒 14,400,000 个乒乓球几乎能堵死任何一条单独的管道但一张由 800×600 条小管道组成的桌子每秒接收 30 波、每波 480,000 个球却能轻松消化。分辨率越高同理——并行硬件越多能处理的数据流就越大。GPU 的另一项超能力硬件级数学加速除了并行之外GPU 还有一项隐藏优势复杂的数学函数直接在硬件芯片层面完成而不是通过软件模拟。这意味着三角函数、矩阵运算等可以以接近电的速度执行。这一点将在后续章节例如 03/README.md 中提到的sin()、cos()、pow()等硬件加速函数被反复使用——你在 GLSL 里写的sin()、atan()并不是普通的软件函数调用而是显卡芯片直接算出来的。什么是 GLSLGLSL 是OpenGLShadingLanguageOpenGL 着色语言的缩写是本书后续章节中你将看到的着色器程序的标准写法。根据硬件和操作系统的不同还存在其他类型的着色器本书聚焦于由Khronos Group制定的 OpenGL 规范。理解 OpenGL 的历史有助于理解它许多奇怪的约定。GLSL 着色器之所以值得学习是因为它跨平台编译运行同一个 GLSL 程序可以在 OpenGL、OpenGL ES 以及 WebGL 环境中运行因此你学会的知识可以直接迁移到 Processing、openFrameworks、Three.js 网站以及 iOS/Android 游戏等各类项目中见 00/README.md 对全书覆盖范围的说明。从仓库源码看 GLSL 的样子在 02/hello_world.frag 中可以看到最基础的 GLSL 程序结构#ifdef GL_ES precision mediump float; #endif uniform float u_time; void main() { gl_FragColor vec4(1.0,0.0,1.0,1.0); }从这段代码可以提炼出几个关键事实详见 02/README.mdGLSL 与 C 类似程序有一个唯一的main函数最终返回一个颜色最终像素颜色被赋值给保留全局变量gl_FragColor语言内置vec4四维浮点向量等类型对应 RGBA 四个通道且值是归一化的范围0.01.0#ifdef/#endif属于预处理宏GL_ES通常在移动设备和浏览器上编译时被定义**精度precision**至关重要precision mediump float;将所有浮点设为中等精度。低精度渲染更快但质量下降可改为lowp或highpGLSL 规范不保证自动类型转换——vec4(1,0,0,1)这类整数写法可能编译失败。养成良好的习惯浮点字面量务必写小数点1.0而不是1。为什么 Shader 让初学者望而生畏正如能力越大责任越大GPU 强大的并行架构也伴随着严格的限制。文档明确指出两个核心约束约束一线程是盲目的blind要让线程并行运行每个线程管道必须与其他线程完全独立。也就是说线程对其他线程在做什么一无所知。这个限制意味着所有数据只能单向流动无法查看另一个线程的输出结果无法修改另一个线程的输入数据无法把一个线程的输出传递给另一个线程作为输入。如果允许线程间通信数据的完整性就会受到威胁。这是着色器编程与 CPU 编程最本质的思维差异你永远不能依赖邻居像素的计算结果除非使用后续章节介绍的特殊技巧。约束二线程是无记忆的memorylessGPU 会让每个并行微处理器管道保持持续忙碌一旦空闲就立即接收新任务。因此一个线程不可能知道自己上一秒在做什么——它可能上一刻在绘制操作系统的 UI 按钮下一刻在渲染游戏里的一片天空再下一刻在显示邮件正文。每个线程不仅是盲的而且是无记忆的。这两条约束加上编写一个能逐像素改变结果的通用函数所需的抽象思维正是着色器不受初学者欢迎的根本原因。不过好消息是这正是本书存在的意义——接下来我们会一步步从简单到高级地学习各种着色计算。实践路径如何在浏览器中验证这些概念文档特别指出如果你正用现代浏览器阅读本书你将能直接玩转交互式示例。在仓库中交互式示例通过嵌入的 Canvas 渲染例如 01/index.php 会读取对应章节的README-*.md文件并用 Parsedown 渲染同时配合 00/README.md 中的canvas>赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐The Book of Shaders 第 02 章详解GLSL Fragment Shader 的 Hello World——gl_FragColor、vec4 与精度声明The Book of Shaders 第 02 章详解GLSL Fragment Shader 的 Hello World——gl_FragColor、veThe Book of Shaders 实战指南在 Three.js、Processing 与 openFrameworks 中运行 Fragment ShaderThe Book of Shaders 实战指南在 Three.js、Processing 与 openFrameworks 中运行 Fragment ShaAnt Design Pagination「更多分页」深度解析省略号折叠与前后跳转按钮的源码实现Ant Design Pagination「更多分页」深度解析省略号折叠与前后跳转按钮的源码实现 导读 本文围绕 Ant Design 官方演示 更多分页说明创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?