Generic Camera Distortions 2D Filter

This is a little 2D filter that does some common camera distortions such as:

  • Chromatic Abberation
  • Barrel Distortion
  • Vignette

All of the parameters can be controlled through game properties.


//A 2D filter to do many common camera distortions:
// - Barrel Distortion (fisheye)
// - Vignette
// - Chromatic abberation
// All can be controlled in real time using in-game variables

uniform sampler2D bgl_RenderedTexture;
uniform float chromatic;
uniform int blurPasses;
uniform float zoom;
uniform float vignette;

float rand(vec2 n){
    /* Returns a pseudorandom number */
    return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
}

vec3 getColAtStrength(float s, vec2 texcoord){
    /* Single pass of Chromatic Abberation */
    vec2 coord = texcoord - vec2(0.5, 0.5);
    vec3 sum = vec3(0.0);
    sum.b = vec3(texture2D(bgl_RenderedTexture, coord * (1.0)         + vec2(0.5, 0.5) )).b;
    sum.g = vec3(texture2D(bgl_RenderedTexture, coord * (1.0 - s/2.0) + vec2(0.5, 0.5) )).g;
    sum.r = vec3(texture2D(bgl_RenderedTexture, coord * (1.0 - s    ) + vec2(0.5, 0.5) )).r;
    return sum;
}

float getDistFromCenter(vec2 coord){
    /* Returns the distance from center with a little noise to break up banding */
    return length(vec2(0.5, 0.5) - coord) + rand(coord)/80.0;
}

vec2 convertCoordsToZoom(float z, vec2 coord){
    /* Barrel Distortion */
    float distFromCenter = getDistFromCenter(coord)*(z) + (1.0 - z);
    return (coord - vec2(0.5, 0.5)) * distFromCenter + vec2(0.5, 0.5);
}

vec3 vignetteColor(float v, vec3 col, vec2 coord){
    /* Vignettes the image */
    float distFromCenter = (1.0 - getDistFromCenter(coord))*(v) + (1.0 - v);
    return col * distFromCenter;
}

void main()
{
    vec3 out_sum = vec3(0.0);

    // Zoom the tex coordinates for barrel distortion
    vec2 texcoord = convertCoordsToZoom(zoom, gl_TexCoord[0].xy);

    // Do the chromatic aberation passes
    for(int i=0;i<=blurPasses;i++){
        out_sum += getColAtStrength(chromatic*float(i) / float(blurPasses), texcoord) / float(blurPasses);
    }

    // Apply vignetting
    out_sum = vignetteColor(vignette, out_sum, gl_TexCoord[0].xy);

    gl_FragColor = vec4(out_sum, 0.0);
}


Tested on AMD and Intel. As with all 2D filters, use sparingly.

Results:



Note the vertical blue lines on the second image aren’t straight and have some colour distortion.
Here is it completely overblown:

Blend:
CamFilterDemo.blend (506 KB)

Nice work! This could be useful for simulating the look of older video cameras, such as early mobile phone cameras or, more usefully, old VHS cctv cameras :smiley:

if a bloom happens then barrel distort this looks kinda lens flarish or no?

I should probably add bloom to that filter. But no, I don’t think it will look lens-flare-ish through the barrel distort.