たまにglsl

たまにshadertoyで作ったglslをを貼っていきます

回転

2020/03/29

  • ただ中央で回転させるだけなのにこんなに大変だと思わなかった
  • コツは一度ずらして回転させて元に戻す

#iChannel0 "file:///Users/xxxxx/nextcloud-sync/mentaiko.jpeg"

mat2 rot(float r){
    float c=cos(r);
    float s=sin(r);
    return mat2(c,-s,s,c);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    uv.x -= 0.5;
    uv.y -= 0.5;

    vec2 uv_rotated = uv * rot(radians(iTime * 70.));

    uv_rotated.x += 0.5;
    uv_rotated.y += 0.5;

    vec4 image1 = texture(iChannel0, uv_rotated);

    fragColor = vec4(image1);

    // デバッグ用
    if (abs(uv_rotated.x - uv_rotated.y) < .002) {
        fragColor = vec4(1.);    
    }
}

パーリンノイズ

2020/03/29

  • パーリンノイズのフェード関数は 6t^5 – 15t^4 + 10t^3
    • vec2での関数pow()は、第二引数もvec2が必要
  • とてもなめらか
    • どうぶつの森のピクセルアートの滑らかさに少し近づいた感じ

#iChannel0 "file:///Users/xxxxx/nextcloud-sync/mentaiko.jpeg"

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


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    float time = iTime*3.5;
    float oi = rand(vec2(time));

    float mosaic_size = 50.;

    vec2 f = fract(uv * mosaic_size);

    vec2 uv50 = uv * mosaic_size;

    vec4 a = texture(iChannel0, floor(uv50)/mosaic_size);
    vec4 b = texture(iChannel0, vec2(1./mosaic_size, 0.) + floor(uv50)/mosaic_size);
    vec4 c = texture(iChannel0, vec2(0., 1./mosaic_size) + floor(uv50)/mosaic_size);
    vec4 d = texture(iChannel0, vec2(1./mosaic_size) + floor(uv50)/mosaic_size);

    vec4 raw = texture(iChannel0, floor(uv * mosaic_size)/mosaic_size);

    // バリューノイズ
    vec4 image = a*(1.-f.x)*(1.-f.y) + b*(f.x)*(1.-f.y) + c*(1.-f.x)*(f.y) + d*(f.x)*(f.y);

    // パーリンノイズ
    vec2 f_perlin = 6.*pow(f, vec2(5.)) - 15.*pow(f, vec2(4.)) + 10.*pow(f, vec2(3.));
    image = a*(1.-f_perlin.x)*(1.-f_perlin.y) + b*(f_perlin.x)*(1.-f_perlin.y) + c*(1.-f_perlin.x)*(f_perlin.y) + d*(f_perlin.x)*(f_perlin.y);

    fragColor = vec4(vec3(image.xyz), 1.0);
    // fragColor = vec4(vec3(raw.xyz), 1.0);
}

バリューノイズ

2020/03/29

  • ノイズをきちんと理解するためThe Book of Shadersを見始めた
    • 4点間の補完の式が理解できなかった
    // Mix 4 coorners percentages
    return mix(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
  • 自分なりに以下のように書き直すと、上記の式と全く同値ということがわかりすっきり理解できた
return a*(1.-u.x)*(1.-u.y) + b*(u.x)*(1.-u.y) + c*(1.-u.x)*(u.y) + d*(u.x)*(u.y);

#iChannel0 "file:///Users/xxxxx/nextcloud-sync/mentaiko.jpeg"

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


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    float time = iTime*3.5;
    float oi = rand(vec2(time));

    float mosaic_size = 50.;

    vec2 f = fract(uv * mosaic_size);

    vec2 uv50 = uv * mosaic_size;

    vec4 a = texture(iChannel0, floor(uv50)/mosaic_size);
    vec4 b = texture(iChannel0, vec2(1./mosaic_size, 0.) + floor(uv50)/mosaic_size);
    vec4 c = texture(iChannel0, vec2(0., 1./mosaic_size) + floor(uv50)/mosaic_size);
    vec4 d = texture(iChannel0, vec2(1./mosaic_size) + floor(uv50)/mosaic_size);

    vec4 raw = texture(iChannel0, floor(uv * mosaic_size)/mosaic_size);

    vec4 image = a*(1.-f.x)*(1.-f.y) + b*(f.x)*(1.-f.y) + c*(1.-f.x)*(f.y) + d*(f.x)*(f.y);

    fragColor = vec4(vec3(image.xyz), 1.0);
    // fragColor = vec4(vec3(raw.xyz), 1.0);
}

