The Book of Shaders:运行 Fragment Shader 的完整工具链——glslCanvas、glslViewer、glslEditor 与主流框架集成实战
【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载本指南对应《The Book of Shaders》第 4 章04/README-fr.md的技术主线如何把书中每一章编写的 Fragment Shader 真正跑起来。文章将带你走完作者为本书构建的完整工具生态浏览器显示、命令行渲染、在线编辑、分享与画廊策展并给出在 Three.js、Processing、openFrameworks、SFML 四大主流框架中接入这些 shader 的可运行代码同时结合本仓库04/ 示例目录 与 src/ 站点资源的源码级证据进行印证。读完你即可拥有从写一行 GLSL到在任意平台展示作品的完整实战能力。一、工具生态总览显示、创建、分享、策展这一章的核心是一套由作者Patricio Gonzalez Vivo为本书构建的 shader 工具生态系统覆盖了 shader 工作流的四个环节环节工具典型用途显示DisplayglslCanvas在浏览器canvas中直接渲染独立的 fragment shader本书所有在线示例均由此驱动命令行ConsoleglslViewer在 bash 脚本或 Unix 管道中运行 shader类似 ImageMagick 的用法也是树莓派上编译 shader 的利器创建CreateglslEditor带辅助小部件widgets的 GLSL 编辑器内嵌于本书示例也可作为独立 Web 应用运行分享ShareglslEditor 在线版导出 shader 的唯一 URL或直接导出到 openFrame.io 艺术展示平台策展CurateglslGallery将多个 shader 组织成画廊嵌入任意网站这套工具最重要的特性是跨平台一致同一份 shader 代码无需任何改动即可在 Linux 桌面、macOS、Windows、Raspberry Pi 以及浏览器上以相同方式运行——这也是后续所有章节示例能够复制即用的前提。二、在浏览器中显示glslCanvasglslCanvas 让运行一个独立 shader变得极其简单只需要在 HTML 中放置一个带glslCanvas类的canvas元素并通过data-fragment-url属性指向你的.frag文件即可canvas classglslCanvas>glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -E screenshot,yourOutputImage.pngyourShader.frag要渲染的 fragment shaderyourInputImage.png可选输入纹理-w 500 -h 500输出窗口/图像尺寸为 500×500-E screenshot,yourOutputImage.png执行截图命令把渲染结果保存为yourOutputImage.png。小提示不同翻译版本对该命令的写法略有差异例如 04/README-ch.md 中使用的是-s 1 -o yourOutputImage.png的形式含义同为保存一帧输出图像实际参数以你所安装的 glslViewer 版本帮助为准。glslViewer 的另一大价值是树莓派由于它能够在树莓派上直接编译并全屏显示 shaderopenFrame.io 正是基于它来展示 shader 艺术作品。此外如果你习惯离线使用 SublimeText 编写代码可以安装 glslViewer 的 SublimeText 插件包在编辑器内一键预览 shader见下方 glslViewer 运行效果。四、编写与分享glslEditor为了降低 GLSL 编码的抽象感作者开发了 glslEditor 编辑器它内嵌在本书的实时示例中参见 src/main.js 中.codeAndCanvas元素的解析逻辑编辑器以 250px 画布跟随、右侧浮动、带导出按钮等选项初始化提供一系列实用小部件让代码编辑过程看得见、摸得着。你也可以在浏览器中将其作为独立 Web 应用打开使用。分享能力无论是内嵌版还是独立版编辑器都提供导出按钮——你可以把 shader 保存到线上并获得一个唯一 URL 用于分享甚至可以直接导出为 openFrame.io 兼容格式让 shader 进入数字艺术展框如下方导出流程动图所示。五、策展你的作品glslGallery分享代码只是把 shader 当作艺术作品分享的开始。glslGallery 是一个画廊工具用于把多个 shader 组织成可嵌入任何网站的展示画廊适合作品集或教学页面批量陈列。至此从编写 → 显示 → 分享 → 策展的完整闭环打通。六、贯穿全书的 uniform 命名约定在进入框架集成之前有必要先明确一个约定本书所有 shader 统一使用以下 uniform 变量名从仓库中的示例 shader 可以清楚看到这一规律uniform vec2 u_resolution;画布/窗口分辨率像素用于把gl_FragCoord归一化到 0.0~1.0uniform float u_time;运行以来的秒数驱动动画uniform vec2 u_mouse;或vec3鼠标位置驱动交互。例如 04/processing/data/shader.frag 与 04/sfml/data/shader.frag 中的标准头部即为此约定而主站源码 src/moon/moon.frag 甚至额外使用了u_tex0、u_tex0Resolution这类纹理 uniform。理解了这套命名后续所有框架示例的对应关系就一目了然框架侧只需负责在每一帧把这三个值喂给 GPU 即可。七、在 Three.js 中运行Three.js 是 WebGL 生态中最知名的框架之一。在浏览器中你可以完全复用第二章学到的 shader 代码把它粘贴到下面 HTML 中idfragmentShader的 script 标签里body div idcontainer/div script srcjs/three.min.js/script script idvertexShader typex-shader/x-vertex void main() { gl_Position vec4( position, 1.0 ); } /script script idfragmentShader typex-shader/x-fragment uniform vec2 u_resolution; uniform float u_time; void main() { vec2 st gl_FragCoord.xy/u_resolution.xy; gl_FragColorvec4(st.x,st.y,0.0,1.0); } /script script var container; var camera, scene, renderer, clock; var uniforms; init(); animate(); function init() { container document.getElementById( container ); camera new THREE.Camera(); camera.position.z 1; scene new THREE.Scene(); clock new THREE.Clock(); var geometry new THREE.PlaneBufferGeometry( 2, 2 ); uniforms { u_time: { type: f, value: 1.0 }, u_resolution: { type: v2, value: new THREE.Vector2() }, u_mouse: { type: v2, value: new THREE.Vector2() } }; var material new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: document.getElementById( vertexShader ).textContent, fragmentShader: document.getElementById( fragmentShader ).textContent } ); var mesh new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); container.appendChild( renderer.domElement ); onWindowResize(); window.addEventListener( resize, onWindowResize, false ); document.onmousemove function(e){ uniforms.u_mouse.value.x e.pageX uniforms.u_mouse.value.y e.pageY } } function onWindowResize( event ) { renderer.setSize( window.innerWidth, window.innerHeight ); uniforms.u_resolution.value.x renderer.domElement.width; uniforms.u_resolution.value.y renderer.domElement.height; } function animate() { requestAnimationFrame( animate ); render(); } function render() { uniforms.u_time.value clock.getDelta(); renderer.render( scene, camera ); } /script /body要点拆解顶点着色器示例给出的是一个最简顶点着色器直接把顶点位置原样输出渲染结果是一张覆盖屏幕的 2×2 平面uniforms 容器u_timef类型、u_resolutionv2、u_mousev2在 JS 侧以{ type, value }形式声明与 GLSL 声明一一对应每帧更新render()中通过clock.getDelta()累加u_timeonWindowResize()中刷新u_resolution鼠标移动事件更新u_mouse——这正是第六节所述约定在 Three.js 中的落地方式。仓库中的完整版本见 04/three_js/index.html它在文档示例基础上额外预置了u_mouse的声明与鼠标事件处理可直接打开运行。八、在 Processing 中运行Processing 会在 sketch 的data文件夹中查找名为shader.frag的 shader 文件所以请把书中的示例代码复制进data目录并正确命名PShader shader; void setup() { size(640, 360, P2D); noStroke(); shader loadShader(shader.frag); } void draw() { shader.set(u_resolution, float(width), float(height)); shader.set(u_mouse, float(mouseX), float(mouseY)); shader.set(u_time, millis() / 1000.0); shader(shader); rect(0,0,width,height); }loadShader(shader.frag)加载并编译着色器shader.set(...)向 uniform 传值注意u_time用millis() / 1000.0换算为秒shader(shader)用自定义着色器替换默认管线rect(0,0,width,height)绘制全屏矩形作为广告牌让每个像素都被 shader 处理。兼容旧版本在 Processing 2.1 之前的版本中运行需要在 shader 开头加入一行#define PROCESSING_COLOR_SHADER完整 shader 形如#ifdef GL_ES precision mediump float; #endif #define PROCESSING_COLOR_SHADER uniform vec2 u_resolution; uniform vec3 u_mouse; uniform float u_time; void main() { vec2 st gl_FragCoord.st/u_resolution; gl_FragColor vec4(st.x,st.y,0.0,1.0); }注意此版本中u_mouse声明为vec3。仓库中的完整 sketch 见 04/processing/processing.pde它额外实现了keyPressed()热重载——每次按键都会重新loadShader(shader.frag)方便边改边看配套的 shader 文件位于 04/processing/data/shader.frag。九、在 openFrameworks 中运行与 Processing 类似openFrameworks 也会从data文件夹查找 shader 文件因此需要把.frag文件复制进去并在程序中指定文件名void ofApp::draw(){ ofShader shader; shader.load(,shader.frag); shader.begin(); shader.setUniform1f(u_time, ofGetElapsedTimef()); shader.setUniform2f(u_resolution, ofGetWidth(), ofGetHeight()); ofRect(0,0,ofGetWidth(), ofGetHeight()); shader.end(); }shader.load(, shader.frag)第一个参数是顶点着色器路径留空表示用默认顶点着色器第二个是 fragment shadershader.begin() / shader.end()在两者之间替换渲染管线setUniform1f / setUniform2f分别设置float与vec2类型的 uniform。仓库中的完整工程见 04/openFrameworks/src/ofApp.cpp类声明在 ofApp.h它不仅补全了u_mouse的传递setUniform2f(u_mouse, mouseX, mouseY)还在keyPressed()中实现了按键热重载ofApp.cpp。如果希望以更简洁的方式使用 glslViewer/glslCanvas 规范中的全套 uniforms多缓冲、材质 shader、热重载、以及树莓派上的 OpenGL ES 自动转换文档推荐使用 ofxShader 插件代码可以简化为 allocate load render 三步。十、仓库补充在 SFML 中运行完整 CMake 工程除了文档正文的三个框架本仓库还额外提供了一个 SFMLC 多媒体库的完整可构建示例位于 04/sfml/04/sfml/src/main.cpp创建 800×800 渲染窗口通过shader.loadFromFile(data/shader.frag, sf::Shader::Fragment)加载片段着色器在主循环中用shader.setUniform(u_resolution, ...)、shader.setUniform(u_mouse, ...)、shader.setUniform(u_time, ...)更新三个标准 uniform最后window.draw(shape, shader)以着色器渲染全屏矩形04/sfml/CMakeLists.txt要求 CMake ≥ 3.15、C17通过find_package(SFML 2.5 COMPONENTS graphics REQUIRED)查找依赖并把data目录随目标一起安装04/sfml/data/shader.frag与 Processing 版完全相同的标准 shader 头。由此可见同一份 shader 文件可以在这些框架之间原样复用——这正是本章工具生态与 uniform 约定设计的直接收益。十一、总结从代码到作品的完整路径本章建立了一套可复用的 shader 工作流写用 glslEditor网页版或内嵌版编写调试借助小部件实时观察输出跑浏览器用 glslCanvas 一行canvas嵌入命令行用 glslViewer 接入脚本/管道甚至部署到树莓派或 openFrame.io接入在 Three.js / Processing / openFrameworks / SFML 中只需按u_resolution、u_time、u_mouse约定喂值即可复用书中全部示例分享与策展通过在线编辑器导出唯一 URL或借助 glslGallery 构建可嵌入任意网站的作品画廊。这套约定与工具链将贯穿全书后续所有章节——从 05 章造型函数 开始你在每个章节学到的 shader都可以用本章的方法立即运行、调试与分享。仓库中 04/ 目录下各框架的完整源码是你对照学习的最佳起点。赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐The Book of Shaders 第 04 章实战用 glslCanvas、glslViewer、glslEditor 与三大框架运行你的 Fragment ShaderThe Book of Shaders 第 04 章实战用 glslCanvas、glslViewer、glslEditor 与三大框架运行你的 FragmeThe Book of Shaders 第4章实战用 glslCanvas、glslViewer、glslEditor 与三大框架运行你的 GLSL ShaderThe Book of Shaders 第4章实战用 glslCanvas、glslViewer、glslEditor 与三大框架运行你的 GLSL ShadAnt Design Pagination「更多分页」深度解析省略号折叠与前后跳转按钮的源码实现Ant Design Pagination「更多分页」深度解析省略号折叠与前后跳转按钮的源码实现 导读 本文围绕 Ant Design 官方演示 更多分页说明上一篇Windows 11绕过硬件限制的完整指南让老电脑轻松升级的终极方案下一篇如何让老电脑也能安装Windows 113个简单技巧打破硬件限制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

