CS 551 / 645: Introductory Computer Graphics Rasterizing General Polygons Clipping Lines David Luebke 7/27/2016 Recap: Rasterizing Triangles Interactive graphics: polygons rule the world In practice, polygons are often decomposed into triangles (Why?) Different methods for rasterizing triangles: – – – – David Luebke Screen-space subdivision (Warnock’s Algorithm) Primitive subdivision (REYES, Renderman) Edge walking Edge equations 7/27/2016 Recap: Edge Walking Basic idea: – – – – David Luebke Draw edges vertically Fill in horizontal spans for each scanline Interpolate colors down edges At each scanline, interpolate edge colors across span 7/27/2016 Recap: Edge Equations Edge equations thus define two half-spaces: David Luebke 7/27/2016 Recap: Edge Equations And a triangle can be defined as the intersection of three positive half-spaces: David Luebke 7/27/2016 Recap: Edge Equations We discussed methods for optimizing rasterization with edge equations: – Early termination – Incremental computation of edge equations – Fast test for negative edge equation values We discussed computing the coefficients {A, B, C} of each edge equation David Luebke 7/27/2016 Recap: Interpolating Parameters Given colors (and later, other parameters) at the vertices, how to interpolate across? Idea: triangles are planar in any space: – This is the “redness” parameter space – Note:plane follows form z = Ax + By + C – Can use same methods! – Setup cost: matrix mult – Inner loop cost: 1 add David Luebke 7/27/2016 General Polygon Rasterization Now that we can rasterize triangles, what about general polygons? We’ll take an edge-walking approach (why?) David Luebke 7/27/2016 General Polygon Rasterization Consider the following polygon: D B C A E F How do we know whether a given pixel on the scanline is inside or outside the polygon? David Luebke 7/27/2016 General Polygon Rasterization Does it still work? D B H C A G I E F David Luebke 7/27/2016 General Polygon Rasterization Basic idea: use a parity test for each scanline edgeCnt = 0; for each pixel on scanline (l to r) if (oldpixel->newpixel crosses edge) edgeCnt ++; // draw the pixel if edgeCnt odd if (edgeCnt % 2) setPixel(pixel); Why does this work? What assumptions are we making? David Luebke 7/27/2016 Faster Polygon Rasterization How can we optimize the code? for each scanline edgeCnt = 0; for each pixel on scanline (l to r) if (oldpixel->newpixel crosses edge) edgeCnt ++; // draw the pixel if edgeCnt odd if (edgeCnt % 2) setPixel(pixel); Big cost: testing pixels against each edge Solution: active edge table (AET) David Luebke 7/27/2016 Active Edge Table Idea: – Edges intersecting a given scanline are likely to intersect the next scanline – Within a scanline, the order of edge intersections doesn’t change much from scanline to scanline David Luebke 7/27/2016 Active Edge Table Algorithm: – Sort all edges by their minimum y coord – Starting at bottom, add edges with Ymin= 0 to AET – For each scanline: Sort edges in AET by x intersection Walk from left to right, setting pixels by parity rule Increment scanline Retire edges with Ymax < Y Add edges with Ymin > Y Recalculate edge intersections and resort (how?) – Stop when Y > Ymax for last edges David Luebke 7/27/2016 Next Topic: Clipping We’ve been assuming that all primitives (lines, triangles, polygons) lie entirely within the viewport In general, this assumption will not hold: David Luebke 7/27/2016 Clipping Analytically calculating the portions of primitives within the viewport David Luebke 7/27/2016 Why Clip? Bad idea to rasterize outside of framebuffer bounds Also, don’t waste time scan converting pixels outside window David Luebke 7/27/2016 Clipping The naïve approach to clipping lines: for each line segment for each edge of viewport find intersection points pick “nearest” point if anything is left, draw it What do we mean by “nearest”? How can we optimize this? David Luebke 7/27/2016 Trivial Accepts Big optimization: trivial accept/rejects How can we quickly determine whether a line segment is entirely inside the viewport? A: test both endpoints. David Luebke 7/27/2016 Trivial Rejects How can we know a line is outside viewport? A: if both endpoints on wrong side of same edge, can trivially reject line David Luebke 7/27/2016 Cohen-Sutherland Line Clipping Divide viewplane into regions defined by viewport edges Assign each region a 4-bit outcode: David Luebke 1001 1000 1010 0001 0000 0010 0101 0100 0110 7/27/2016 Cohen-Sutherland Line Clipping How do we set the bits in the outcode? How do you suppose we use them? David Luebke 1001 1000 1010 0001 0000 0010 0101 0100 0110 7/27/2016 Cohen-Sutherland Line Clipping Set bits with simple tests x > xmax y < ymin etc. Assign an outcode to each vertex of line – If both outcodes = 0, trivial accept – bitwise AND vertex outcodes together – If result 0, trivial reject David Luebke 7/27/2016 Cohen-Sutherland Line Clipping If line cannot be trivially accepted or rejected, subdivide so that one or both segments can be discarded Pick an edge that the line crosses (how?) Intersect line with edge (how?) Discard portion on wrong side of edge and assign outcode to new vertex Apply trivial accept/reject tests; repeat if necessary – How did the programmer get stuck in the shower? David Luebke 7/27/2016 Cohen-Sutherland Line Clipping Outcode tests and line-edge intersects are quite fast (how fast?) But some lines require multiple iterations (see F&vD figure 3.40) Fundamentally more efficient algorithms: – Cyrus-Beck uses parametric lines – Liang-Barsky optimizes this for upright volumes David Luebke 7/27/2016 Coming Up… We know how to clip a single line segment – How about a polygon in 2D? – How about in 3-D? David Luebke 7/27/2016