美文网首页shader
日积月累Shader - 10 生成设计

日积月累Shader - 10 生成设计

作者: Zszen | 来源:发表于2019-06-11 14:45 被阅读0次

    提示

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

    随机

    y = fract(sin(x)*1.0);
    
    y = fract(sin(x*10000.)*10000.0);
    

    我们提取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);
    ···

    试试下面这几个
    ···
    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);
    

    }
    ···


    • 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);
    }
    
    • 这个例子告诉你,random输入到值是固定的,输出值也是固定的
    • 把小数部分补上去看看色彩 color += vec3(fpos.5,fpos.5);

    看下这个著名的 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);
    }
    

    掌握随机

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

    相关文章

      网友评论

        本文标题:日积月累Shader - 10 生成设计

        本文链接:https://www.haomeiwen.com/subject/cvtqfctx.html