邮件礼仪与Outlook技巧:从收件人到延迟发送的避坑指南

邮件礼仪与Outlook技巧:从收件人到延迟发送的避坑指南

简介:这份PPT资料聚焦电子邮件礼仪与Outlook使用技巧,面向职场人士、行政人员及需要频繁进行邮件沟通的高校师生,帮助解决邮件回复不及时、收件人选择不当、标题含糊、内容冗长等常见沟通问题,同时提升Outlook客户端的实操效率。资…

2026/10/15 20:44:25 阅读更多 →
计及条件风险价值的电-气综合能源系统能量-备用分布鲁棒优化

计及条件风险价值的电-气综合能源系统能量-备用分布鲁棒优化

做综合能源系统优化这些年,我经常被同一个问题卡住:风电预测误差的真实分布根本不知道,凭什么直接用正态分布或者历史频率分布去做随机优化?这个问题最稳妥的解法之一就是分布鲁棒优化——不要精确分布,只要一批历史场…

2026/10/15 20:44:25 阅读更多 →
Buzz传播四引擎:社交货币、参与门槛、反馈闭环与裂变触点

Buzz传播四引擎:社交货币、参与门槛、反馈闭环与裂变触点

1. “Buzz”不是随便叫的——这个词在当代传播语境里的真实分量“Buzz”这个词最近又刷屏了,不是因为某款新手机发布,也不是哪家大厂开了发布会,而是它自己成了主角。你刷短视频时看到弹幕飘过“这波buzz拉满了”,点开一篇小红书笔…