グリッチその3

2020/03/28

  • 座標がずれる色が固定だったので時間依存にした
  • ずれるブロックの幅と高さが固定だったので、幅をy座標依存になるようにした

#iChannel0 "file:///Users/xxxxx/nextcloud-sync/mentaiko.jpeg"

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

float fractal_noise(vec2 fragCoord, float time) {
    vec2 uv = fragCoord/iResolution.xy;

    float y_noise = rand(vec2(uv.y));

    float split_size_y = 100.0;
    float y = floor(uv.y * split_size_y);


    float split_size_x = 20.0 * y/100.;
    float x = floor(uv.x * split_size_x);
    return rand(vec2(x, y) + vec2(cos(time)));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    float time = floor(iTime*8.);
    float oi = rand(vec2(time));
    
    vec3 image_merged = texture(iChannel0, uv).xyz;

    // ランダム割合
    float probability = 0.6;

    if (oi > probability) {
        float noise1 = fractal_noise(fragCoord, time);
        float noise2 = fractal_noise(fragCoord, time+4.);
        float noise3 = fractal_noise(fragCoord, time+8.);

        vec4 image1 = texture(iChannel0, uv+vec2(-.2+(.4*noise1), 0));
        vec4 image2 = texture(iChannel0, uv+vec2(-.2+(.4*noise2), 0));
        vec4 image3 = texture(iChannel0, uv+vec2(-.2+(.4*noise3), 0));

        // RGBどれかは座標移動させたくないので一つ選んで座標リセット
        float io2 = (oi-probability)/(1.-probability);
        if (io2 > .666) {
            image1 = texture(iChannel0, uv);
        } else if (io2 > .333) {
            image2 = texture(iChannel0, uv);
        } else {
            image3 = texture(iChannel0, uv);
        }

        image_merged = vec3(image1.x, image2.y, image3.z) - vec3(.1);
    }
    fragColor = vec4(image_merged, 1.0);
}

グリッチその2

2020/03/28

  • xyのランダムと組み合わせたら劇的にお洒落になった
    • 画面を20*100のブロックに分割し、
    • 各ブロックに0~1を生成
    • 0~1をランダム発生時のx座標のズレに使った
  • xyのランダムもとても良いが、ノイズが欲しくなった

#iChannel0 "file:///Users/xxxxxxxx/nextcloud-sync/mentaiko.jpeg"

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

float fractal_noise(vec2 fragCoord, float time) {
    vec2 uv = fragCoord/iResolution.xy;

    float split_size_x = 20.0;
    float split_size_y = 100.0;

    float x = floor(uv.x * split_size_x);
    float y = floor(uv.y * split_size_y);
    return rand(vec2(x, y) + vec2(cos(time)));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    float time = floor(iTime*8.);
    float oi = rand(vec2(time));
    
    vec4 image1 = texture(iChannel0, uv);
    vec4 image2 = texture(iChannel0, uv);
    vec4 image3 = texture(iChannel0, uv);


    if (oi > .8) {
        float noise = fractal_noise(fragCoord, time);

        image1 = texture(iChannel0, uv+vec2(0.1 * noise, .0)) - vec4(.1);
        image2 = texture(iChannel0, uv) - vec4(.1);
        image3 = texture(iChannel0, uv-vec2(0.1 * noise, .0)) - vec4(.1);
    }
    fragColor = vec4(image1.x, image2.y, image3.z, 1.0);
}

フラクタルランダム

2020/03/28

  • グリッチ本格的に作ってみようと思ったけどまずはフラクタルランダムが必要そうだった
  • すぐ作れた

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

vec4 fractal_noise(vec2 fragCoord) {
    vec2 uv = fragCoord/iResolution.xy;

    float time = floor(iTime*8.);

    float split_size = 100.0;

    float x = floor(uv.x * split_size);
    float y = floor(uv.y * split_size);
    float io = rand(vec2(x, y));

    return vec4(vec3(io), 1.0);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = fractal_noise(fragCoord);
}

