Gooch Shading

Photorealistic rendering is a major issue nowadays. We are looking for increased realism in moves and games. But this realism can come as a flaw when rendering for illustration purposes. This lead to a whole field of study called NPR, Non Photorealistic Rendering. An important work in this field is the shading of Gooch [1]. This is a method to shade objects that focuses on rendering an picture that is easily readable.

The first point made by Gooch is that the edges of the objects should be drawn. There are several methods to do so. The fastest one to implement is to use two rendering passes. The first one draw the wireframe of the object with very large lines. The second one draws the object itself. The depth test hides the edges that are not visible. This methods is easy to implement but the results present some artefacts where edges connect.

The edges help to determine the silhouette of the skeleton. However, you may note that since the edges are drawn in black, it can be difficult to discern the edges from the shadowed part of the mesh. T rex mesh from :


You can note that the lines are broken where edges connect. Those artefacts could be avoided by using another method for the edge detection and silhouette drawing.


glCullFace (GL_FRONT);
glDepthFunc (GL_LEQUAL);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 
glCullFace (GL_BACK);
glDepthFunc (GL_LESS);

Once the edges are drawn, the second point made by Gooch is that the shadows and highlights on the object should be of different color than the edges or the object. Otherwise, different parts of the object can be rendered in the same color which prevents them from being easily differentiable.

Therefore, what is suggested is to take a « hot » color (like orange) for the enlightened parts of the object, and a « cold » color (like blue) for the shadowed parts. This way, the object colors interpolate between orange and blue, and therefore are never white or black. The edges and the highlights of the object are then perfectly readable.

In his paper, Gooch incorporates the original color of the object. The « hot » and « cold » colors thus become


where kd is the color of the object, kblue is (0, 0, 1) and kyellow is (1, 1, 0), α = 0.2 and β = 0.6.

Leading to the final shading formula


where l is the normalized light direction and n is the normalized normal.

There is the same mesh enlightened with Phong and with Gooch.

T Rex lighten with Phong. T rex mesh from :
The same T Rex with gooch shading. It is much easier to discern the different bones. T rex mesh from :
vec4 gooch_shading(vec4 m_color, //color of the mesh
                   float m_shine, //shininess of the surface
                   vec3 l_direction, //light direction
                   vec3 v_normal, //normal
                   vec3 c_direction) //camera direction
    float kd = 1;
    float a = 0.2;
    float b = 0.6;

    float NL = dot(normalize(v_normal), normalize(l_direction));
    float it = ((1 + NL) / 2);
    vec3 color = (1-it) * (vec3(0, 0, 0.4) + a* 
               +  it * (vec3(0.4, 0.4, 0) + b*;
    vec3 R = reflect( -normalize(l_direction), 
                      normalize(v_normal) );
    float ER = clamp( dot( normalize(c_direction), 
                     0, 1);
    vec4 spec = vec4(1) * pow(ER, m_shine);

    return vec4(, m_color.a);
[1] A.Gooch, B. Gooch, P. Shirley, and E. Cohen, “A non-photorealistic lighting model for automatic technical illustration,” in Proceedings of the 25th annual conference on Computer graphics and interactive techniques, 1998, pp. 447–452.


Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:


Vous commentez à l'aide de votre compte Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s