2026/10/15 20:44:25 阅读更多 →

最新新闻

Python与Pycharm安装过程

Python与Pycharm安装过程

1.Python安装过程 (1)网址:http://www.python.org (2)进入官网后点击顶部导航栏Downloads下的Windows选项,进入下载页面下滑找到3.9.6版本的64位的安装包,点击下载 (3)下…

2026/10/15 21:35:51 阅读更多 →
stm32OTA升级学习笔记(2)

stm32OTA升级学习笔记(2)

实验结果如上图 APP1区上电后等待服务器下发固件包,确认完毕后开始传输,通过帧池缓存收到的数据,同时使用crc校验检验每帧的数据是否正确,加入传输完成帧通知mcu传输结束,并校验总数据crc是否正确,传输完进…

2026/10/15 21:35:51 阅读更多 →
【C++算法打怪专栏】LeetCode 349. 两个数组的交集(哈希集合解法总结)

【C++算法打怪专栏】LeetCode 349. 两个数组的交集(哈希集合解法总结)

【C算法打怪专栏】LeetCode 349. 两个数组的交集(哈希集合解法总结) 一、 题目链接 LeetCode 官方网址:LeetCode 349. 两个数组的交集 二、 核心思路 去重与匹配:题目要求输出的交集结果中每个元素必须是唯一的,且不…

