Wanted to play around for a bit with WebGL and glitching images, was working with Three.js and react and I decieded to make a little project out of it.
One day was trying to make images glitch and traditonal way with css was not good enought, so I decided to try ThreeJS with in a React Project.
I implemented it in a project I already had with three.js and react, so I could use the same camera and renderer.
This is the end result:
This are the important libraries involved:
the Plane that will be the "image"
This Plane component is part of a larger React application that uses Three.js for 3D graphics. The component represents a plane in the 3D space, and it's defined as a functional component that accepts props such as position, rotation, and scale. for this particular case I'm using it plane and with no rotation, so its behaves kinda like a 2D image.
The stored state is not so relevant for this case, the main interesting things are the random generation using clock and the use of useFrame hook to update the displacement map.
and of course the myCustomMaterial component which is a custom shader material that uses a displacement map to create the glitch effect
The Shader:
This Shader ( which is an extension of ShaderMaterial ) has 3 parts:
Displacement
Chromatic Aberration
Displacement
Here's what's happening, the shader samples a displacement texture (disp) and creates two distorted versions of the UV coordinates:
dispFactor: How much displacement to apply (0-1)
effectFactor: Overall intensity multiplier
disp.r: Red channel of the displacement texture
Mixing
The shader samples the main texture twice using both distorted positions, these samples are then mixed together based on dispFactor which creates a smooth transition between the two displaced versions
Additional randomness
Here I generate a pseudo-random v value, when v is above 0.1, it creates additional displacement and use amplitude to control how many "slices" the effect creates.
Here the displacements get applied in a "Grid" type of way, the sin function is used to create the spaces in between the glitch and not gitched parts.
Chromatic Aberration
Here I define the red green blue channels and then:
each channel gets a different distortion.
Finally the original image tex gets added with the new 3 channel distorted image ruvguvbuv, beacuse this 3 separated channels will have pixels only in the places that are visible thanks to the v condition and sin() function.
The clock and the randoms from the React components generate randomness thru time, and update the dispFactor variable, the rest of the randomness happens in the glsl shader, based on the dispFactor variable.