OpenGL Rim Shader
Using a rim light gives your shading a nice volumentric effect which can greatly enhance the contrast with the background. A rim shader is very simple but has a great result. In this screenshot I applied a rim light effect which I blurred a bit to make it even more effective.

To create your rim shader, first a bit of background about the vectors that we need to perform the calculations. The contribution of the rim shading should be bigger around the peaks. Around the peaks, some normals are pointing towards the eye/cam position and some are pointing away. In the image below you can see that the angle between the normal and the eye vector (v) is big.
Getting the eye vector in your shader is easy. You convert your vertex position to view space by multiplying it with your view matrix, then you normalize and negate it.

Below you can see how small the angle between the eye and the normal of the other face is. It's clearly a lot smaller. This means that the rim contribution for this second drawing should be less then the first one.

In short you can say, the bigger the angle between the eye vector (v) and the 
normal (n), the bigger the contribution of the rim shading. To calculate this,
we use the dot product which gives us the cosine between two vectors. As you 
might know, the cosine between two vectors that are perpendicular is 0. You
can read up a bit on the dot product here. Because we want 
the contribution of the rim shading to be bigger when the angles are bigger,
we will use 1.0 - dot(normal, eye_vector). The 1.0 - part is necessary to 
make sure that the value will be bigger when the angle is bigger. E.g. when 
the vectors are perpendicular the contribution will be 1.0 (as the dot product
is zero).
In the GLSL example below we're implementing this rim shader, but we're skipping one important part to show you how using the calculated rim-contribution value looks like:
vec3 n = normalize(mat3(u_vm) * v_norm); // convert normal to view space, u_vm (view matrix), is a rigid body transform. vec3 p = vec3(u_vm * v_pos); // position in view space vec3 v = normalize(-p); // vector towards eye float vdn = 1.0 - max(dot(v, n), 0.0); // the rim-shading contribution fragcolor.a = 1.0; fragcolor.rgb = vec3(vdn);
Using the rim shading contribution as color (the vdn) we get the 
following result.

As you can clearly see, there is much more contribution than just around the 
edges/peaks. What we want to do, is to remove some of the contribution that are 
below a certain value. We could use an if statement like if(vdn < 0.5) { // skip }
but this will result in hard edges between the rim contribution. When we 
use smoothstep we can still limit the use of certain values but also make sure
that the values have a nice smooth cutoff. Therefore we add a smoothstep like:
fragcolor.rgb = vec3(smoothstep(0.8, 1.0, vdn));
This results in the image below:

The complete shader looks like:
#version 330 uniform mat4 u_pm; uniform mat4 u_vm; layout( location = 0 ) out vec4 fragcolor; in vec3 v_norm; in vec4 v_pos; void main() { vec3 n = normalize(mat3(u_vm) * v_norm); // convert normal to view space, u_vm (view matrix), is a rigid body transform. vec3 p = vec3(u_vm * v_pos); // position in view space vec3 v = normalize(-p); // eye vector float vdn = 1.0 - max(dot(v, n), 0.0); // the rim contribution fragcolor.a = 1.0; fragcolor.rgb = vec3(smoothstep(0.6, 1.0, vdn)); }
        
        NAT Types
        
        Building Cabinets
        
        Compiling GStreamer from source on Windows
        
        Debugging CMake Issues
        
        Dual Boot Arch Linux and Windows 10
        
        Mindset Updated Edition, Carol S. Dweck (Book Notes)
        
        How to setup a self-hosted Unifi NVR with Arch Linux
        
        Blender 2.8 How to use Transparent Textures
        
        Compiling FFmpeg with X264 on Windows 10 using MSVC
        
        Blender 2.8 OpenGL Buffer Exporter
        
        Blender 2.8 Baking lightmaps
        
        Blender 2.8 Tips and Tricks
        
        Setting up a Bluetooth Headset on Arch Linux
        
        Compiling x264 on Windows with MSVC
        
        C/C++ Snippets
        
        Reading Chunks from a Buffer
        
        Handy Bash Commands
        
        Building a zero copy parser
        
        Kalman Filter
        
        Saving pixel data using libpng
        
        Compile Apache, PHP and MySQL on Mac 10.10
        
        Fast Pixel Transfers with Pixel Buffer Objects
        
        High Resolution Timer function in C/C++
        
        Rendering text with Pango, Cairo and Freetype
        
        Fast OpenGL blur shader
        
        Spherical Environment Mapping with OpenGL
        
        Using OpenSSL with memory BIOs
        
        Attributeless Vertex Shader with OpenGL
        
        Circular Image Selector
        
        Decoding H264 and YUV420P playback
        
        Fast Fourier Transform
        
        OpenGL Rim Shader
        
        Rendering The Depth Buffer
        
        Delaunay Triangulation
        
        RapidXML
        
        Git Snippets
        
        Basic Shading With OpenGL
        
        Open Source Libraries For Creative Coding
        
        Bouncing particle effect
        
        OpenGL Instanced Rendering
        
        Mapping a texture on a disc
        
        Download HTML page using CURL
        
        Height Field Simulation on GPU
        
        OpenCV
        
        Some notes on OpenGL
        
        Math
        
        Gists to remember
        
        Reverse SSH
        
        Working Set
        
        Consumer + Producer model with libuv
        
        Parsing binary data
        
        C++ file operation snippets
        
        Importance of blur with image gradients
        
        Real-time oil painting with openGL
        
        x264 encoder
        
        Generative helix with openGL
        
        Mini test with vector field
        
        Protractor gesture recognizer
        
        Hair simulation
        
        Some glitch screenshots
        
        Working on video installation
        
        Generative meshes
        
        Converting video/audio using avconv
        
        Auto start terminal app on mac
        
        Export blender object to simple file format