【免费下载链接】thebookofshaders
Step-by-step guide through the abstract and complex universe of Fragment Shaders.
导读:本文以《The Book of Shaders》开篇章节(00/README-fa.md,仓库中同时提供英文版 00/README.md 与中文版 00/README-ch.md)为核心,系统讲解片段着色器(Fragment Shader)的核心理念——像素级并行计算,并通过仓库中的 CMYK 半调着色器源码 直观对比"串行手绘"与"并行计算"两种图像生产方式。读完本文,你将掌握片段着色器的基本心智模型、GLSL 的跨平台特性、本书的学习路线(程序化图形、图像处理、模拟与 Ray Marching),以及三种离线使用本书的实战方案(本地服务器、树莓派、PDF/EPUB 编译)。
一张封面图揭示的两种图像生产方式
章节开篇的互动画布(<canvas>元素,加载 cmyk-halftone.frag 并配合纹理图 vangogh.jpg)并排展示了两张风格迥异的图像,它们恰好代表了计算机图形学中两种截然不同的思维方式:
- 第一张(梵高风格):由画家一层一层徒手涂抹颜料完成,耗时以小时计。这是一条**串行(serial)**的生产流水线——每个动作都依赖上一个动作的结果,按步骤依次执行。
- 第二张(CMYK 半调点阵):在数秒内由四组像素矩阵组合生成——青色(Cyan)、品红(Magenta)、黄色(Yellow)与黑色(Black)各占一组。其关键区别在于它是非串行(non-serial)的:不是逐步骤推进,而是所有计算同时进行。
这正是本书反复强调的核心命题:片段着色器是"图像领域的古腾堡印刷术"(原文用 Gutenberg's press 类比),它把数字图像的生成方式从"逐像素手工排字"升级为"整版同时压印"。仓库中的 gutenpress.jpg 与 journey.jpg 两张配图分别承载了"印刷术类比"与"真实应用场景(That Game Company 的《Journey》)"两层含义——后者说明片段着色器并非实验室玩具,而是已被用于手机视频滤镜与大型 3D 游戏渲染的成熟技术。
CMYK 半调着色器源码解读:并行计算的最小演示
为了把"非串行"落到实处,仓库中的 00/cmyk-halftone.frag 给出了一个可运行、可交互的完整 GLSL 实现(作者 tsone,来自 Shadertoy)。它的工作原理值得逐段拆解:
// Author: tsone #ifdef GL_ES precision mediump float; #endif #define DOTSIZE 1.48 #define D2R(d) radians(d) #define MIN_S 07.5 #define MAX_S 15.0 #define SPEED 0.3 uniform sampler2D u_tex0; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time;- 精度声明:
#ifdef GL_ES / precision mediump float; / #endif是移动端与浏览器(OpenGL ES 系)必须的浮点精度声明,这是 GLSL 预处理器宏(#ifdef/#endif)的典型用法,本书 02 章 Hello World 会对这套预处理机制展开讲解。 - Uniform 输入:
u_tex0(输入纹理,即梵高原图)、u_resolution(画布分辨率)、u_mouse(鼠标位置)、u_time(运行时间)构成了着色器与外部世界的全部通信渠道——它们正是后续章节(03 章 Uniforms)的主角。
核心算法部分:
vec4 rgb2cmyki (in vec4 c) { float k = max(max(c.r,c.g),c.b); return min(vec4(c.rgb/k,k),1.0); }这是从 RGB 到 CMYK 的经典转换:黑色通道k取三通道最大值,其余三通道各自除以k完成归一。随后halftone()函数以网格取模(grid())的方式把屏幕切分为规则的半调网点,并用smoothstep(ss()函数)实现网点的软边过渡,同时通过两组旋转矩阵mc/mm/my/mk(分别旋转 15°/75°/0°/45°)让四种颜色的网点呈现经典 CMYK 错位角度。鼠标位置还会实时改变网点尺寸S与旋转角R,这正是"可交互示例"的精髓——修改代码或移动鼠标,GPU 会即时重新编译并渲染。
值得注意的是,这个 shader 中没有任何 for 循环、没有像素间的顺序依赖:main()对屏幕上的每一个像素独立执行相同的逻辑,依据gl_FragCoord(像素坐标)与 uniform 输入决定该像素的最终颜色。这就是"非串行"的直接证据——所有像素的计算在同一时刻被 GPU 并行完成。上一章中作为对照的另一份实现 00/halftone.frag(灰度半调,同样由gl_FragCoord驱动)可帮助你进一步对比不同网点算法的写法。
为什么片段着色器快:GPU 的并行架构
理解了"同时计算所有像素",下一个自然的问题是:为什么可以这么快?本书第一章(01/README.md)给出了一个形象的比喻:
- 把 CPU 想象成一根粗大的工业管道,任务是流经管道的工件,任务之间只能串行排队处理;现代 CPU 通常只有数个这样的线程管道。
- 而屏幕上的每个像素都是一个小任务:一个 800×600 的老式屏幕有 480,000 个像素,以 60fps 计算每秒要处理 1,440 万个像素级计算;2880×1800 的 Retina 屏幕在 60fps 下更是高达每秒 3.11 亿次计算——这对串行 CPU 是无法承受的负载。
- GPU 的解法是:用大量微小的处理器并行工作,相当于一张"管道桌"。像素数据像乒乓球一样被分成多批同时推进,吞吐量随并行单元数量线性扩展。
此外 GPU 还拥有硬件加速的数学指令(三角函数、矩阵运算由微芯片直接完成),这正是着色器在图形密集型场景中快得惊人的两个底层原因。当然,并行架构也有代价——第一章同时指出着色器线程彼此"盲目(blind)"且"无记忆(memoryless)":一个线程无法读取其他线程的计算结果,也无法记住自己上一帧在做什么,这是编写着色器时必须时刻牢记的两条约束。
GLSL:一套跨平台的着色语言
本书全程使用GLSL(OpenGL Shading Language),即 OpenGL 的着色语言标准(由 Khronos Group 制定)。GLSL 着色器可以在任何支持 OpenGL、OpenGL ES 或 WebGL 的环境中编译运行,因此你在本书中学到的技能具有极强的可移植性,可以直接用于:
- Processing 中提供了
processing/目录下的.pde示例) - openFrameworks 应用(见 04/openFrameworks 的 C++ 示例)
- Cinder 交互装置
- Three.js 网站(见 04/three_js 的 HTML 示例)
- iOS/Android 游戏
仓库 04 章 的index.php页面正是围绕这套跨平台演示组织起来的,包含 glslEditor、glslGallery、glslViewer 等配套工具的介绍,是"把 GLSL 接入真实项目"的直接参考。
这本书讲什么、不讲什么
覆盖范围(贯穿全文的主线)
本书聚焦于GLSL 像素着色器(pixel/fragment shaders),学习路径大致为:
- 定义与基础:什么是着色器(01)、第一个 "Hello World"(02)、uniform 输入(03)与在各类框架中运行着色器(04);
- 程序化绘制(Algorithmic drawing):造型函数(05)、颜色(06)、形状(07)、矩阵(08)、图案(09);
- 生成式设计(Generative designs):随机(10)、噪声(11)、细胞噪声(12)、分形布朗运动(13);
- 图像处理(Image processing):纹理、图像运算、矩阵卷积、模糊、颜色滤镜、查找表(LUT)等效果;
- 模拟(Simulation):Conway 生命游戏、Gray-Scott 反应扩散、水波、水彩效果、Voronoi 细胞等;
- 3D 图形:光照、法线贴图、凹凸贴图,以及书末的进阶技术Ray Marching(光线步进)。
每章都配有可交互示例——当你修改代码,GPU 会即时重新编译并更新画面。仓库中几乎每个章节目录都同时保存了.frag源码与对应的.png渲染结果(例如 03/space.frag 与 03/space.png),这些正是"改代码立刻见效果"这一学习理念的静态存档,适合离线研读。交互能力本身由仓库根目录的 src/main.js 驱动:它遍历页面中所有.codeAndCanvas容器,调用 GlslEditor 组件加载对应.frag文件(canvas_size: 250、canvas_follow: true、开启 tooltips),把每一段代码块变成可直接编辑的实验台。
明确不覆盖的内容(避免预期偏差)
- 这不是一本 OpenGL/WebGL 的书:OpenGL/WebGL 是比 GLSL 更庞大的主题,本书不讲解渲染管线、状态机等完整 API 体系;
- 这不是一本数学书:虽然会大量使用线性代数与三角学(如上面半调 shader 中的旋转矩阵),但不会系统讲解数学原理。
因此建议读者具备编程经验 + 线性代数与三角学基础。原书针对想先学编程的读者给出的建议是:先上手 Processing 目录正是这条衔接路径的落点。
开始学习需要什么
按原书的说法,"准备"少得令人意外:
只需要一个支持 WebGL 的现代浏览器(如 Chrome、Firefox 或 Safari)与网络连接,点击页面底部的 "Next" 按钮即可开始。
从仓库实现看,这句话是字面意义的:每个章节目录下的 index.php 会把对应的README.md(通过?lan=参数支持多语言切换,波斯语即README-fa.md)交给 Parsedown 渲染成 HTML,而页面头部(header.php)按需加载 GlslCanvas / GlslEditor / GlslGallery 三个前端组件——它们若不存在于本地src/目录,则回退到 CDN。也就是说,一个静态文件服务器 + 浏览器就是全部运行环境。
三种进阶使用方式:离线、树莓派与 PDF/EPUB
原文档末尾列出了三个附录入口,对应三种"不依赖在线浏览器"的使用场景,仓库中均有完整操作说明:
1. 构建离线版本书(appendix/00)
适合长途旅行离线学习。只需 PHP、Python 3 与 git 客户端:
- macOS(需先安装 homebrew):
brew update brew upgrade brew install git php- 树莓派(Raspbian,Debian 系):
sudo apt-get update sudo apt-get upgrade sudo apt-get install git-core glslviewer php环境就绪后,克隆仓库并用 PHP 内置服务器在本地托管(仓库根目录 index.php 与各章 index.php 即站点入口):
cd ~ git clone --recursive https://github.com/patriciogonzalezvivo/thebookofshaders.git cd thebookofshaders git submodule foreach git submodule init && git submodule update php -S localhost:8000随后浏览器打开http://localhost:8000/即可离线浏览全书。
2. 在无浏览器的树莓派上运行示例(appendix/01)
树莓派自带的 Broadcom GPU 可从控制台直接访问。作者为本书专门开发了命令行工具glslViewer:它可以编译并渲染本书全部示例,且支持"保存即重编译"的实时预览——编辑 shader 后保存,画面立即更新,甚至可通过 ssh/sftp 远程编辑。典型用法:
sudo apt-get install git-core glslviewer cd ~ git clone https://github.com/patriciogonzalezvivo/thebookofshaders.git cd thebookofshaders glslviewer 02/hello_world.frag -l # -l 让画面驻留屏幕角落,边编辑边预览3. 编译 PDF / EPUB 打印版(appendix/02)
如果只想获得一本传统纸书,可以按以下流程将全书编译为可打印的book.pdf或电子书book.epub:
- 安装 glslViewer(把各章示例 shader 编译渲染为图片):macOS 用
brew install glslviewer,树莓派用sudo apt-get install git-core glslviewer; - 安装 Python 3、XeTeX 与 Pandoc:macOS 用
brew install --cask mactex-no-gui与brew install pandoc python;树莓派用sudo apt-get install texlive-xetex pandoc python2.7; - 编译:
cd ~ git clone https://github.com/patriciogonzalezvivo/thebookofshaders.git cd thebookofshaders make clean pdf # 生成 book.pdf,可直接打印 make clean epub # 生成 book.epub,可用 Calibre 等工具转 .mobi 供 Kindle 使用这套流程在仓库中有完整的自动化支撑:根目录 Makefile 定义了pdf、epub、tex三个目标,统一调用 src/parseBook.py;该脚本会遍历全部章节目录,把每个章节中的<div class="codeAndCanvas">代码块抽取为独立的.frag文件,并执行glslViewer ... --headless -e wait,0.5 -E screenshot将其渲染成临时 PNG 图片嵌入文档,最后以 Pandoc(xelatex引擎、scrbook文档类、A4 纸型、自动目录)汇总为book.pdf或带封面与元数据的book.epub(--epub-metadata=epub/metadata.xml --epub-cover-image=epub/cover.png)。若只想生成中间产物而不渲染图片,还可使用--skip-image-generation参数。
结语:从这一章开始你的着色器之旅
开篇章节用一张互动画布完成了三件事:建立了"串行 vs 并行"的图像生产心智模型,预告了全书"程序化绘制 → 生成式设计 → 图像处理 → 模拟 → Ray Marching"的递进路线,并给出了三条不依赖在线浏览器的学习路径(本地 PHP 服务器、树莓派 glslViewer、Makefile 编译 PDF/EPUB)。
下一步建议直接打开仓库中的 第一章:什么是片段着色器,那里将回答"着色器为什么快"的完整推导,并首次引入gl_FragColor、vec4、精度修饰符与预处理器宏等 GLSL 核心语法(见 02/README.md 的 Hello World 详解)。如果阅读时卡在某个术语,仓库还提供了一份可检索的 术语表,配合每章的.frag源码与.png渲染结果对照学习,效率会高出很多。
【免费下载链接】thebookofshaders
Step-by-step guide through the abstract and complex universe of Fragment Shaders.
相关推荐
languagemodels与Hugging Face性能对比:为什么它能节省50%内存?
languagemodels与Hugging Face性能对比:为什么它能节省50%内存? 在AI大模型日益普及的今天,内存占用一直是开发者和普通用户面临的主要
The Book of Shaders终极指南:30个惊艳片段着色器效果展示与学习教程
The Book of Shaders终极指南:30个惊艳片段着色器效果展示与学习教程 The Book of Shaders是一份循序渐进的指南,带您探索抽象
完整指南:如何参与The Book of Shaders开源着色器项目
完整指南:如何参与The Book of Shaders开源着色器项目 The Book of Shaders是一个面向初学者的着色器学习开源项目,通过渐进式教
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考