Film Grain in OpenGL

Is there a fast technique for rendering a scene using opengl and creating a film grain (a noise-like pattern) over the screen? Something that runs in realtime would be great.

Can you get away with a series of textures that make up about a seconds worth of this noise and then display them on a blended quad over the entire scrren as the last rendering step?

Animating the texture used would make it look quite cool. You could even have the vertical scrape lines that are often found in old black and white films…

Pete

ftp://ftp.scene.org/pub/parties/2000/takeover00/demo/vip2.zip

At the end of this (FANTASTIC !) OpenGL demo, there are some film grain examples.

You can create one texture with the grain
pattern, and make it fairly large (say,
1024x1024) but only luminance. Then when
your scene is drawn, turn off depth testing
and draw a large quad covering the screen
with this one texture (or some part of it)
in GL_MODULATE mode.
You should jitter/move the grain texture
between each frame by a fair amount, because
grain is not correlated from frame to frame.

Assuming your range is 0.5 in each dimension,
your texture coordinates could be from
<dx,dy> to <dx+0.5,dy+0.5> with the range of
dx and dy in [0.f, 0.5].

There are more advanced ways of simulating
film grain (using gamma tricks, color bleed
and other such things) but you can’t do that
without an accumulation buffer, and thus it
won’t run in real-time on current hardware.

Although this is pretty much a repetition of what has been said above but…

We created an XRay renderer and to simulate the noise we created a noise texture using 3ds max then blended at the last pass and randomly jittered, it looked excellent.

If you need a good procedural texture
generator, try the POV-Ray raytracer/renderer.
It’s pretty slow, but the “shader language”
is fairly expressive and it can easily
generate good skyboxes, backgrounds, and
“procedural” textures.

Try this for a noise pattern (512x512 or
bigger):

camera {
right x
up y
angle 90
}

plane {
z 1
texture {
pigment {
granite
color_map { [0.0 color rgb 0.3 ] [0.7 color rgb 1] }
}
finish {
ambient 1
}
scale 0.03
}
}