The Book of Shaders 实战:GLSL 片段着色器的第一个 Hello World 逐行解析
【免费下载链接】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/README-tr.md 及其英文原版 02/README.md完整讲解片段着色器Fragment Shader的入门示例——用 GLSL 语言让画布上每一个像素呈现同一种颜色。读完本文你将掌握片段着色器程序的最小骨架main函数、输出变量gl_FragColor、vec4向量类型、预处理器宏与浮点精度声明并能识别最常见的白屏编译错误根因。在传统的编程学习中Hello world 是接触一门新语言的第一步一行简单的代码输出一句热情的问候。但在 GPU 的世界里第一步就渲染一行文字是过度复杂的任务——文本渲染需要字形、纹理与采样等一整套管线。因此本书的入门方式改为为画布上每一个像素选择一种明亮的欢迎色让整块画布喊出我们的热情。这也是理解片段着色器本质的最佳起点着色器是一段对屏幕上的每一个像素同时执行的程序它接收像素的位置返回该像素的颜色。先看完整代码hello_world.frag本仓库第二章的示例着色器位于 02/hello_world.frag全文只有 9 行#ifdef GL_ES precision mediump float; #endif uniform float u_time; void main() { gl_FragColor vec4(1.0,0.0,1.0,1.0); }当你在浏览器中阅读本书时页面上的代码块是可交互的可以点击并修改任意一行代码改动会立刻反映到旁边的实时预览画布上。这是因为本书站点src/main.js在页面加载时会把所有带data属性的.codeAndCanvas元素交给 GlslEditor 处理着色器代码借助 GPU 架构被on the fly即时重新编译并替换无需刷新页面。因此你可以大胆地把第 8 行的四个数值改成任意值观察颜色变化。别看这段代码只有寥寥数行从中可以推导出片段着色器最核心的七条知识点。1. 单一入口main 函数GLSLOpenGL Shading Language与 C 语言一样要求程序包含一个名为main的入口函数。片段着色器没有返回值传递机制而是通过预设的全局输出变量把颜色交给管线void main() { gl_FragColor vec4(1.0,0.0,1.0,1.0); }void main()是片元fragment着色阶段的唯一入口GPU 会为画布上的每一个像素/片元并行调用它最终像素颜色被赋给保留字全局变量gl_FragColor即 GLSL 内置的输出变量参见仓库术语表 glossary/gl_FragColor/README.md与上一章 01/README.md 中描述的并行架构一致每个线程彼此盲且无记忆只负责计算自己负责的那个片元的颜色。2. 第一次认识 vec4四分量浮点向量vec4是 GLSL 的内建类型表示四维浮点向量。从代码vec4(1.0,0.0,1.0,1.0)的四个参数可以推断它们分别对应参数位置通道含义第 1 个RRed红色分量第 2 个GGreen绿色分量第 3 个BBlue蓝色分量第 4 个AAlpha透明度分量同时可以注意到这些值都是**归一化normalized**的——取值范围限定在0.0到1.0之间。归一化之所以重要是因为它让不同变量、不同维度之间的数值可以方便地互相map映射例如把一个坐标值直接映射到颜色通道或把时间值映射到透明度。这也是后续章节反复使用的核心技巧。除vec4外GLSL 还提供vec3三分量浮点向量和vec2二分量浮点向量以及最常用的标量类型float、int、bool。仓库的术语表对每种类型的构造方式有完整说明例如 glossary/vec4/README.md、glossary/vec3/README.md、glossary/vec2/README.md 与 glossary/float/README.md。3. 预处理器宏GL_ES 与条件编译GLSL 继承了大量 C 语言的预处理特性。所有宏命令以#开头在正式编译之前的预编译阶段被处理#define定义宏/全局常量#ifdef若某宏已定义则编译其后代码#ifndef若某宏未定义则编译其后代码#endif结束条件块。回到我们的示例#ifdef GL_ES precision mediump float; #endif这里仅当宏GL_ES被定义时才插入第 2 行的精度声明。GL_ES通常在移动设备与浏览器WebGL / OpenGL ES 环境中编译着色器时自动定义而在桌面 OpenGL 环境中则不一定存在。因此这段包裹让同一个着色器既能跑在 WebGL 上也能兼容桌面环境。这是编写跨平台着色器的惯用写法在仓库几乎所有示例如 05/step.frag、07/circle.frag 等的头部都能看到同一模式。4. 浮点精度声明precision mediump float浮点类型在着色器中至关重要而**精度precision**直接决定了渲染速度与质量之间的取舍声明精度适用场景precision lowp float;低精度渲染最快但数值误差大、画质损失明显precision mediump float;中精度速度与质量的平衡点本书示例的默认选择precision highp float;高精度质量最高但渲染开销更大示例中的precision mediump float;把后续所有浮点变量统一设置为中精度你也可以按需为每个变量单独指定精度。精度不仅影响颜色渐变的平滑度还会影响数值运算的稳定性——例如在后面的噪声、分形章节中低精度会直接导致图案出现可见的条带或块状瑕疵。仓库术语表 glossary/precision/README.md 与 glossary/mediump/README.md 对相关声明做了归档。5. 最关键的陷阱GLSL 不保证自动类型转换GLSL 规范不保证变量会被自动强制转换implicit cast。原因在于显卡制造商为了加速图形处理会采取各自不同的实现策略他们只需要保证满足规范的最低要求而自动类型转换并不在最低要求之列。vec4是浮点精度的向量因此它的四个参数必须是float。请看这段不总是能运行的错误代码void main() { gl_FragColor vec4(1,0,0,1); // 错误整数传给浮点向量可能编译失败 }1、0是整数int而vec4期望浮点float。在有些显卡驱动上这段代码也许能侥幸通过但在另一些驱动上会直接编译失败——呈现一片白屏。规范要求我们养成在浮点数值后加上小数点.的习惯例如1.0、0.0。对于从 C/Java 等语言转来的读者这与(float) 1的显式 cast 语法不同GLSL 的cast就是在字面量上写出小数点。6. 动手实验把知识变成手感理解了上述要素之后就是点击代码块、亲手验证所学的时候了。请记住一旦代码编译失败程序不会运行画布会显示白屏。以下四组练习按难度递进练习一用整数替换浮点void main() { gl_FragColor vec4(1,0,0,1); }把第 8 行的1.0、0.0换成1、0观察你的显卡/浏览器驱动是否容忍这种行为——在不同设备上结果可能截然不同。练习二注释掉颜色赋值void main() { // gl_FragColor vec4(1.0,0.0,1.0,1.0); }把第 8 行注释掉不给main()赋任何像素值。程序同样无法通过编译屏幕将保持白色。练习三自定义函数返回颜色把返回特定颜色的逻辑封装成独立函数并在main()中调用vec4 red(){ return vec4(1.0,0.0,0.0,1.0); } void main() { gl_FragColor red(); }练习四探索 vec4 的多种构造方式vec4并不只有四个标量参数这一种构造写法。可以混合使用向量与标量甚至用一个标量填充所有分量。例如vec4 color vec4(vec3(1.0,0.0,1.0),1.0);此外仓库术语表 glossary/vec4/README.md 还收录了这些合法构造方式vec4 aVec4 vec4(1.0, 1.0, 1.0, 1.0); // 四个标量 vec4 bVec4 vec4(1.0); // 单个标量填充所有分量 vec4 cVec4 vec4(aVec2, aFloat, aVec3);// 向量与标量混合构造函数的参数分量总数必须不小于目标向量的分量数这是 GLSL 的硬性约束。7. 这只是起点下一步是空间与时间尽管整块画布同一颜色看起来并不刺激它却是最基础的示例——我们改变了画布内每一个像素的颜色尽管是相同的颜色。这也意味着着色器代码必须能根据像素在屏幕上的位置产生不同行为这正是片段着色器与普通 CPU 程序最本质的差异。下一章 03/README.md 将介绍两种驱动像素变化的输入源它们也对应着本书后续绝大部分示例的骨架空间space像素在屏幕上的位置坐标gl_FragCoord时间time页面加载后经过的秒数u_time。届时你会看到u_time、u_resolution、u_mouse这类uniform输入如何与sin()、cos()等硬件加速的数学函数组合让画布从一个静止的颜色变成流动的图案。而本示例 02/hello_world.frag 头部声明的uniform float u_time;正是为那个方向埋下的伏笔——虽然本章尚未使用它但它已经出现在每一个示例的模板中。赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐The Book of Shaders 第 2 章详解用 Hello World 片段着色器入门 GLSLThe Book of Shaders 第 2 章详解用 Hello World 片段着色器入门 GLSL 本篇基于 The Book of ShaderThe Book of Shaders 入门实战从 GLSL Hello World 读懂片段着色器的 7 个核心要点The Book of Shaders 入门实战从 GLSL Hello World 读懂片段着色器的 7 个核心要点 导读 本文以开源教程《The BookThe Book of Shaders 第 2 章解析用 Hello World 掌握 GLSL 片元着色器的基础语法The Book of Shaders 第 2 章解析用 Hello World 掌握 GLSL 片元着色器的基础语法 本文基于 The Book of Sh上一篇agentic-awesome-skills 技能锻造指南用 Andru.ia Skill-Smith 按钻石标准设计、编写与部署新技能下一篇ccusage 仓库的 GitHub PR 评审自动化实战用 gh api 处理行内评论线程与解析状态创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

