2025.11.08

Github:

https://github.com/sakkom/portfolio-kuhu/tree/main/app/kuhu/glitch

セグメント分割によるランダムピクセル化グリッチ


    float trigger = rand1(floor(uTime * 5.0));
    if(trigger > 0.7) {
      vec4 tex1 = texture2D(tDiffuse, blockUV);
      vec4 tex2 = texture2D(tDiffuse, lineUV);
      gl_FragColor = mix(tex1, tex2, 0.5);
    }
    else {
      gl_FragColor = texture2D(tDiffuse, uv);
    }
  

グリッチの大きな概念に戸惑いながらもグリッチ風なエフェクトを作成しました。 ピクセル化の工夫で実装しました。xyの二次元ランダムによって決定されるものとyの一次元ランダムから派生するものの2つのレイヤーを重ねました。 グリッチ風なデモは時間の一次元で60fpsにおいて瞬間的にフレームが発生するようにしました。


    vec2 seg = floor(uv * uBlockSegment) / uBlockSegment;
    float randomPixel = rand2(seg + sin(timeVal)) * uBlockSize - uBlockSize * 0.5;
    vec2 blockUV = floor(uv * uResolution / randomPixel) * randomPixel / uResolution;
  

最終的なフラグメント座標が確定される前にランダムな大きさでピクセル化が行われるようにします。 分割された範囲で一意な大きさでピクセル化がされます。なので分割数でバリエーションが決定されます。 たとえば分割数が2でもピクセル化のrand値が返す(2つ)にしたがって細かいのか大きいのかの粒度が決定されます。


  float segY = floor(uv.y * uLineSegment) / uLineSegment;
  float randomHeight = max(rand1(segY + sin(timeVal)) * uLineHeight, 1.0);
  float row = floor(uv.y * uResolution.y / randomHeight) * randomHeight / uResolution.y;
  float randomWidth = rand1(row) * uLineWidth - uLineWidth * 0.5;
  float col = floor(uv.x * uResolution.x / randomWidth) * randomWidth / uResolution.x;
  vec2 lineUV = vec2(col, row);
  

yについて分割された範囲でピクセル化しそのフラグメント座標に従って幅が確定します。 - uLineWidth * 0.5についてですがxのオフセット的な意図でパラメータ調整していたのですが その後の処理では必ず正の値になるので論理的に理解できておりません。