Rim Lighting

Rim lighting is a very beautiful effect that you can use to enhance your overall lighting in your 3D scene. To get this effect in a photo or in real life you must have some lights behind your objects and your view direction must be in front of this object, for this reason in some books or other website you will find it named as back-lighting. The special power of Rim lighting is that it creates, as the name implies, a bright contour around the lit object. Now you know that proverb “A picture is worth a thousand words”, so this is the effect that I’m talking about in photography:

Rim Light

Rim lighting in a photo (Original)

And this is the OpenGL scene that I created with Rim lighting (just look at the trees). To implement the rim lighting effect in your 3D scene is very simple, you only need surface Normals, in this case trees normals and the View direction which you already have from a reflection lighting model (I talked about them here).

Rim Lighting OpenGL

Rim Lighting in OpenGL

I highlighted with red the rim effect just to be clear

I highlighted with red the rim effect on a few trees just to be clear

Without Rim Lighting

Without Rim Lighting

The easiest way to explain how Rim lighting works in a 3D environment is to rely once again on  Lambert’s cosine law with light direction changed by the view direction:

Rim Lighting

Rim Lighting

In the image above, we don’t use light direction to get the rim lighting but I just added it to see the concept. Now we know that the dot product of two orthogonal vectors is 0.0 because they form a 90 degrees angle and cosine of 90 is equal to 0.0. The problem is that we actually need that dot product to be 1.0 instead of 0.0 when we create the rim effect (to brighten the contour). So we can subtract the dot product result from 1.0:

Rim Equation

Rim Equation

The only thing left to discuss about Rim lighting implementation is the contribution of light on the surface of the object. There are a couple of ways to deal with this. We can use an if-else-if statemant or a pow function or a smoothstep function. The last two can create a nice cutoff and give some really nice results.

I enhanced my scene by using a lateral diffuse light. In the pictures below I separate the rim and diffuse lights just to see how they behave by themselves (click on the image to enlarge). By the way the ground here is rendered with the same rim lighting shader. Also I introduced a higher gamma to get a dark image. The sun object is rendered with another shader with only ambient and diffuse lighting.

Diffuse Light Only

Diffuse Lighting Only (click to enlarge)

Only Rim Lighting

Only Rim Lighting

Rim lighting without high gamma

Rim lighting without high gamma to see the pure effect :)

Rim and Diffuse

Rim and Diffuse

Rim Lighting OpenGL

Final scene with rim, diffuse lights and textures

Now let’s see the vertex shader:

#version 330

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_texcoord;

uniform mat4 model_matrix, view_matrix, projection_matrix;

out vec3 world_pos;
out vec3 world_normal;
out vec2 texcoord;

void main()
{
 //convert in world coords
 world_pos = mat3(model_matrix) * in_position;//careful here
 world_normal = normalize(mat3(model_matrix) * in_normal); 
 texcoord = in_texcoord;

 gl_Position = projection_matrix * view_matrix * model_matrix * vec4(in_position, 1);
}

And fragment shader:

#version 330

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_texcoord;

uniform mat4 model_matrix, view_matrix, projection_matrix;

out vec3 world_pos;
out vec3 world_normal;
out vec2 texcoord;

void main()

{
 //convert in world coords
 world_pos = mat3(model_matrix) * in_position;//careful here
 world_normal = normalize(mat3(model_matrix) * in_normal);
 
 texcoord = in_texcoord;
 gl_Position = projection_matrix * view_matrix * model_matrix * vec4(in_position, 1);
}

To enhance your scene even more you can add fog or light shafts. Also a skybox can be added to create a complete scene.

Source code:

Rim lighting Source only

Rim Lighting Visual Studio 2013 solution


Tagged under:
blog comments powered by Disqus