Integrating the clipping

We will now integrate the previous clipping into our framework. There isn't actually much that we have to do, but we have to apply the clipping and also handle the output. The changes are minor, we just throw each triangle in the clipping function, but there is something we have to do with the result, because it might not be a triangle! For example, if you cut off one side with a clipping plane, you will get a quadrilateral!

As we are only able to rasterize triangles, what can we do, when the clipping result is a general polygon?

The answer is actually simple: We decompose the polygon into multiple triangles! There might be algorithms to find the nicest decomposition, for example such that we avoid very thin triangles, but we can also do it simply.

We start with the first triangle with vertices 0,1,20,1,2. That way, we have basically "surrounded" the middle vertex, as the polygon line will just continue at the last vertex. So the next triangle will skip the second vertex and start with the third, giving us the triangle 0,2,30,2,3.

In general, the ii-th triangle will have the indices 0,i+1,i+20,i+1,i+2.

We will incorporate this into our process_triangle method, that finally gets something to do. The clip_polygon function from the last section is already included as a member function of the rasterizer.

process_triangle(pipeline, v0, v1, v2) {

  // prepare points and data for clipping
  let points = [v0, v1, v2];
  // clip polygon
  points = this.clip_polygon(points, pipeline.clip_planes);

  // triangulate polygon (clipping the triangle may result
  //  in non triangles

  // we will do this now
   ... 
}

Clip planes are stored in the same format as before as an array in the Pipeline class that holds all the state options. It looks as follows:

class Pipeline {
    constructor({
        viewport = {
            x: 0,
            y: 0,
            w: 0,
            h: 0
        },
        framebuffer = Framebuffer.new(),
        clip_planes = [],
    } = {}) {
        this.viewport = viewport;
        this.clip_planes = clip_planes;
        this.framebuffer = framebuffer;
    }
}

Since we can't yet output different color per shape, our image will be a bit simpler than the one in the previous section, but we will get there in the next part!

Below that is the solution

Exercise:

Solution:

See the solution