During my not-so-secret project to make a visual demo in GodotEngine I'm trying to make most of the graphics engine. But as in most production most magic is made by faking it. This time it's about the camera.

The Problem with Camera

This screen shows default camera. It's nice with DoF and all but lacks two little details.

Vignetting or just darker corners of the image. Also chromatic aberrations that is a shifted red and blue channels of the image also in the corners.

Those two things simulates problems with real lenses. Can you spot the difference?

Solution

Camera trick

I made a plane in front of camera that covers full frame. Then I added this shader.

shader_type spatial;
render_mode depth_test_disable, depth_draw_never, unshaded, cull_disabled;

uniform float light : hint_range(0, 1);
uniform float extend : hint_range(0, 1);
uniform float offset : hint_range(0, 10);

void fragment() {
    vec2 uv = UV;
    vec3 chroma;
    float amount = offset * 0.0005;

    // cache screen
    vec3 og_color = textureLod( SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;

    // cache screen witch chroma (r/b shifted by ammount)
    chroma.r = textureLod( SCREEN_TEXTURE, SCREEN_UV + vec2(amount, 0.), 0.0).r;
    chroma.g = og_color.g;
    chroma.b = textureLod( SCREEN_TEXTURE, SCREEN_UV - vec2(amount, 0.), 0.0).b;
    
    // generate gradient from center to the corners
    uv *=  1.0 - uv.yx;
    float vig = uv.x*uv.y * 15.;
    vig = pow(vig, extend);
    vig = 1.0 - vig;

    // mix chroma with original image by the gradient (more on corners, less in center)
    chroma = mix(og_color, chroma, vig * 2.);
    
	// mix chroma with vignette (darker version of chroma image)
    ALBEDO = mix(chroma, chroma * vec3(light), vig);
}
Screenshot from Efate
Screenshot from Efate
Screenshot from Efate