TheBigPromptLibrary 实战:拆解「22.500+ Best Custom GPTs」——如何用一份指令构建 GPT 检索推荐 Agent

TheBigPromptLibrary 实战:拆解「22.500+ Best Custom GPTs」——如何用一份指令构建 GPT 检索推荐 Agent

提示工程AI 安全治理 【免费下载链接】TheBigPromptLibrary A collection of prompts, system prompts and LLM instructions 项目地址: https://gitcode.com/gh_mirrors/th/TheBigPromptLibrary 点击查看 免费下载 导读:本文以 TheBigPromptLibrary 仓…

2026/10/15 3:46:43 阅读更多 →
企业布局 GEO 要避开哪些陷阱,传播易解析 AI 采信底层规则

企业布局 GEO 要避开哪些陷阱,传播易解析 AI 采信底层规则

随着大语言模型、AI智能搜索逐步取代传统关键词检索,成为用户信息获取的核心渠道,企业品牌营销的底层逻辑正在发生根本性、结构性变革。生成式引擎优化(GEO)的核心逻辑,是依托人工智能模型整合全网权威信源,自动生成精准答案、输出…

2026/10/15 3:45:43 阅读更多 →
机器人学导论课后习题答案:从对答案到建立推导校验体系

机器人学导论课后习题答案:从对答案到建立推导校验体系

