Joshua Barczak CMSC 435 UMBC Clipping Joshua Barczak CMSC 435 UMBC
Object-Order Rendering We are here Object-Space Primitives World-space Primitives Camera-Space Primitives Clip-Space Primitives Clip Modeling XForm Viewing XForm Projection XForm Clip-Space Primitives Rasterize Window XForm Viewport XForm Displayed Pixels Pixels Raster-Space Primitives
Viewing Transform The job of the viewing transform is: Get us from these axes Onto these axes
Projection Transform The job of the projection transform is: Cram the visible universe into a unit box Project
Canonical View Volume (GL) (-1,1,1) (1,1,1) Top Edge of Screen (0,1,-1) Center of screen Left Edge of Screen (0,0,-1) (-1,0,-1) (1,0,-1) (1,-1,1) Points outside the cube are not visible… (1,-1,-1) (0,-1,-1) D3D uses z=0. I like theirs better… Bottom Edge of Screen
Primitive States Invisible Partially Visible Visible Our Reaction: Trivial Reject: Throw it away, it does not exist… Remove the parts that do not exist… Trivial Accept: Pass it through
Definitions Culling: Clipping Discarding invisible primitives Removing invisible parts of primitives
Basic Idea For each primitive: Transform to C.V.V. (clip space) Cull test: Is it completely outside? Trivial Reject Else: Is it completely inside? Trivial Accept Else Clip it
Why do we do this? Culling Clipping Efficiency Simplicity of rasterization No boundary cases Efficiency of rasterization Skip invisible pixels Stability of rasterization Precision
Line Clipping Turns lines into other lines
Line Clipping(3D) Same thing, but edges are planes now… Same algorithms, different math 2D is easier to draw…
Line Clipping Point is in clip box if: xmax,ymax xmin,ymin
Line Clipping Endpoints in box?? Both endpoints inside Trivial accept One endpoint inside Will clip Both endpoints outside Don’t know yet…??
Line Clipping Region Check? Trivial reject if both endpoints outside the same boundary… max(x0,x1) <= xmin min(x0,x1) >= xmax min(y0,y1) <= ymin max(y0,y1) >= ymax
Cohen-Sutherland Line Clipping Each region assigned a 4-bit code (outcode) 1st bit – above top y > ymax 2nd bit – below bottom y < ymin 3rd bit – right of right x > xmax 4th bit – left of left x < xmin
Cohen-Sutherland Line Clipping Efficient bitcode calculation: First bit is the sign bit of ymax – y Second bit is y – ymin Third bit is the sign bit of xmax – x Forth bit is x – xmin
Cohen-Sutherland Line Clipping Trivial accept if both endpoints zero code1|code2 ==0 Trivial reject if both endpoints ‘outside’ same edge code1 & code2 != 0 Otherwise, need to split the line
Cohen-Sutherland Line Clipping code1 = outcode from endpoint1 code2 = outcode from endpoint2 if (code1 | code2 == 0) then trivial_accept else if (code1 & code2 != 0) then trivial_reject else clip against left clip against right clip against bottom clip against top if (anything is left) then accept clipped segment
Cohen-Sutherland Line Clipping Clipping to an edge: If one endpoint sticks out, move it in Move one coordinate Re-compute the other At most one point is outside, due to region check
Cohen-Sutherland Line Clipping Update and re-check outcodes after clipping… Needs clip Trivial Reject
Liang-Barsky Line Clipping First: Trivial Reject based on AABB: NOT < or >. This is important…
Liang-Barsky Line Clipping Optional: Trivial Accept based on AABB:
Liang-Barsky Line Clipping T=1 Next: Ray-box intersection tymax txmax tymin T=0 txmin …Reject if t0 >= t1
Liang-Barsky Line Clipping The divides are fine. Don’t panic… We know that: xmin xmax y0 y1 … or the trivial reject test passes IEEE rules handle division of non-zero by zero Nans are evil, but infinities are not…
Triangle Culling Trivial cases All vertices outside same box edge All vertices inside box Box corners outside triangle edge
Triangle Culling The edge test is 3 point-line tests (not 12) Choose corner based on edge normal: Nx > 0 ? xmin : xmax Ny > 0 ? ymin : ymax
Need to factor these into all your tests… Triangle Culling Nasty edge cases Edge in plane Vert in plane Entire triangle in plane Need to factor these into all your tests…
Triangle Clipping General case… There will be two vertices on one side, one on the other side
Triangle Clipping General case… Compute edge/plane intersection locations Two line clips…
Triangle Clipping General case… If “the one” is inside, keep the triangle
Triangle Clipping General case… If “the one” is outside, create two triangles Pass both to subsequent clip tests Gets expensive very quickly…
Triangle Clipping: Example
Triangle Clipping: Example
Triangle Clipping: Example
Triangle Clipping: Example
Triangle Clipping: Example
Guard Bands Add padding to turn clips into trivial reject/accept Small triangles less likely to need clipping Which is good, because they’re more numerous Guard band Viewport
Sutherland-Hodgeman Polygon Clipping For each edge, walk along vertex loop Add 0, 1, or 2 vertices to output
Sutherland-Hodgman Polygon Clipping At each step, 1 of 4 possible cases arises 1) Edge is completely inside clip boundary, so add vertex p to the output list 2) Intersection i is output as vertex because it intersects with boundary 3) Both vertices are outside boundary, so neither is output 4) Intersection i and vertex p both added to output list 39 39
Homogeneous Clipping The projection transform does strange and wonderful things… Recall: For perspective projection, typically w’=z
Homogeneous Clipping The following hold for all points in the view frustum Assuming sane view/projection matrices OpenGL spec is undefined for w<0
Projection Matrix Behavior Near plane Far plane Eye z=w w=0 z=-w
Homogeneous Clipping Can clip/cull to w planes on each axis, prior to division Avoids division for culled primitives But wait, it gets weirder…! w x=-w x=w -x x
Homogeneous Clipping Blinn, 1978 Curiouser and curiouser…
Homogeneous Clipping Motion of projected point, from P1 to P2 Blinn, 1978 P2 is behind the eye….
Homogeneous Clipping Tooo Infinity! And beyond! Blinn, 1978
Homogeneous Clipping This happens for triangles too… Olano and Greer
Homogeneous Clipping This is what we want… w x=-w x=w w=1 -x x
Homogeneous Clipping …but this is what we’ll get… w x=-w x=w w=1 -x x
Homogeneous Clipping …and this is what the user will think they saw… w x=-w x=w w=1 -x x
Homogeneous Clipping Worse yet… Invisible segments magically become visible… w x=-w x=w w=1 -x x
Why do we do this? Culling Clipping Efficiency Simplicity of rasterization No boundary cases Efficiency of rasterization Skip invisible pixels Stability of rasterization Precision All of these are reasons we might want to clip. But…
The Real Reason We Clip: Correct perspective for points behind the eye If you project without clipping, you will draw the wrong line! You cannot detect this post-projection w x=-w x=w w=1 -x x Blue and red lines have same projected endpoints
Homogeneous Clipping Without clip (WRONG) w x=-w x=w w=1 -x x
Homogeneous Clipping Trivial Reject cases: w x=-w x=w w=1 Outside x=w Outside Both
Homogeneous Clipping Replace x=xmin/xmax with x=+/-w Ditto for y and z Use clipped ‘w’ values in subsequent tests w x=-w x=w w=1 -x x
Homogeneous Clipping w x=-w x=w w=1 -x x