日积月累Shader - 10 生成设计

提示

教程例子都可以到下面网址进行运行,不需要另外安装软件环境:
官方提供在线编写shader工具:https://thebookofshaders.com/edit.php
glslsandbox网站:http://glslsandbox.com/
shadertoy网站:https://www.shadertoy.com/

随机

y = fract(sin(x)*1.0);
日积月累Shader - 10 生成设计_第1张图片
y = fract(sin(x*10000.)*10000.0);
日积月累Shader - 10 生成设计_第2张图片

我们提取sin函数其波形的分数部分。sin() 函数值在 -1.01.0 之间浮点分布,返回作业在 0.01.0 间的正值。(这里翻译有些奇怪)我们可以用这种效果通过把 sin(x) 打散成小片段来得到一些伪随机数。如何实现?乘以大些的sin值。在上面函数的相应位置加些0.
当你加到 100000.0 (方程看起来是这样的:y = fract(sin(x)*100000.0) ),你再也区分不出sin波了。小数部分的粒度将sine的循环变成了伪随机的混沌。

控制混沌

》使用随机会很难;它不是太混沌难测就是有时又不够混乱。看看下面的图例。要实现这样的效果,我们像之前描述的那样应用用 rand() 函数。
细看,你可以看到 sin()-1.57071.5707 到拐点。???我打赌一定理解为什么——那就是sin最大值和最小值的地方。
如果你仔细观察随机分布,你会注意到相比边缘,中部更集中。
···
y = rand(x);
···

日积月累Shader - 10 生成设计_第3张图片

试试下面这几个
···
y = rand(x)*rand(x);
y = sqrt(rand(x));
y = pow(rand(x),5.);
···

如果你读下 Pixelero 的文章,一定谨记我们用的 rand() 是确定性随机,也被称作是伪随机。这就意味着, 就 rand(1.) 为例,总会返回相同的值。Pixelero 用 ActionSript 函数做了些参考,Math.random(),一个非确定性随机;每次调用都返回不同的值。

2D 随机

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

···

ifdef GL_ES

precision mediump float;

endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random (vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;

float rnd = random( st );

gl_FragColor = vec4(vec3(rnd),1.0);

}
···


日积月累Shader - 10 生成设计_第4张图片
  • vec2(12.9898,78.233)换成vec2(u_mouse.x,u_mouse.y), 你会看到一台雪花电视

使用混沌

我们的第一步是在网格上的应用;用 floor() 函数,我们将会产生一个单元整数列表。看下下面的代码,尤其是22行和23行。

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random (vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(12.9898,78.233)))*
        43758.5453123);
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    st *= 10.0; // Scale the coordinate system by 10
    vec2 ipos = floor(st);  // get the integer coords
    vec2 fpos = fract(st);  // get the fractional coords

    // Assign a random value based on the integer coord
    vec3 color = vec3(random( ipos ));

    // Uncomment to see the subdivided grid
    // color = vec3(fpos,0.0);

    gl_FragColor = vec4(color,1.0);
}
日积月累Shader - 10 生成设计_第5张图片
  • 这个例子告诉你,random输入到值是固定的,输出值也是固定的
  • 把小数部分补上去看看色彩 color += vec3(fpos.5,fpos.5);
    日积月累Shader - 10 生成设计_第6张图片

看下这个著名的 10 PRINT CHR$(205.5+RND(1)); : GOTO 10迷宫生成器的GLSL代码块

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265358979323846

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random (in vec2 _st) {
    return fract(sin(dot(_st.xy,
                         vec2(12.9898,78.233)))*
        43758.5453123);
}

vec2 truchetPattern(in vec2 _st, in float _index){
    _index = fract(((_index-0.5)*2.0));
    if (_index > 0.75) {
        _st = vec2(1.0) - _st;
    } else if (_index > 0.5) {
        _st = vec2(1.0-_st.x,_st.y);
    } else if (_index > 0.25) {
        _st = 1.0-vec2(1.0-_st.x,_st.y);
    }
    return _st;
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st *= 10.0;
    // st = (st-vec2(5.0))*(abs(sin(u_time*0.2))*5.);
    // st.x += u_time*3.0;

    vec2 ipos = floor(st);  // integer
    vec2 fpos = fract(st);  // fraction

    vec2 tile = truchetPattern(fpos, random( ipos ));

    float color = 0.0;

    // Maze
    color = smoothstep(tile.x-0.3,tile.x,tile.y)-
            smoothstep(tile.x,tile.x+0.3,tile.y);

    // Circles
    // color = (step(length(tile),0.6) -
    //          step(length(tile),0.4) ) +
    //         (step(length(tile-vec2(1.)),0.6) -
    //          step(length(tile-vec2(1.)),0.4) );

    // Truchet (2 triangles)
    // color = step(tile.x,tile.y);

    gl_FragColor = vec4(vec3(color),1.0);
}
日积月累Shader - 10 生成设计_第7张图片

日积月累Shader - 10 生成设计_第8张图片

掌握随机

Ikeda 的作品并试试看下面的练习:

  • 做按行随机移动的单元(以相反方向)。只显示亮一些的单元。让各行的速度随时间变化。
    日积月累Shader - 10 生成设计_第9张图片

    https://thebookofshaders.com/edit.php#10/ikeda-00.frag
  • 同样地,让某几行以不同的速度和方向。用鼠标位置关联显示单元的阀值
    日积月累Shader - 10 生成设计_第10张图片

    https://thebookofshaders.com/edit.php#10/ikeda-03.frag
  • 创造其他有趣的效
    日积月累Shader - 10 生成设计_第11张图片

    https://thebookofshaders.com/edit.php#10/ikeda-04.frag

你可能感兴趣的:(日积月累Shader - 10 生成设计)