Shader 中的随机与噪声

栏目: PHP · 发布时间: 6年前

内容简介:说到随机函数,JavaScript 中有通过我们把上面的公式封装成

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声
Shader 中的随机与噪声

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

Shader 中的随机与噪声

2D 随机

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

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

封装函数:

// 伪随机
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)

噪声跟随机有什么不同?

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

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

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

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

2D 噪声

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

Shader 中的随机与噪声

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

Shader 中的随机与噪声

函数封装:

// 一维(这里都是基于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 tile
	float 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 wrapping
    float 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);
}
复制代码

以上所述就是小编给大家介绍的《Shader 中的随机与噪声》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Structures and Algorithm Analysis in Java

Data Structures and Algorithm Analysis in Java

Mark A. Weiss / Pearson / 2006-3-3 / USD 143.00

As the speed and power of computers increases, so does the need for effective programming and algorithm analysis. By approaching these skills in tandem, Mark Allen Weiss teaches readers to develop wel......一起来看看 《Data Structures and Algorithm Analysis in Java》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具