GLSL 噪声完全指南:《The Book of Shaders》第 11 章解析——从一维 Value Noise 到 Simplex Noise

发布时间:2026/10/15 3:48:07

GLSL 噪声完全指南:《The Book of Shaders》第 11 章解析——从一维 Value Noise 到 Simplex Noise 【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载导读噪声Noise是计算机图形学中把随机变成自然的关键技术路面、岩石、树木、云朵的纹理看似随机却又与电视白噪声那种纯随机截然不同。本文以《The Book of Shaders》第 11 章11/README.md 及其多语言版本如 乌克兰语版为骨架结合仓库内完整可运行的 GLSL 示例源码逐步拆解一维噪声、二维价值噪声Value Noise、梯度噪声Gradient Noise以及 Ken Perlin 的单纯形噪声Simplex Noise的构造原理与 GLSL 实现。读完本文你将能够亲手写出float noise(float x)与vec2版噪声函数并用噪声驱动形状动画、生成木纹/泼溅等生成式纹理以及为既有作品添加自然质感。一、为什么需要噪声从纯随机到真实的丰富在之前的章节里我们一直在与看起来像电视雪花的随机函数打交道。但现实世界的纹理——texture-00.jpg 到 texture-06.jpg 中的路面、树皮、云层——它们的不可预测性虽然可以被称为随机却与之前的纯随机截然不同现实世界是一个极其丰富而复杂的地方我们该如何用计算去逼近这种变化性这正是 Ken Perlin 在 1980 年代初接到为电影《Tron电子世界争霸战》生成更真实纹理的任务时所面对的问题。他由此提出了一个优雅的、后来获得奥斯卡技术成就奖的噪声算法。需要说明的是本章接下来给出的并非经典的 Perlin 噪声实现而是一个理解噪声如何生成的绝佳起点。二、一维噪声把随机值变成连续曲线2.1 核心思路整数部分 × 随机小数部分 × 插值我们首先要把一个连续的浮点数x拆成两部分整数部分i用floor()获取小数部分f用fract()获取。然后对整数部分应用上一章学过的rand()让每一个整数对应一个唯一的随机值float i floor(x); // integer float f fract(x); // fraction y rand(i); // rand() is described in the previous chapter // y mix(rand(i), rand(i 1.0), f); // y mix(rand(i), rand(i 1.0), smoothstep(0., 1., f));直接使用y rand(i)时你会看到阶梯状的随机平台而一旦加入插值曲线就开始变得连续。2.2 线性插值mix 两个随机值取消注释第一行插值代码y mix(rand(i), rand(i 1.0), f);这里用小数部分f作为插值权重通过mix()把相邻两个整数对应的随机值混合起来。结果是从一个突变的阶梯变成折线式的连续波形。2.3 平滑插值smoothstep 与自定义三次曲线折线依然不够自然。取消注释第二行改用smoothstep()插值y mix(rand(i), rand(i 1.0), smoothstep(0., 1., f));注意波峰之间的过渡变得圆滑了——这正是smoothstep()的 Hermite 三次插值的功劳其本质是t * t * (3.0 - 2.0 * t)。在不少噪声实现里程序员会放弃内置smoothstep手写等效的立方曲线float u f * f * (3.0 - 2.0 * f ); // 自定义三次曲线 y mix(rand(i), rand(i 1.0), u); // 用于插值这种平滑的随机是图形工程师与艺术家的游戏规则改变者——它让生成具有有机感的图像与几何体成为可能。仓库中的完整示例见 11/1d-noise.frag其中random(in float x)用fract(sin(x)*1e4)生成哈希随机值noise(in float x)用floor/fract拆分坐标并用三次曲线插值最后main()里以noise(st.x*3.u_time)驱动一条随时间流动的绿色波形曲线。2.4 练习写出你自己的float noise(float x)函数用噪声函数移动、旋转或缩放一个形状使其动起来用噪声让多个形状组成一支共舞的动画用噪声构造有机外形的形状把得到的生物进一步发展成有特定动作的角色。三、二维噪声从线段插值到平面插值3.1 四个角点的 Value Noise一维是在线段的两端rand(x)与rand(x)1.0之间插值二维则要在正方形的四个角之间插值rand(st)、rand(st)vec2(1.,0.)、rand(st)vec2(0.,1.)、rand(st)vec2(1.,1.)。同理三维噪声需要插值立方体的八个角。这种对随机值做插值的技术因此得名Value Noise价值噪声。与一维一样插值不是线性的而是三次的从而平滑地过渡方形网格内的任意点。3.2 源码走读11/2d-noise.frag仓库中的 11/2d-noise.frag 是这一思想的直接实现随机哈希第 10–14 行random(in vec2 st)用fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453123)为每个坐标点生成稳定的伪随机标量拆分网格第 18–20 行vec2 i floor(st)取格子的整数坐标vec2 f fract(st)保留格子内部的分数位置四个角取随机值第 23–26 行random(i)、random(i vec2(1.0, 0.0))、random(i vec2(0.0, 1.0))、random(i vec2(1.0, 1.0))三次平滑第 31 行vec2 u f*f*(3.0-2.0*f)注释中保留了等价写法u smoothstep(0.,1.,f)双线性混合第 35–37 行用mix(a, b, u.x)加上(c-a)*u.y*(1.0-u.x)与(d-b)*u.x*u.y完成四个角点权重的合成缩放观察第 45 行vec2 pos vec2(st*5.0)把坐标空间放大 5 倍以便看清网格单元之间的插值过渡。3.3 练习修改第 45 行的缩放倍数并尝试让它随时间动画化观察放大到什么程度噪声重新看起来像纯随机放大到什么程度噪声又几乎不可见把噪声函数接入鼠标坐标u_mouse把噪声的梯度当作距离场distance field做些有趣的事结合矩形、颜色与噪声创作一幅接近 Mark Rothko马克·罗斯科 油画复杂性的画面。四、生成式设计中的噪声运用4.1 Value Noise 与 Gradient Noise 的区别前面看到的 1D/2D 实现都是对随机标量值的插值因此叫 Value Noise。它的缺点是从实践中能直观感受到的——块状感blocky。为了消除这种块状感1985 年 Ken Perlin 开发了另一种实现Gradient Noise梯度噪声——不再插值随机值而是插值随机的梯度方向二维随机函数返回vec2方向而非float标量。仓库中 Inigo Quilez 的两份对照实现非常值得反复对比价值噪声 11/2d-vnoise.fragrandom2返回标量四个角直接参与mix梯度噪声 11/2d-gnoise.fragrandom2返回vec2方向用dot(random2(i), f - i)把角点梯度与角点到采样点的位移做点积后再插值。对比两份源码可以发现两者共享floor/fract拆分与u f*f*(3.0-2.0*f)平滑差异只在于角点信息是标量还是方向向量——这正是 Value Noise 与 Gradient Noise 的分水岭。4.2 木纹用噪声旋转空间像画家了解颜料特性一样越了解噪声实现就越能用好它。例如用二维噪声的输出去旋转绘制了直线的空间就能得到类似木纹的旋涡效果完整代码见 11/wood.fragpos rotate2d( noise(pos) ) * pos; // 旋转空间 pattern lines(pos,.5); // 绘制直线其中rotate2d构造二维旋转矩阵lines用smoothstep配合sin(pos.x*3.1415)绘制带厚度控制的条纹。4.3 泼溅把噪声当作距离场第二种玩法是把噪声当作距离场套用 07 章形状 的距离场技巧得到泼溅splatter纹理见 11/splatter.fragcolor smoothstep(.15,.2,noise(st*10.)); // 黑色泼溅 color - smoothstep(.35,.4,noise(st*10.)); // 泼溅上的孔洞两个不同阈值区间的smoothstep相减就在噪声场的等值线附近雕刻出了泼墨的边界该示例还内置了st noise(st*2.)*t的坐标空间扰动取消注释即可看到流动动画。4.4 调制形状噪声驱动的圆波第三种用法是用噪声调制形状本身。11/circleWave-noise.frag 在极坐标下绘制圆环m noise(stu_time*0.1)*.5让角度随噪声起伏f sin(a*50.)*noise(stu_time*.2)*.1让半径产生噪声扰动最终得到一圈不断波动、宛如液体涟漪的圆环。4.5 练习你还能生成哪些生成式图案花岗岩、大理石、岩浆、水找三张你感兴趣的纹理图片用噪声算法实现它们用噪声调制一个形状回到 08 章矩阵 中移动 的平移示例给它的运动加入随机与噪声生成一幅生成式的 Jackson Pollock杰克逊·波洛克风格作品。五、改进噪声从三次曲线到五次曲线Perlin 对原始噪声的改进之一即后来 Simplex Noise 的前奏是把三次 Hermite 曲线f(x) 3x^2 - 2x^3与smoothstep()完全等价替换为五次插值曲线f(x) 6x^5 - 15x^4 10x^3// 三次 Hermite 曲线等价于 smoothStep() y x*x*(3.0-2.0*x); // 五次插值曲线 // y x*x*x*(x*(x*6.-15.)10.);五次曲线让两端都更加平坦每条边界都能与下一条更平滑地缝合单元之间的过渡更加连续。取消注释上述代码中的第二行即可在图表中直观对比曲线端点形态的变化。六、单纯形噪声Simplex Noise6.1 动机2^N 个角点太昂贵Perlin 并不满足于原算法的表现。在 Siggraph 2001 上他发表了simplex noise声称相比旧算法获得如下改进更低的计算复杂度、更少的乘法次数向更高维度扩展时计算成本增长更小没有方向性伪影directional artifacts具有定义良好且连续的梯度且计算廉价易于在硬件上实现。为什么能更快二维需要插值正方形的 4 个角三维需要插值立方体的 8 个角四维则需要 16 个角——N 维需要平滑插值2^N个点。但 Perlin 敏锐地注意到虽然正方形是显而易见的填满空间的形状二维空间中最简单的形状其实是等边三角形。于是他把方形网格替换为等边三角形组成的单纯形网格simplex grid。6.2 单纯形网格的构造N 维的单纯形是拥有N 1 个角的多边形。这意味着二维少算 1 个角三维少算 4 个角四维少算 11 个角——巨大的提升二维单纯形噪声的插值方式与普通噪声类似只是只需要插值 3 个角而非 4 个。单纯形网格的构造堪称优雅把四角规则网格的每个单元一分为二成两个等腰三角形再倾斜skew直到每个三角形变成等边三角形正如 Stefan Gustavson 在论文《Simplex noise demystified》中所述通过观察待求值点的变换后坐标 (x, y) 的整数部分可以快速判断它位于两个单纯形中的哪一个单元再比较 x 和 y 的绝对值就能确定点在上三角还是下三角从而遍历正确的三个角点。仓库中的 11/simplex-grid.frag 用代码演示了这一过程skew()第 11–16 行实现倾斜变换r.x 1.1547*st.x系数源于等边三角形几何r.y st.y0.5*r.xsimplexGrid()第 18–31 行判断p.x p.y下三角还是p.y p.x上三角把倾斜后的正方形分成两个等边三角形并返回三个角点的重心坐标在main()中取消注释第 44 行可看到网格倾斜效果取消注释第 47 行可看到单纯形网格的构造——正如文档所说第 22 行仅凭x y就完成了三角剖分。6.3 GLSL 版单纯形噪声实现以上改进的集大成者就是Simplex Noise。仓库提供了一份由 Ian McEwanAshima Arts与 Stefan Gustavson 合著的经典 GLSL 实现 11/2d-snoise-clear.frag其核心snoise(vec2 v)结构清晰预处理常数第 27–34 行C向量包含了(3.0-sqrt(3.0))/6.0、0.5*(sqrt(3.0)-1.0)等单纯形几何常数用于坐标倾斜确定单纯形角点第 37–44 行i floor(v dot(v, C.yy))定位所在单元再依据x0.x x0.y选择上/下三角得到另外两个角点x1、x2排列去截断第 48–51 行mod289与permute用模 289 的排列避免哈希截断伪影径向衰减权重第 53–60 行m max(0.5 - dot(x,x), 0.0)再四次幂构成单纯形顶点的衰减核梯度构造与合成第 67–80 行把排列值映射到菱形上的梯度方向经m缩放后点积求和最后130.0 * dot(m, g)归一化输出。同一章还提供了该实现的实际应用11/lava-lamp.frag 用两层snoise叠加出熔岩灯般的流动效果DF snoise(posvel)*.25.25再以smoothstep(.7,.75,fract(DF))提取液滴轮廓11/iching-03.frag 则在《易经》六边形符号上叠加三维单纯形噪声snoise(vec3(st*75., t*0.1))*0.03制造动态纹理。若想研究更高维度与周期性变体可参考仓库中的 11/3d-noise.frag、11/3d-pnoise.frag 与 11/2d-pnoise.frag含经典 Perlin 噪声cnoise与周期噪声pnoise作者 Stefan Gustavson。6.4 练习像看云找形状一样把每种噪声实现想象成雕塑家面前的大理石原料体会它们的手感差异跟随直觉把想法写进代码写一个制造流动错觉的着色器熔岩灯、墨滴、水流等用单纯形噪声给你之前的作品添加纹理细节。七、仓库配套如何运行与查阅这些示例本章所有.frag文件都遵循 The Book of Shaders 的统一约定声明u_resolution、u_mouse、u_time三个 uniform在main()中用gl_FragCoord.xy/u_resolution.xy归一化坐标。你可以在线打开仓库根目录的 edit.php 内嵌编辑器如edit.php#11/2d-noise.frag也可以结合 04 章介绍的 glslViewer 等工具在本地渲染。术语表本章用到的floor()、fract()、mix()、smoothstep()均可查阅 glossary 下的对应条目含多语言版本章节导航本章内容位于 11 号章节目录前后衔接上一章随机与下一章噪声的高级应用章节总览见 11/SUMMARY.md多语言阅读除 英文原版 外仓库还提供 中文版、乌克兰语版 等十余种语言。结语在本章中我们通过对混沌的有限控制把随机驯化成了噪声从floor/fract拆分坐标、mix与smoothstep平滑插值构造一维噪声到四角点双线性插值构造二维 Value Noise再到旋转空间生成木纹、以距离场思想生成泼溅、用噪声调制形状最后理解了五次曲线改进与单纯形网格如何让噪声更平滑、更快。掌握噪声你就掌握了一门连接计算与自然的语言——接下来请带着这些工具去观察并复刻大自然中那些复杂的图案吧。赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐The Book of Shaders 第 11 章从 TV 白噪声到有机纹理——GLSL 中 Value Noise、Gradient Noise 与 Simplex Noise 全解The Book of Shaders 第 11 章从 TV 白噪声到有机纹理——GLSL 中 Value Noise、Gradient Noise 与 SiThe Book of Shaders 第 11 章深度解析GLSL 噪声算法——Value Noise、Gradient Noise 与 Simplex Noise 从入门到实战The Book of Shaders 第 11 章深度解析GLSL 噪声算法——Value Noise、Gradient Noise 与 Simplex NThe Book of Shaders 第 11 章用 GLSL 从零构建 Value Noise 与 Simplex Noise 程序化纹理The Book of Shaders 第 11 章用 GLSL 从零构建 Value Noise 与 Simplex Noise 程序化纹理 导读 本章是《上一篇Trigger.dev 成本优化实战任务、调度与运行的降本审计指南下一篇Pandoc 引文处理实战--citeproc 结合内联 references 元数据与外部 BibTeX 文献库基于 6951 号命令测试深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/15 3:48:07

名字一排序就乱?文本排序的 5 个坑,一次说清

把一堆名字、编号、文件名贴进 Excel 或者排序工具里,点一下排序,结果出来的顺序和预想的完全不一样——数字排在中间、大写排前面、中文乱成一团。文本排序看着是最简单的操作,其实坑一点不少。今天一次说清。 坑一:字符串排序 …

2026/10/15 4:53:11

Scratch第7讲课件:从搭积木到做项目,接住类游戏教学全解析

简介:一份面向少儿编程课堂的Scratch培训课件,适合教师备课或家长带领低龄孩子入门图形化编程。内容围绕两则趣味案例展开:小猫躲移动挡板、蚂蚁爬线,通过任务导航、任务分析、跟着做、回顾知识点、创造思考等环节,讲解…

2026/10/15 4:53:11

VBA实战15-手把手用 VBA 创建“会自我成长“的数据透视表

透视分析:一键生成动态可刷新数据透视表 免费基金定投助手全功能拆解:为什么你的基金定投还在亏钱?因为你的工具用错了。动态平衡仓位管理8种智能定投策略引擎,会自己算买卖点的定投系统-CSDN博客 https://download.csdn.net/down…

2026/10/15 4:53:11

Azkaban自定义多通道报警插件实战:钉钉/微信/电话集成

1. 项目概述:为什么Azkaban的默认报警机制必须被“动手术”Azkaban作为一款成熟稳定的批处理工作流调度系统,在某高校实验室、某金融科技公司和某电商中台等多个实际生产环境中,我连续三年负责其集群运维与任务治理。它原生支持邮件报警&…

2026/10/15 4:53:11

Azkaban告警增强实战:构建低延迟多渠道统一告警中枢

1. 项目概述:为什么Azkaban的默认告警远远不够用在某公司数据平台团队的实际运维中,我负责维护一套运行着200个核心ETL任务的Azkaban集群。刚接手时,系统只配置了最基础的邮件告警——任务失败后发一封带堆栈的HTML邮件到运维邮箱。结果呢&am…

2026/10/15 4:48:11

水工隧洞安全监测技术规范SL 764-2018核心要点与实施指南

简介:《SL 764-2018》是水利水电行业针对水工隧洞安全监测的专项技术规范,面向设计、施工与运营管理阶段的工程技术人员,为围岩稳定性、衬砌变形、裂缝、渗漏水及洞内环境等关键参数的监测与评价提供统一技术依据。资源包共1个文件&#xff0…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/15 0:02:22

防关联浏览器哪个好?三款产品实测差异解析

新手做多店铺,最纠结的就是防关联浏览器选哪个。飞跨、网易、站斧这三款被问得最多,先给结论:要一体化省心、长期便宜,选站斧;要网易招牌和稳,选网易;预算紧做东南亚 Lazada,选飞跨。…

2026/10/15 0:02:22

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成 一、技术背景 大模型(LLM)在通用场景下表现强大,但当我们将 GPT-4 或 Qwen 直接用于生成影刀RPA操作指令和 XPath 定位时,准确率通常只有 40%-60%。原因…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