グリッチ

2020/03/28

  • switchのOld School Musicalをやってたらグリッチぽい演出があってお洒落だったので再現しようと頑張った
  • なんかコレジャナイ感
  • asb(mod(x, 2.)-1.)fract でかけることに今頃気づいた

#iChannel0 "file:///Users/xxxxxxxx/nextcloud-sync/mentaiko.jpeg"

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

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    float time = floor(iTime*8.);
    float oi = rand(vec2(time));
    
    vec4 image1 = texture(iChannel0, uv);
    vec4 image2 = texture(iChannel0, uv);
    vec4 image3 = texture(iChannel0, uv);
    if (oi > .85) {
        image1 = texture(iChannel0, uv+vec2(0.05, .0)) - vec4(.1);
        image2 = texture(iChannel0, uv) - vec4(.1);
        image3 = texture(iChannel0, uv-vec2(0.05, .0)) - vec4(.1);
    }

    // fragColor = vec4(image1.x, image2.y, image3.z, 1.0);
    fragColor = vec4(image1.x, image2.y, image3.z, 1.0);

}

三角形

2020/03/03

  • 60度の直線がかけなくてオロオロした
  • 0~1のギザギザの波形を作るときは asb(mod(x, 2.)-1.)だったのを思い出した
#define PI 3.141592653589793

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

void mainImage( out vec4 fragColor, in vec2 fragCoord ){
    
    vec2 uv = (fragCoord.xy/iResolution.xy);

    float rad1 = cos(PI/3.);
    float rad2 = sin(PI/3.);

    float io1 = step(.5, mod(uv.y*10., 1.0));

    float line2 = mod(uv.y * 10. *rad1 + uv.x *10. * rad2, 1.);
    float io2 = step(.5, line2);

    float line3 = mod(uv.y * 10. *rad1 - uv.x *10. * rad2 , 1.);
    float io3 = step(.5, line3);

    float io = (io1 + io2 + io3)/3.;

    fragColor = vec4(vec3(io), 1.);
}

ボロノイ

2019/04/??

  • このころShaderShowDownっていうより魅力的なglslを時間内に書く大会をよくみてた
    • ある年の決勝かなんかで女性がボロノイ作っててそれに夢中になって自分で作ってみたもの

// - glslfan.com --------------------------------------------------------------
// Ctrl + s or Command + s: compile shader
// Ctrl + m or Command + m: toggle visibility for codepane
// ----------------------------------------------------------------------------
precision mediump float;
uniform vec2  resolution;     // resolution (width, height)
uniform vec2  mouse;          // mouse      (0.0 ~ 1.0)
uniform float time;           // time       (1second == 1.0)
uniform sampler2D backbuffer; // previous scene

const float PI = 3.1415926;

vec2 norm() {
    return (2.0*vec2(gl_FragCoord.x,gl_FragCoord.y)-resolution)/max(resolution.x,resolution.y) ;
}

// vec2 random2( vec2 p ) {
//     return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
// }

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

float gizagiza(float offset) {
    return abs(mod(time+offset,2.0)-1.0);
}


vec2 points[200];

void main(){
    vec2 p = norm();
    vec3 color = vec3(0.0,1.0,1.0);
    float nearerDist = 9999.0;
    
    int hoge = int(floor(time*1.0));
    
    vec3 timeRand = vec3(gizagiza(0.0), gizagiza(.8), gizagiza(.3));
    
    for (int i = 0; i < 200; ++i)
    {
        vec2 basePoint = vec2(random(vec2(i+1,i)),random(vec2(i+2,i)));
        points[i] = 0.508 + 0.5*sin(time*.1 + 6.2831*basePoint);
    
        if (nearerDist > length((2.0*points[i]-1.0)-p)) {
            nearerDist = length((2.0*points[i]-1.0)-p);
            color = vec3(
                random(vec2(i,i))
                ,random(vec2(i,i+1))
                ,random(vec2(i,i+2))) + timeRand;
        }
        
        // // Animate the point
        // point = 0.508 + 0.5*sin(u_time + 6.2831*point);
    }
    
    gl_FragColor = vec4(color,1);
}
tech  glsl 

See also