glslスクールでせっかくグリッチを教わったのでその話です。
スクールで教わったグリッチはモザイク化(ブロックで分割して解像度を下げる)してからランダム値を返す関数を使ってテクスチャをずらしてグリッチをかけるというものでした。
まず横方向のみだったサンプルを拡張して縦横両方向にずれるようにします。
out vec4 fragColor; uniform vec2 resolution; uniform float time; uniform float threshold; uniform vec2 blockSize; float rnd(vec2 n){ float a = 0.129898; float b = 0.78233; float c = 437.585453; float dt= dot(n ,vec2(a, b)); float sn= mod(dt, 3.14); return fract(sin(sn) * c); } void main() { float blockV = blockSize[0]; float blockH = blockSize[1]; float Vert = floor((vUV.t) / blockV) * blockV; float Horz = floor((vUV.s) / blockH) * blockH; // 0.0 ~ 1.0のランダムな結果を返す float gNoiseV = rnd(vec2(Vert, time*.1)); float gNoiseH = rnd(vec2(Horz, time*.2)); // thresholdを基準に0 or 1を返す float gStepV = step(gNoiseV, threshold * 2.); float gStepH = step(gNoiseH, threshold); // ズレの強度を決める float gStrengthV = gNoiseV / threshold; float gStrengthH = gNoiseH / threshold; // -1.0 ~ 1.0の間に補正する gStrengthV = gStrengthV * 2.0 - 1.0; gStrengthH = gStrengthH * 2.0 - 1.0; float V = gStepV * gStrengthV; float H = gStepH * gStrengthH; vec2 coord = vUV.st + vec2(V + H, 0.0); vec4 color = texture(sTD2DInputs[0], coord); fragColor = TDOutputSwizzle(vec4(color.rgb, 1.0)); }
ex1)
threshold -> 0.1
blockSize -> [0.6, 1.0]
ex2)
threshold -> 0.3
blockSize -> [0.4, 0.02]
パラメータでだいぶ結果が変わります。いい感じです。
ただもう少し元絵に動きを加えて不安な感じ?にしたいなぁと思いました。
参考文献を見て三角関数でテクスチャにオフセットを足すといい感じになりました。
out vec4 fragColor; uniform vec2 resolution; uniform float time; uniform float threshold; uniform vec2 blockSize; uniform vec2 length; uniform vec2 width; uniform vec2 speed; float rnd(vec2 n){ (...省略...) } // Offsetといっても結局ただの時間依存のsin波を返すだけ float calcOffset(float pos, float length, float width, float speed) { return sin(pos * length + mod(time, 3.0) * speed) * width; } void main() { float blockV = blockSize[0]; float blockH = blockSize[1]; (...省略...) float V = gStepV * gStrengthV; float H = gStepH * gStrengthH; float offsetX = calcOffset(vUV.s, length[0],width[0],speed[0]); float offsetY = calcOffset(vUV.t, length[1],width[1],speed[1]); vec2 uv = vec2(vUV.s + offsetX, vUV.t + offsetY); vec2 coord = uv + vec2(V + H, 0.0); vec4 color = texture(sTD2DInputs[0], coord); fragColor = TDOutputSwizzle(vec4(color.rgb, 1.0)); }
ex3)
threshold -> 0.05
blockSize -> [0.5, 0.05]
length -> [12, 8]
width -> [0.003, 0.005]
speed -> [32,18]
参考
https://nogson2.hatenablog.com/entry/2018/01/19/002342nogson2.hatenablog.com