Post processing exercise 1 on ShaderToy - faults

Fault Art

It's mainly for reference, or it's written according to the post-processing tutorial of the famous big man Qianmo, but he is implemented in Unity. As a high-quality post-processing plug-in, I implement it on ShaderToy. Of course, I'm reproducing the big man's code. I recommend you to read the big man's article. Address: https://github.com/QianMo/GPU-Gems-Book-Source-Code
Strong Amway!!!!

RGB Split Glitch

Common

#define IDENSITY (0.091)
#define PATTERRN (2)
#define AMPLITUDE (3.0)

float randomNoise(float x, float y)
{
	return fract(sin(dot(vec2(x, y), vec2(12.9898, 78.233))) * 43758.5453);
}

Image

float getSplitAmount()
{
    #if PATTERRN > 1
        float splitA = (1. + sin(iTime * 6.)) * 0.5;
        splitA *= 1.0 + sin(iTime * 16.) * 0.5;
        splitA *= 1.0 + sin(iTime * 19.) * 0.5;
        splitA *= 1.0 + sin(iTime * 27.) * 0.5;
        splitA = pow(splitA, AMPLITUDE);
        splitA *= (0.05 * IDENSITY);
        return splitA;
    #else
        return IDENSITY * randomNoise(iTime, 2.);
    #endif
    
}

vec3 Frag_Horizontal(vec2 uv)
{
    float splitamout = getSplitAmount();
    vec3 col;
    
    col.r = texture(iChannel0, uv + vec2(splitamout, 0.0)).r + splitamout;
    col.g = texture(iChannel0, uv + vec2(0.0, 0.0)).g;
    col.b = texture(iChannel0, uv - vec2(splitamout, 0.0)).b + splitamout;
    
    return col;
}

vec3 Frag_Vertical(vec2 uv)
{
    float splitamout = getSplitAmount();
    vec3 col;
    
    col.r = texture(iChannel0, uv + vec2(0.0, splitamout)).r;
    col.g = texture(iChannel0, uv + vec2(0.0, 0.0)).g;
    col.b = texture(iChannel0, uv - vec2(0.0, splitamout)).b;
    
    return col;
}