简介:《机器人学导论》第三版课后习题答案手册(Solutions Manual)是John J. Craig所著经典教材的配套辅导资料,由Alice Dworkin担任副编辑整理,主要面向机器人学课程的本科生、研究生以及需要备课的教师。手册逐题给出…

2026/10/15 3:45:43 阅读更多 →

最新新闻

MIPS核心指令硬件原理与工程避坑指南

MIPS核心指令硬件原理与工程避坑指南

/* 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 4:46:53 阅读更多 →
iOS应用代码保护与Ipa Guard命令行自动化集成指南

iOS应用代码保护与Ipa Guard命令行自动化集成指南

1. 项目背景与核心价值在iOS应用开发领域,代码保护一直是开发者关注的重点。随着移动应用市场的竞争加剧,防止逆向工程和代码窃取变得尤为重要。传统的代码混淆工具往往需要手动操作,这在持续集成和自动化部署流程中显得效率低下。Ipa Guard命…

2026/10/15 4:46:53 阅读更多 →
Samba容器化实战:多租户隔离、协议兼容与权限映射

Samba容器化实战:多租户隔离、协议兼容与权限映射

1. 为什么在容器里跑Samba,而不是直接装在宿主机上?“Docker里跑Samba?这不反直觉吗?”——这是我第一次被团队同事问到这个问题时的真实反应。当时我们正在重构一个老旧的文件协作系统,原方案是在物理服务器上直接部署…

2026/10/15 4:46:53 阅读更多 →
STM32+华为云IoT+Qt:从传感器到云端的物联网数据链路实战

STM32+华为云IoT+Qt:从传感器到云端的物联网数据链路实战

/* 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 4:46:53 阅读更多 →
沙箱代理工作流实战:隔离、权限与提示注入防御

沙箱代理工作流实战:隔离、权限与提示注入防御

1. 沙箱代理工作流到底在解决什么问题第一次接触“沙箱代理工作流”这个概念,是在一个自动化任务编排的项目里。当时团队想让一个智能代理去帮我们处理一批外部数据:抓取、清洗、分类、再写回内部系统。听起来很顺,但真正跑起来才发现&#x…

2026/10/15 4:46:53 阅读更多 →
模板代码生成工具:从元数据到可用接口的完整实现

模板代码生成工具:从元数据到可用接口的完整实现

1. 为什么需要模板代码生成工具:一大半重复代码其实不该手写做后端开发的朋友应该都有过这种体验:新项目启动,建表、写实体、写Mapper、写Service接口和实现、写Controller,然后前端再把列表页、表单页、弹窗、状态标签挨个撸一遍…

2026/10/15 4:45:53 阅读更多 →

日新闻

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/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/14 7:53:34 阅读更多 →