Back to shaders
Shader test bench
FFT Filled Waveform.fs
runnable fragment
Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.
Code
uniform float fftImage;
uniform float strokeSize;
uniform float gain;
uniform float minRange;
uniform float maxRange;
uniform vec4 topColor;
uniform vec4 bottomColor;
uniform vec4 strokeColor;
precision mediump float;
/*{
"DESCRIPTION": "Visualizes an FFT analysis image with custom set colors for frequency domain",
"CREDIT": "by VIDVOX",
"ISFVSN": "2",
"CATEGORIES": [
"Audio Visualizer"
],
"INPUTS": [
{
"NAME": "fftImage",
"TYPE": "audioFFT"
},
{
"NAME": "strokeSize",
"TYPE": "float",
"MIN": 0.0,
"MAX": 0.25,
"DEFAULT": 0.1
},
{
"NAME": "gain",
"TYPE": "float",
"MIN": 1.0,
"MAX": 5.0,
"DEFAULT": 1.0
},
{
"NAME": "minRange",
"TYPE": "float",
"MIN": 0.0,
"MAX": 1.0,
"DEFAULT": 0.0
},
{
"NAME": "maxRange",
"TYPE": "float",
"MIN": 0.0,
"MAX": 1.0,
"DEFAULT": 1.0
},
{
"NAME": "topColor",
"TYPE": "color",
"DEFAULT": [
0.0,
0.0,
0.0,
0.0
]
},
{
"NAME": "bottomColor",
"TYPE": "color",
"DEFAULT": [
0.0,
0.5,
0.9,
1.0
]
},
{
"NAME": "strokeColor",
"TYPE": "color",
"DEFAULT": [
0.25,
0.25,
0.25,
1.0
]
}
]
}*/
void main() {
vec2 loc = (gl_FragCoord.xy / u_resolution.xy);
// the fftImage is 256 steps
loc.x = loc.x * abs(maxRange - minRange) + minRange;
vec4 fft = texture2D(fftImage, vec2(loc.x,0.5));
float fftVal = gain * (fft.r + fft.g + fft.b) / 3.0;
if (loc.y > fftVal)
fft = topColor;
else
fft = bottomColor;
if ((strokeSize > 0.0) && (abs(fftVal - loc.y) < strokeSize)) {
fft = mix(strokeColor, fft, abs(fftVal - loc.y) / strokeSize);
}
//(smoothstep(0.0, stroke, abs(fftVal - loc.y))) * strokeColor);
gl_FragColor = fft;
}