Can you explain why clipping takes place after the illumination process in the rendering pipeline? Would it be not cheaper to clip first and do then the illumination?
It wouldn't actually be faster, and it would be mean a much more complex pipeline with less control and flexibility over the final image.
Conceptually, clipping creates extra vertices. When you clip a triangle, you end up with a polygon, and that means you'll need at least one extra vertex in order to turn everything into triangles again.
While many lighting computations are done now at the per-pixel level, some per-vertex setup is often necessary or desirable. It is useful to look at what reality would be if you did clip before you did any other per-vertex attribute computations needed for eventual per-vertex lighting.
If you were to perform lighting (and other vertex attribute) computations after you clipped a triangle, you'd have to have already transformed the position all the way to clip space so you know what and where to clip, and you'd also have to determine values for all attributes of all the new vertices. That means you're going to have to interpolate them, much like varying data is eventually interpolated across the surface of the triangle when fragment shading is performed.
But that means that now you have these extra computations to perform (which you're just going to perform again when you do fragment shading), and you have an additional vertex (at least) to run your vertex shader on. So it isn't necessarily true that clipping earlier would be more efficient.
Furthermore, many vertex attributes are specified by hand, and/or may not interpolate well. This is especially true of some of the attributes used to do some of the clever tricks used to make modern effects. That would significantly decrease the amount of flexibility available in the graphics pipeline to achieve interesting lighting effects or other such fancy business. Especially so with the modern programmable pipeline. That loss of flexibility would be a huge detriment, optimization or no.
Finally, a somewhat less important issue is that clipping is done in a very unusual coordinate space, and it would be fairly annoying to work in that space all the time (for lighting computations, and whatnot).
Clipping happens after vertex processing, before the pixel processing stage of the graphics pipeline. It has to take place after vertex processing for the trivial reason that clipping needs to know where the vertices are in screen space.
Clipping has nothing in particular to do with illumination. It only takes place after illumination if you do illumination per-vertex. But nowadays, lighting calculations are usually done per-pixel, not per-vertex. Only the pixels within the viewport, i.e. those that survive clipping, will be shaded, so in that case illumination is done after clipping.
It doesn't necessarily do that.
In some models, lighting is per-vertex. The problem is that you can't clip vertices until after they're transformed into clip space, since you have absolutely no way to know if a vertex is visible or not (aside from view frustrum clipping, which is not cheap). So you do all per-vertex calculations in one go. Then comes the conversion to clip space where clipping can cheaply and easily be done. Then the clipped triangle is rasterized and the fragment/pixel shader is run.
Many newer rendering pipelines do most or all lighting calculations in the pixel shader, so it actually is done after clipping.
To cut down on the amount of vertex data processed, the application should do some form of culling. Due to the inherent inefficiencies of clipping before hitting clip space, culling is typically by whole objects/meshes. An object which is only partially potentially visible will still have vertex processing done for all its vertices but at least objects which are wholly outside the view frustrum won't be sent to the GPU for processing in the first place.
In simple pseudo-code, the pipeline (including the application-side bits) is something like:
for each object: if not culled: for each vertex: run vertex shader convert to clip space for each triangle in clip space: clip triangle // note this is after vertices are processed convert to NDC space rasterize for each fragment of clipped triangles: do early depth test do early stencil test run pixel shader do alpha test, depth test, stencil test write depth, stencil, and blend outputs
Lighting traditionally was done all in vertex shaders because they're much cheaper. A large triangle will have only 3 vertices (maybe more if clipped into a more complex polygon, though most hardware just maps all shapes into multiple trapezoids anyway) but it could have potentially thousands of fragments/pixels (maybe even millions in some cases). Doing the computation in the pixel shader requires significantly more powerful hardware than was available when the classic rendering pipeline was defined.