vec3 Frag_Horizontal_Vertical(vec2 uv)
{
    float splitamout = getSplitAmount();
    vec3 col;
    
    col.r = texture(iChannel0, uv + vec2(splitamout, splitamout)).r;
    col.g = texture(iChannel0, uv + vec2(0.0, 0.0)).g;
    col.b = texture(iChannel0, uv - vec2(splitamout, splitamout)).b;
    
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = Frag_Horizontal(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Image Block Glitch

Image Block Glitch of basic version

Common

#define BLOCK_SIZE (10.0)
#define SPEED (10.1)

Image

float randomNoise(vec2 seed)
{
    return fract(sin(dot(seed * floor(iTime * SPEED), vec2(17.13, 3.71))) * 43758.5453123);
}


float hash11(float p)
{
    p = fract(p * .1031);
    p *= p + 33.33;
    p *= p + p;
    return fract(p);
}

vec3 ImageBlockGlitch_BASE(vec2 uv)
{
    vec2 block = vec2(randomNoise(floor(uv * vec2(BLOCK_SIZE))));
    float dis = pow(block.x, 8.) * pow(block.x, 3.);
    vec3 col;
    
    col.r = texture(iChannel0, uv).r;
    col.g = texture(iChannel0, uv + vec2(dis * 0.05 * hash11(block.y + iTime), 0.0)).g;
    col.b = texture(iChannel0, uv - vec2(dis * 0.05 * hash11(block.y + iTime), 0.0)).b;
    
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = ImageBlockGlitch_BASE(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Image Block Glitch combined with RGB Split

Common

#define BLOCK_SIZE (10.0)
#define SPEED (12.1)

#define _MaxRGBSplitX (2.)
#define _MaxRGBSplitY (2.)

Image

float randomNoise(vec2 seed)
{
    return fract(sin(dot(seed * floor(iTime * SPEED), vec2(17.13, 3.71))) * 43758.5453123);
}


float randomNoise(float seed)
{
	return randomNoise(vec2(seed, 1.0));
}

vec3 ImageBlockGlitch_RGB(vec2 uv)
{
    vec2 block = vec2(randomNoise(floor(uv * vec2(BLOCK_SIZE))));
    float displaceNoise = pow(block.x, 8.0) * pow(block.x, 3.0);
	float splitRGBNoise = pow(randomNoise(7.2341), 15.0);
	float offsetX = displaceNoise - splitRGBNoise * _MaxRGBSplitX;
	float offsetY = displaceNoise - splitRGBNoise * _MaxRGBSplitY;

	float noiseX = 0.05 * randomNoise(13.0);
	float noiseY = 0.05 * randomNoise(7.0);
	vec2 offset = vec2(offsetX * noiseX, offsetY * noiseY);
    vec3 col;
    
    col.r = texture(iChannel0, uv).r;
    col.g = texture(iChannel0, uv + offset).g;
    col.b = texture(iChannel0, uv - offset).b;
    
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = ImageBlockGlitch_RGB(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Image Block Glitch of advanced version

Common

#define SPEED (10.1)
#define _Fade (1.)
#define _Offset (10.)


#define _BlockLayer1_U (5.)
#define _BlockLayer1_V (9.5)

#define _BlockLayer2_U (15.)
#define _BlockLayer2_V (15.)

#define _BlockLayer1_Indensity (6.)
#define _BlockLayer2_Indensity (4.)

#define _RGBSplit_Indensity (4.)

Image

float randomNoise(vec2 seed)
{
    return fract(sin(dot(seed * floor(iTime * SPEED), vec2(127.13, 311.71))) * 43758.5453123);
}


float randomNoise(float seed)
{
	return randomNoise(vec2(seed, 1.0));
}

vec4 ImageBlockGlitch_HIGH(vec2 uv)
{
    vec2 blockLayer1 = floor(uv * vec2(_BlockLayer1_U, _BlockLayer1_V));
    vec2 blockLayer2 = floor(uv * vec2(_BlockLayer2_U, _BlockLayer2_V));
    //return vec4(blockLayer1, blockLayer2);
    
    float lineNoise1 = pow(randomNoise(blockLayer1), _BlockLayer1_Indensity);
    float lineNoise2 = pow(randomNoise(blockLayer2), _BlockLayer2_Indensity);
    float RGBSplitNoise = pow(randomNoise(5.1379), 7.1) * _RGBSplit_Indensity;
    float lineNoise = lineNoise1 * lineNoise2 * _Offset - RGBSplitNoise;
    //return vec4(lineNoise);
    
    vec4 colR = texture(iChannel0, uv);
    vec4 colG = texture(iChannel0, uv + vec2(lineNoise * 0.05 * randomNoise(7.), 0.));
    vec4 colB = texture(iChannel0, uv - vec2(lineNoise * 0.05 * randomNoise(23.), 0.));
    
    vec4 re = vec4(vec3(colR.x, colG.y, colB.z), colR.a + colG.a + colB.a);
    re = mix(colR, re, _Fade);
    return re;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec4 col = ImageBlockGlitch_HIGH(uv);

    // Output to screen
    fragColor = col;
}

result

Line Block Glitch

Common

#define _LinesWidth (0.8) / / smaller, wider
#define _Amount (0.3) / / control the number of lines, and 1 will not be available
#define _Offset (0.9) / / control the strength of the line
#define _Alpha (0.9) / / blend scale

float randomNoise(vec2 seed)
{
    return fract(sin(dot(seed, vec2(1.9898, 7.233))) * 43758.5453123);
}

float trunc(float x, float num_levels)
{
    return floor(x * num_levels) / num_levels;
}

vec2 trunc(vec2 x, vec2 num_levels)
{
    return floor(x * num_levels) / num_levels;
}

vec3 rgb2yuv(vec3 rgb)
{
    vec3 yuv;
    yuv.x = dot(rgb, vec3(0.299, 0.587, 0.114));
    yuv.y = dot(rgb, vec3(-0.14713, -0.28886, 0.436));
    yuv.z = dot(rgb, vec3(0.615, -0.51499, -0.10001));
    return yuv;
}
	
vec3 yuv2rgb(vec3 yuv)
{
    vec3 rgb;
    rgb.r = yuv.x + yuv.z * 1.13983;
    rgb.g = yuv.x + dot(vec2(-0.39465, -0.58060), yuv.yz);
    rgb.b = yuv.x + yuv.y * 2.03211;
    return rgb;
}

Image

vec3 LineBlockGlitch(vec2 uv)
{
    float truncTime = trunc(iTime, 4.0);
    float uv_trunc = randomNoise(trunc(uv.yy, vec2(8., 8.)) + vec2(100.0 * truncTime));
    //return vec3(uv_trunc); ------------------------------1
    
    float uv_randomTrunc = 6. * trunc(iTime, 24. * uv_trunc);
    //return vec3(uv_randomTrunc); ------------------------2
    
    float blockLine_random = 0.5 * randomNoise(trunc(uv.yy + uv_randomTrunc, vec2(8. * _LinesWidth, 8. * _LinesWidth)));
    blockLine_random += 0.5 * randomNoise(trunc(uv.yy + uv_randomTrunc, vec2(7., 7.)));
    blockLine_random = blockLine_random * 2.0 - 1.0;	
    blockLine_random = sign(blockLine_random) * clamp((abs(blockLine_random) - _Amount) / (0.4), 0., 1.);
    blockLine_random = mix(0., blockLine_random, _Offset);
    //return vec3(blockLine_random);-----------------------3
    
    vec2 uv_blockLine = uv;
    uv_blockLine = clamp(uv_blockLine + vec2(0.1 * blockLine_random, 0.), 0., 1.);
    
    vec3 col = texture(iChannel0, abs(uv_blockLine)).xyz;
    //return col; -----------------------------------------4
    
    col = rgb2yuv(col);
    col.y /= 2. - 3. * abs(blockLine_random) * clamp(0.5 -  blockLine_random, 0., 1.); //Chrominance
    col.z += 3.25 *  blockLine_random * clamp( blockLine_random - .5, 0., 1.);  //Chroma
    col = yuv2rgb(col);
    col = pow(col, vec3(1. / 2.2));
    
    vec3 ori_col = texture(iChannel0, uv).xyz;
    return mix(ori_col, col, vec3(_Alpha));
    
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = LineBlockGlitch(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Tile Jitter Glitch

Common

#define IS_DYMIC 0
#define IS_HOR 1
#define SPLIT_DIR 1
#define _Frequency (30.)
#define _SplittingNumber (8.)
#define _JitterSpeed (25.4)
#define _JitterAmount (67.)
#define pixelSizeX (1. / iResolution.x)

Image

vec3 TileJitterGlitch(vec2 uv)
{
    float str;
    #if IS_DYMIC
        str = 1.;
    #else
        str = 0.5 + 0.5 * cos(iTime * _Frequency);
    #endif
    
    float dir;
    #if SPLIT_DIR
        dir = mod(uv.y * _SplittingNumber, 2.);
    #else
        dir = mod(uv.x * _SplittingNumber, 2.);
    #endif
    
    if(dir < 1.)
    {
        #if IS_HOR
            uv.x += pixelSizeX * cos(iTime * _JitterSpeed) * _JitterAmount * str;
        #else
            uv.y += pixelSizeX * cos(iTime * _JitterSpeed) * _JitterAmount * str;
        #endif
    }
    return texture(iChannel0, uv).xyz;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = TileJitterGlitch(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Scan Line Jitter Glitch

Common

#define _DIR 0 / / direction
#define _ScanLineJitter_Y (sin(iTime)) / / effect degree
#define _ScanLineJitter_X (1. / iResolution.x * 10.)  // Offset Degree

Image

float randomNoise(float x, float y)
{
	return fract(sin(dot(vec2(x, y), vec2(12.9898, 78.233))) * 43758.5453);
}

vec3 ScanLineJitter(vec2 uv)
{
    #if _DIR
        float jitter = randomNoise(uv.x, iTime) * 2. - 1.;
    #else
        float jitter = randomNoise(uv.y, iTime) * 2. - 1.;
    #endif
    
    jitter *= step(_ScanLineJitter_Y, abs(jitter)) * _ScanLineJitter_X;
    
    vec3 col = texture(iChannel0, fract(uv + vec2(jitter, 0))).xyz;
    return col;
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = ScanLineJitter(uv);

    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Digital Stripe Glitch

Digital Stripe Glitch is also one of the post-processing effects of Glitch system with high appearance rate. For example, it can be seen in the gameplay of cyberpunk 2077:

[if the external link image fails to be transferred, the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-E9OvmOvf-1623489358512)(... /... / game programmer study notes master / game programmer study notes master / content / high quality post-processing: summary and implementation of ten Glitch Art algorithms / media/3d34f30356b1f00abb6b3c93ae2b43dc.png)]

Figure Digital Stripe Glitch special effect in cyberpunk 2077 @ CD Projekt

Digital Stripe Glitch needs to complete the generation of noise Texture in the Runtime layer, and then transfer it to GPU for final operation and rendering.

The core idea of Runtime is to generate random color stripe map based on random number. The implementation code is as follows:

for (int y = 0; y < _noiseTexture.height; y++)
{
    for (int x = 0; x < _noiseTexture.width; x++)
    {
        //If the random value is greater than the random threshold of the given strip, the random color will be changed again
        if (UnityEngine.Random.value > stripLength)
        {
            color = XPostProcessingUtility.RandomColor();
        }
        //Set map pixel values
        _noiseTexture.SetPixel(x, y, color);
    }
}

The generated pictures are as follows:

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-8cjkkesw-1623489358513) (post processing technology - fault. Assets / c55183415acbce177f0b96c3b090d9a. PNG)]

The implementation of Shader layer is divided into two main parts: uv offset and optional interpolation based on discarded frames:

half4 Frag(VaryingsDefault i): SV_Target
{
	// Basic data preparation
	 half4 stripNoise = SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, i.texcoord);
	 half threshold = 1.001 - _Indensity * 1.001;

	// uv offset
	half uvShift = step(threshold, pow(abs(stripNoise.x), 3));
	float2 uv = frac(i.texcoord + stripNoise.yz * uvShift);
	half4 source = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);

    #ifndef NEED_TRASH_FRAME
	    return source;
    #endif 	

	// Interpolation based on discarded frames
	half stripIndensity = step(threshold, pow(abs(stripNoise.w), 3)) * _StripColorAdjustIndensity;
	half3 color = lerp(source, _StripColorAdjustColor, stripIndensity).rgb;
	return float4(color, source.a);
}

The rendering without waste frame interpolation is shown as follows:

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-ssbpjswz-1623489358514) (post processing technology - fault. assets/b5d768ce574684a71147c32c3d79749d.gif)]

The rendering performance of waste frame interpolation is as follows. In addition to the offset color similar to the reverse color used in the figure below, the offset color based on RGB color random or chroma correction after color space conversion can also be realized:

[the external chain picture transfer fails, and the source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-uh9da9bm-1623489358515) (post processing technology - fault. assets/9b8e47d4109237a8d500229895b170e3.gif)]

The complete implementation source code of Digital Stripe Glitch post-processing can be seen:

https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchDigitalStripe

Analog Noise Glitch

Common

#define _Speed (0.1)
#define _LuminanceJitterThreshold (0.5)
#define _Fading (0.7)

vec2 Speed()
{
    return vec2(_Speed, _Speed);
}

Image

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

vec2 iTimeV2()
{
    return vec2(iTime, iTime);
}


vec3 AnalogNoiseGlitch(vec2 uv)
{
    float noiseX = randomNoise(iTimeV2() * Speed() + uv);
    float noiseY = randomNoise(iTimeV2() * Speed() - uv);
    float noiseZ = randomNoise(iTimeV2() * Speed() + uv);
    
    vec3 col = texture(iChannel0, uv).xyz;
    vec3 noise_col = col;
    
    float luminance = dot(noise_col, vec3(0.22, 0.707, 0.071));
    
    if(randomNoise(vec2(iTime * _Speed, iTime * _Speed)) > _LuminanceJitterThreshold)
    {
        noise_col = vec3(luminance, luminance, luminance);
    }
    
    
    noise_col += 0.25 * vec3(noiseX, noiseY, noiseZ) - 0.125;
    
    noise_col = mix(col, noise_col, _Fading);
    return noise_col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = AnalogNoiseGlitch(uv);  
    
    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Screen Jump Glitch

Common

#define _DIR 1
#define _JumpIndensity (0.2)
#define _JumpTime (10. * iTime)

Image

vec3 ScreenJumpGlitch(vec2 uv)
{
    #if _DIR
        float jump = mix(uv.y, fract(uv.y + _JumpTime), _JumpIndensity);
        vec3 col = texture(iChannel0, fract(vec2(uv.x, jump))).xyz;
    #else
        float jump = mix(uv.x, fract(uv.x + _JumpTime), _JumpIndensity);
        vec3 col = texture(iChannel0, fract(vec2(jump, uv.y))).xyz;
    #endif
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = ScreenJumpGlitch(uv);  
    
    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Screen Shake Glitch

Common

#define _DIR 1
#define _ScreenShake (0.2)

Image

float randomNoise(float x, float y)
{
	return fract(sin(dot(vec2(x, y), vec2(12.9898, 78.233))) * 43758.5453);
}

vec3 ScreenShakeGlitch(vec2 uv)
{
    float shake = (randomNoise(iTime, 2.) - 0.5) * _ScreenShake;
    #if _DIR  
        vec3 col = texture(iChannel0, fract(vec2(uv.x, uv.y + shake))).xyz;
    #else
        vec3 col = texture(iChannel0, fract(vec2(uv.x + shake, uv.y))).xyz;
    #endif
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = ScreenShakeGlitch(uv);  
    
    // Output to screen
    fragColor = vec4(col,1.0);
}

result

Wave Jitter Glitch

Noise generation function library XNoiseLibrary

For this, XPL refers to paper<Simplex noise demystified >,Webgl noise Library and NoiseShader Library , realize a single file version of multi-dimensional noise generation library[ XNoiseLibrary].

XNoiseLibrary has three types of Noise generating functions:

  • 2D/3D/4D Simplex Noise

  • 2D/3D textureless classic Noise

  • Re-oriented 4 / 8-Point BCC Noise

The advantage of XNoiseLibrary is that it is easy to use and directly include s a single file XNoiseLibrary HLSL can call the multi version noise function encapsulated in it.

The implementation source code of XNoiseLibrary can be seen:

https://github.com/QianMo/X-PostProcessing-Library/blob/master/Assets/X-PostProcessing/Shaders/XNoiseLibrary.hlsl


Implementation algorithm of Wave Jitter Glitch

Common

#define _DIR 1
#define _Speed (0.2)
#define strength (2. * cos(iTime))
#define _Amount (2. * sin(iTime))

#define NOISE_SIMPLEX_1_DIV_289 0.00346020761245674740484429065744

vec2 mod289(vec2 x)
{
	return x - floor(x * NOISE_SIMPLEX_1_DIV_289) * 289.0;
}

vec3 mod289(vec3 x)
{
	return x - floor(x * NOISE_SIMPLEX_1_DIV_289) * 289.0;
}

vec3 permute(vec3 x)
{
	return mod289(x * x * 34.0 + x);
}

vec3 taylorInvSqrt(vec3 r)
{
	return 1.79284291400159 - 0.85373472095314 * r;
}

float snoise(vec2 v)
{
	const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
	0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
	- 0.577350269189626, // -1.0 + 2.0 * C.x
	0.024390243902439); // 1.0 / 41.0
	// First corner
	vec2 i = floor(v + dot(v, C.yy));
	vec2 x0 = v - i + dot(i, C.xx);
	
	// Other corners
	vec2 i1;
	i1.x = step(x0.y, x0.x);
	i1.y = 1.0 - i1.x;
	
	// x1 = x0 - i1  + 1.0 * C.xx;
	// x2 = x0 - 1.0 + 2.0 * C.xx;
	vec2 x1 = x0 + C.xx - i1;
	vec2 x2 = x0 + C.zz;
	
	// Permutations
	i = mod289(i); // Avoid truncation effects in permutation
	vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) 
    + i.x + vec3(0.0, i1.x, 1.0));
	
	vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0);
	m = m * m;
	m = m * m;
	
	// Gradients: 41 points uniformly over a line, mapped onto a diamond.
	// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
	vec3 x = 2.0 * fract(p * C.www) - 1.0;
	vec3 h = abs(x) - 0.5;
	vec3 ox = floor(x + 0.5);
	vec3 a0 = x - ox;
	
	// Normalise gradients implicitly by scaling m
	m *= taylorInvSqrt(a0 * a0 + h * h);
	
	// Compute final noise value at P
	vec3 g;
	g.x = a0.x * x0.x + h.x * x0.y;
	g.y = a0.y * x1.x + h.y * x1.y;
	g.z = a0.z * x2.x + h.z * x2.y;
	return 130.0 * dot(m, g);
}

Image

vec3 WaveJitterGlitch(vec2 uv)
{
    float uv_y = uv.y * iResolution.y;
    float noise_wave_1 = snoise(vec2(uv_y * 0.01, iTime * _Speed * 20.))
    * (strength * _Amount * 32.);
    float noise_wave_2 = snoise(vec2(uv_y * 0.02, iTime * _Speed * 10.))
    * (strength * _Amount * 4.);
    float noise_wave_x = noise_wave_1 / iResolution.x;
    float uv_x = uv.x + noise_wave_x;
    vec3 col = texture(iChannel0, vec2(uv_x, uv.y)).xyz;
    return col;
    
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = WaveJitterGlitch(uv);  
    
    // Output to screen
    fragColor = vec4(col,1.0);
}

result

summary

Fault art pursues the unique beauty brought by "fault". In recent years, fault art has become one of the core artistic styles in cyberpunk style films and games. With the continuous release of various relevant film and television works and game works, the performance style of fault art has also attracted extensive imitation in e-commerce, variety show, FMCG and other industries.

After reading the above ten different fault art algorithms, we can refine them. To realize the rendering performance of fault art style in screen space, the core of the algorithm lies in four points:

  • Selection of noise function: noise function is the source of generating all kinds of interference signals.

  • Selection of uv dithering mode: after the noise function is applied to the uv in the screen space, sampling is carried out based on the new uv to produce the dithering performance of the fault.

  • Selection of sampling channel: RGB is sampled separately, or specific channel is selected for sampling, so as to realize various styles of fault performance.

  • Conversion of color space: make good use of YUV, CMY, HSV, YIQ and YCbCr
    , YC1C2 and other spaces are converted to RGB space to realize various styles of fault performance.

Familiar with the key points of the above four fault art algorithms, plus a little creativity, combined with the surrounding algorithms, we can create more expressive fault art effects.


Reference

[1] Jackson R. The Glitch Aesthetic[J]. 2011.
https://scholarworks.gsu.edu/cgi/viewcontent.cgi?article=1081&context=communication_theses

[2] den Heijer E. Evolving glitch art[C]//International Conference on
Evolutionary and Biologically Inspired Music and Art. Springer, Berlin,
Heidelberg, 2013: 109-120.

[3] https://zh.wikipedia.org/wiki/%E8%B5%9B%E5%8D%9A%E6%9C%8B%E5%85%8B

[4] https://github.com/keijiro/KinoGlitch

[5] https://github.com/ashima/webgl-noise

[6] https://github.com/keijiro/NoiseShader

[7] https://wallpaperswise.com/new-20-blade-runner-wallpapers/

[8] http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf

v selection of dithering mode * *: after the noise function is applied to the uv in the screen space, sample based on the new uv to produce the dithering performance of the fault.

  • Selection of sampling channel: RGB is sampled separately, or specific channel is selected for sampling, so as to realize various styles of fault performance.

  • Conversion of color space: make good use of YUV, CMY, HSV, YIQ and YCbCr
    , YC1C2 and other spaces are converted to RGB space to realize various styles of fault performance.

Familiar with the key points of the above four fault art algorithms, plus a little creativity, combined with the surrounding algorithms, we can create more expressive fault art effects.


Reference

[1] Jackson R. The Glitch Aesthetic[J]. 2011.
https://scholarworks.gsu.edu/cgi/viewcontent.cgi?article=1081&context=communication_theses

[2] den Heijer E. Evolving glitch art[C]//International Conference on
Evolutionary and Biologically Inspired Music and Art. Springer, Berlin,
Heidelberg, 2013: 109-120.

[3] https://zh.wikipedia.org/wiki/%E8%B5%9B%E5%8D%9A%E6%9C%8B%E5%85%8B

[4] https://github.com/keijiro/KinoGlitch

[5] https://github.com/ashima/webgl-noise

[6] https://github.com/keijiro/NoiseShader

[7] https://wallpaperswise.com/new-20-blade-runner-wallpapers/

[8] http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf

[9] The picture is from Cyberpunk 2077

Added by klpang on Sun, 30 Jan 2022 12:21:17 +0200