Giving visuals an analog feel

Hi guys,

I have been working on audio-reactive visuals for a while now and I’m looking for a way to make it feel more analog. I guess the most important aspects are color and noise, maybe some subtle glitches too. This video gives you an idea of what I’m looking for.

http://vimeo.com/23029522

Does anyone have any tips on where to start with this? I have a little experience in writing shaders.

Any examples or ideas would be great.

Cheers,
Daan

The only thing that comes to mind would be to take a look at all those vintage, instagram-like photo effects you see on everyone’s iphone lately. You could probably do the same kind of process in OF. It would be a post-processing type way of doing it, not sure how to make something that would look inherently analog in a digital medium though. Here are some photoshop actions that recreate all of the cliche vintage iphone effects:
http://dbox.tumblr.com/post/5426249009/instagram-filters-as-photoshop-actions

erik

I think some of what is going on in that video is “chromatic aberration”, this is something that you should be able to accomplish with a fragment shader: http://www.geeks3d.com/20101008/shader-library-chromatic-aberration-demo-glsl/

Also in the emulator world, there are a number of projects that attempt to make your computer act more like an old tv.

This post talks about patches to stella that do this: http://www.bogost.com/games/a-television-simulator.shtml
Here are some cpp things that emulate NTSC output for various platforms: http://slack.net/~ant/libs/ntsc.html
This blog post talks about some of the high level ways to jack up your signal: http://altdevblogaday.com/2011/07/18/high-voltage-retro-crt-emulation-for-pixel-art/

Of course, you won’t do that bad by going and grabbing some of Vade’s patches off of his site:
http://v002.info/?page-id=27

All those shader that Vade has on his site are basically how I learned the GLSL that I know. There’s a ton on there once you look around a little. Really remarkably stuff that only requires minor tweaking to get working in OF.

I’ve always been a fan of grain myself for analog feelings. Some of my rather lame attempts at frag shaders for that are here:

  
uniform sampler2D m_Texture;  
varying vec2 texCoord;  
uniform float m_Time;  
uniform float m_Strength;  
uniform float grainSize;  
void main() {  
    float x = (texCoord.x+4.) * (texCoord.y+4.) * (m_Time*10.);  
    vec4 grain = vec4(mod((mod(x, 13.) + 1.) * (mod(x, 123.) + 1.), grainSize)-(grainSize*0.5)) * m_Strength;  
    gl_FragColor = texture2D(m_Texture, texCoord) + grain;  
}  
  

or

  
uniform float time;  
varying vec4 vertexInImageSpace;  
  
float rand(vec2 co)  
{  
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);  
}  
  
void main()  
{  
    //just get a random number, using the vertex's screen-space position as a seed along with the time.  
    float r = rand(vec2(vertexInImageSpace.x/2.0 + sin(time), vertexInImageSpace.y/2.0 + cos(time)));  
  
    //play with the noise a bit; clamp it based on its value and scale the alpha.  
    if(r < 0.3) r = 0.0;  
    vec4 finalColor = vec4(r,r,r,r*0.7);  
  
    gl_FragColor = texture2D(m_Texture, vertexInImageSpace.xy) - clamp(finalColor, 0.0, 1.0);  
}  

Thanks for all the replies. I’ve started reading the Orange Book for learning shaders and I must say it’s a lot of fun. I generated a noise texture in photoshop and I blended it in using this:

  
  
        vec2 noiseCoords = float(frameNum * 50) + texCoord;  
	noiseCoords = mod(noiseCoords, noiseTextureSize);  
	vec4 noiseColor = texture2DRect(noiseTexture, noiseCoords);  
	vec4 noiseCol1 = mix(noiseColor, texture2DRect(tex0, texC), 0.95);  
  

which gives me almost the exact same results as Joshua’s second shader. My guess is that texture lookup is faster then the random number generation but I could be wrong. I’ll be looking around at Vade’s website for some more examples.

Yep, texture look-up is most definitely faster than random num generation. Really the only thing either of them have that’s at all quasi-cool is the grain size control in the first one, and even that needs a bunch of work to actually look like film grain :slight_smile:

I ended up using the following shader, in case it might be of interest to anyone. I used the technicolor color filtering from Vade’s website.

.vert:

  
  
uniform sampler2DRect tex0;  
varying vec2 texCoord;  
  
void main(){  
	texCoord = gl_MultiTexCoord0.xy;  
	  
	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;  
	gl_Position = pos;  
}  
  

.frag:

  
  
uniform sampler2DRect tex0;  
uniform sampler2DRect noiseTexture;  
  
uniform vec2 textureSize;  
uniform vec2 noiseTextureSize;  
uniform int frameNum;  
uniform float vignetteSize;  
uniform float colorFilterAmount;  
uniform float noiseAmount;  
  
varying vec2 texCoord;  
  
const vec4 redfilter 		= vec4(1.0, 0.0, 0.0, 1.0);  
const vec4 bluegreenfilter 	= vec4(0.0, 1.0, 0.7, 1.0);  
  
void main(){	  
	vec2 texC = texCoord;  
	float vignetteSizeSquared = vignetteSize * vignetteSize;  
	vec4 col = texture2DRect(tex0, texC);  
	  
	// vignette  
	vec2 center = textureSize / 2.0;  
	vec2 d = center - vec2(texCoord);  
	float distSQ = d.x*d.x + d.y*d.y;  
	float invDistSQ = 1.0 / distSQ;  
	  
	col.rgb -= distSQ / vignetteSizeSquared;  
	col = clamp(col, 0.0, 1.0);  
	  
	// noise   
	vec2 noiseCoords = float(frameNum * 50) + texCoord;  
	noiseCoords = mod(noiseCoords, noiseTextureSize);  
	vec4 noiseColor = texture2DRect(noiseTexture, noiseCoords);  
	noiseColor = mix(noiseColor, col, noiseAmount);  
  
	// color filter  
	vec4 redrecord = noiseColor * redfilter;  
	vec4 bluegreenrecord = noiseColor * bluegreenfilter;  
	  
	vec4 rednegative = vec4(redrecord.r);  
	vec4 bluegreennegative = vec4((bluegreenrecord.g + bluegreenrecord.b)/2.0);  
	  
	vec4 redoutput = rednegative * redfilter;  
	vec4 bluegreenoutput = bluegreennegative * bluegreenfilter;  
	vec4 result = redoutput + bluegreenoutput;  
	  
	result = mix(noiseColor, result, colorFilterAmount);  
	result.a = noiseColor.a;  
	  
	gl_FragColor = result;  
}  
  

Without shader:

With shader:

Nice. Love the line curvature and the vignetting is nice. Looking forward to seeing how the noise works into in over time too, since you’re altering per frame.