2026/10/15 21:35:51 阅读更多 →
Codex多模型接入实战:网关路由与算力成本优化

Codex多模型接入实战:网关路由与算力成本优化

最近被算力问题折腾得不轻。团队里跑AI辅助开发的服务器队列动不动就要等半小时,云端API的免费配额早就见底,付费额度又贵得肉疼;更要命的是,单一模型处理稍微大一点的代码库,干到一半就上下文溢出,整个任务…

2026/10/15 21:35:51 阅读更多 →
MySQL内置函数实战指南:从字符串到窗口函数的用法与性能陷阱

MySQL内置函数实战指南:从字符串到窗口函数的用法与性能陷阱

写SQL这事儿,入门靠增删改查,进阶拼的就是函数用得熟不熟。拿我自己的经历说,前几年给某业务部门做日报统计数据,要按天汇总订单、还得分渠道、算同比环比,当时我对窗口函数和各种日期函数也不熟,愣是写了一…

2026/10/15 21:35:51 阅读更多 →
任务阻塞不是死机:从采集被 MQTT 堵住讲清 RTOS 测试看什么

任务阻塞不是死机:从采集被 MQTT 堵住讲清 RTOS 测试看什么

副标题:Ready / Blocked / 死循环 / 看门狗,拷机不能只看灯还亮 专栏:《嵌入式学生的方案测试课》第 3 篇 前置:第 2 篇堆栈与死机分层 标签:嵌入式、RTOS、软件测试、物联网、C语言 读者:写过 LiteOS / Fr…

2026/10/15 21:34:50 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →