《The Book Of Shader》笔记,有增删。

一、随机(random)

说到随机函数,JavaScript 中有 Math.random(),PHP 中有rand(),在图形绘制时,随机也无处不在。《The Book Of Shader》 通过一个简单的函数衍化,让我们了解随机:

通过fract()sin()的结合,我们得到了一个有一定规律但被打乱的曲线,当我们把1.0变成无限大时,再看看效果:

我们把上面的公式封装成rand()函数:

Shader 中的随机是确定性随机(伪随机),也就是当我们的输入值确定时,输出值也是确定的,而 JavaScript 和 PHP 则是非确定随机,每次随机出来的内容是不一样的。当然我们还可以对随机增加一些变化:

rand()*rand() 会让值更趋近于 0:

更多的随机研究可以看这篇文章,你会发现随机数也是可以「操作」的:

你会发现随机图表中,会有两个地方的随机分布不均匀(-1.5707 ~ 1.5707),这是 sin() 最大值和最小值的地方,所以我们在取值的时候尽量避免这两个地方:

2D 随机

现在我们对随机有了深入的理解,是时候将它应用到二维,x 轴和 y 轴。为此我们需要将一个二维向量转化为一维浮点数。这里有几种不同的方法来实现,但 dot() 函数在这个例子中尤其有用。它根据两个向量的方向返回一个 0.0 到 1.0 之间的值。—— refer

如果你对下面的vec2(12.23,78.32)))*232348.23)留有疑问,姑且将其理解为 magic number,它的效果就跟电视没有信号时的雪花效果一样:

下面对这些随机数做一些操作:

封装函数:

// 伪随机
float random (float n) {return fract(sin(n)*1000000.);
}float random (vec2 st) {return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);
}// 散列函数(哈希值)
float hash(float n) {return fract(sin(n) * 1e4);
}float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x))));
}
复制代码

二、噪声(noise)

噪声跟随机有什么不同?

噪音的基础来自于随机数,随机数的特点是每个点的值都是离散的,相互完全没有关系,而噪音则是让离散的随机数连续起来。最简单的连续化处理就是插值,在离散数据中间用函数插值的方法把空隙填满空间就自然连续了。说到插值,学过数值分析的立刻就能想到七八种插值方法,只要能保持连续性不管是三角函数,正态分布,还是样条曲线都可以使用。—— 不只是噪音

有了噪音我们就可以还原出自然界的真实景象:

如何得到一个离散的随机值,可以通过上面的随机函数:

接着把这些离散的随机值通过mix()线性插值的方式连接起来:

通过smoothstep()函数让变化更圆滑:

在一些 noise 的应用中你会发现程序员喜欢用他们自己的三次多项式函数(比如下面的例子),而不是用smoothstep(),结果是一样的。

通过这种方式得到了一段 「噪音」

当我们把它作为值,显示在画布中,会是什么样子呢?可以看到一维的噪音并没有太大的价值:

可以用直接封装好的noise()函数(文章底部会罗列这些函数的声明):

2D 噪声

2D 噪声在图形角度才更具备价值,其自变量不再是水平或垂直的一个值而是二维的值:

当我们使用已经封装好后的 2D noise() 函数并传入坐标后,看看效果:

函数封装:


// 一维(这里都是基于hash,也可以改成基于random
float noise(float x) {float i = floor(x);float f = fract(x);float u = f * f * (3.0 - 2.0 * f);return mix(hash(i), hash(i + 1.0), u);
}// 二维
float noise(vec2 x) {vec2 i = floor(x);vec2 f = fract(x);// Four corners in 2D of a tilefloat a = hash(i);float b = hash(i + vec2(1.0, 0.0));float c = hash(i + vec2(0.0, 1.0));float d = hash(i + vec2(1.0, 1.0));// Simple 2D lerp using smoothstep envelope between the values.// return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),//           mix(c, d, smoothstep(0.0, 1.0, f.x)),//         smoothstep(0.0, 1.0, f.y)));// Same code, with the clamps in smoothstep and common subexpressions// optimized away.vec2 u = f * f * (3.0 - 2.0 * f);return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}// 三维
float noise(vec3 x) {const vec3 step = vec3(110, 241, 171);vec3 i = floor(x);vec3 f = fract(x);// For performance, compute the base input to a 1D hash from the integer part of the argument and the // incremental change to the 1D based on the 3D -> 1D wrappingfloat n = dot(i, step);vec3 u = f * f * (3.0 - 2.0 * f);return mix(mix(mix( hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x),mix( hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y),mix(mix( hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x),mix( hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z);
}
复制代码

相关链接:

  • zhuanlan.zhihu.com/p/22337544
  • thebookofshaders.com/10/?lan=ch
  • thebookofshaders.com/11/?lan=ch

Shader 中的随机与噪声相关推荐

  1. Shader 中的颜色混合模式(Blend Mode)

    在之前的文章中提及了 Shader 中的颜色计算,介绍了一些基本的颜色混合计算,然而在实际的 Shader 滤镜中,简单到加减乘除并不能很好地还原出我们想要的效果,mix()也只是其中一个选择. 回顾 ...

  2. 深度学习中的随机梯度下降(SGD)简介

    随机梯度下降(Stochastic Gradient Descent, SGD)是梯度下降算法的一个扩展. 机器学习中反复出现的一个问题是好的泛化需要大的训练集,但大的训练集的计算代价也更大.机器学习 ...

  3. 【OpenGL】向Shader中传递数据

    传递顶点属性信息 之前讲过,vertex shader会被每个顶点调用,通常一个顶点会包含很多信息,例如顶点坐标.顶点法向量.纹理坐标等等,我们称这些信息为顶点的属性.在之前的OpenGL版本里,每个 ...

  4. MariaDB/MySQL从数据库中选择随机的行

    MariaDB/MySQL从数据库中选择随机的行 一个比较传统的做法是使用sql自带的rand函数,从而达到随机排序的目的. SELECT column FROM table ORDER BY RAN ...

  5. 在数据框中采样随机行

    本文翻译自:Sample random rows in dataframe I am struggling to find the appropriate function that would re ...

  6. 从JavaScript数组中获取随机项[重复]

    本文翻译自:Get random item from JavaScript array [duplicate] This question already has answers here : 这个问 ...

  7. 深度学习中的随机种子

    ''' 深度学习代码中的随机种子 深度学习网络模型中初始的权值参数通常都是初始化成随机数 而使用梯度下降法最终得到的局部最优解对于初始位置点的选择很敏感 为了能够完全复现作者的开源深度学习代码,随机种 ...

  8. python随机生成字符串_Python 2.6中的随机字符串(可以吗?)

    我一直在试图找到一种更像python的方法来生成python中的随机字符串,这种方法也可以伸缩.通常,我看到类似的东西''.join(random.choice(string.letters) for ...

  9. 随机从mysql中读取_如何实现MySQL表数据随机读取?从mysql表中读取随机数据

    文章转自 http://blog.efbase.org/2006/10/16/244/ 如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysq ...

最新文章

  1. Yolov4性能分析(下)
  2. C#获取邮件客户端保存的邮箱密码
  3. 如何在graphpad表示出正负误差_GraphPad Prism 8.0绘制误差连线并填充颜色图
  4. iframe 自适应高度 [记录]
  5. 别羡慕别人的舒服,静下心来坚持奋斗!!!
  6. mysql 远程load data,PyMySQL将(文件)数据加载到远程MySQL实例时发生错误/异常
  7. tidb数据库_异构数据库复制到TiDB
  8. 天池 在线编程 数组划分III(计数)
  9. 内向的人在面试时如何表现自己?
  10. 修复 github 项目的语言属性
  11. C++ 二叉树深度优先遍历和广度优先遍历
  12. Oracle 10g宝典(第2版)
  13. 面试题1,值传递和参数传递
  14. tableau示例超市数据在哪儿_Tableau | 超市销售数据可视化分析
  15. 无线扫码枪 服务器查询异常,扫描枪常见问题
  16. PDF文档页面如何重新排版?
  17. UV Mapping(UV贴图)
  18. 一些杂谈和对他们的认识程度
  19. 三层交换工作原理及配置过程
  20. SIMBOSS:物联网业务如何应用领域驱动设计?

热门文章

  1. File 类型的文本框,选择文件时响应很慢解决方法
  2. ATT、IBM等公司结成新的物联网网络安全联盟
  3. Embedded Linux Primer----嵌入式Linux基础教程--导论
  4. [值得学习]售前工程师的成长---一个老员工的经验之谈(一)
  5. 【WPF】MeshGeometry3D中的Normals和TextureCoordinates属性
  6. 揭秘:倒卖火车票的惊人黑幕全过程!
  7. 一个“蝇量级” C 语言协程库
  8. 《数字质量手册》新书问答
  9. CISCO NAT 经典配置合集
  10. 不借助第三方 Windows 7搞定无法删除文件