recall: graphics rendering pipelinemdamian/past/graphicssp13/notes/... · 2013. 8. 5. · better:...
TRANSCRIPT
-
1
From Ver(ces to Fragments: Rasteriza(on
Recall: Graphics Rendering Pipeline
Application Geometry Rasterizer
3D scene input
2D image
output CPU GPU
-
2
Rendering Pipeline – Application
• Executed on the CPU – The programmer decides what happens here
• Examples: – Collision detection – Speed-up techniques – Animation
• Most important task: – send rendering primitives (e.g. triangles) to the GPU
Application Geometry Rasterizer Image
output CPU GPU
Rendering Pipeline – Geometry
Application Geometry Rasterizer Image
output
• The geometry stage does per-vertex operations: – Move objects (matrix multiplication) – Move the camera (matrix multiplication) – Compute lighting at vertices of triangle – Project onto screen (3D to 2D)
CPU GPU
-
3
Rendering Pipeline – Rasterizer
Application Geometry Rasterizer Image
output
• The rasterizer stage does per-pixel operations: – Turn geometry into visible pixels on screen – Add textures – Resolve visibility (Z-buffer)
CPU GPU
From Geometry to Display
-
4
• How to draw primitives? – Convert from geometric definition to pixels – Rasterization = selecting the pixels
• Will be done frequently • Must be fast:
• use integer arithmetic • use addition instead of multiplication
Rasterization
This Lecture • Line-drawing algorithm
– Naïve algorithm – Bresenham algorithm
• Circle-drawing algorithm – Naïve algorithm – Bresenham algorithm
-
5
Scan Converting 2D Line Segments • Given:
– Segment endpoints (integers x1, y1; x2, y2) • Identify:
– Set of pixels (x, y) to display for segment
(x1, y1)
(x2, y2)
Line Rasterization Requirements • Transform continuous primitive into
discrete samples • Uniform thickness & brightness • Continuous appearance • No gaps • Accuracy • Speed
(x1, y1)
(x2, y2)
-
6
Simple Line • Slope-intercept equation of a line: y = mx + h
• Given (x1, y1) and (x2, y2):
• Naïve line approach: - increment x, solve for y - known as DDA (Digital Differential Analyzer)
h
(x1, y1)
(x2, y2)
m = y2 − y1x2 − x1
h = y1 −mx1
DDA Rasterization Algorithm • Simply compute y as a function of x
– Move vertical scan line from x1 to x2 – Determine y in terms of x – Set pixel (x, Round (y))
x
y
(x1, y1)
(x2, y2)
y = y1+m(x − x1)
m = dydx
=y2 − y1x2 − x1
Two floating point operations per pixel !!!
Round is expensive!!!
-
7
Efficiency • Computing y value is expensive
• Observe: y += m at each x step (m = dy/dx) )1(1 xxmyy −+=
y(x+1)
y(x)x x+1
m
x
y(x)
(x1, y1)
(x2, y2)
y(x+1)
x+1
DDA Line Rasterization
x
y(x)
(x1, y1)
(x2, y2)
y(x+1)
x+1
y(x+1)
y(x)x x+1
m
Line(x1,y1,x2,y2) { float slope, y; slope = (y2-y1)/(x2-x1); y = y1; for(x = x1; x
-
8
Example
)2,0(
(6, 4)
m = 4−26−0 = 13
x = 0 y = 2 x = 1 y = 7/3 x = 2 y = 8/3 x = 3 y = 3 x = 4 y = 10/3 x = 5 y = 11/3
Does it Work?
• OK for lines with a slope of 1 or less
• NOT ok for lines with slope greater than 1: – lines become more
discontinuous in appearance – must add more than 1 pixel per
column to make it work.
• Solution? - use symmetry.
-
9
Better: Bresenham's Line Algorithm • Select pixel vertically closest to line segment
– intuitive, efficient, pixel center always within 0.5 vertically
• Same result as the DDA approach
Incremental Algorithm: - current value uses previous value - integer operations only
Bresenham's Algorithm • Observation:
– If we're at pixel P(x, y), the next pixel must be either E (x+1, y) or NE (x+1, y+1)
– Why?
ENE
P
-
10
Bresenham Step • Which pixel to choose: E or NE? • Error associated with a pixel:
Error pixel NE
Error pixel E E
N E
• Pick the pixel with error < ½ • The sum of the 2 errors is _____
Bresenham Step • How to compute the error? • Line defined as y = mx + h • Vertical distance from line to pixel (x, y):
e(x, y) = mx+h-y – negative if pixel above L – zero on L – positive below L
e is called the error function.
e > 0
e < 0 e = 0
L
-
11
Bresenham's Algorithm • How to compute the error? • Error Function:
e(x, y) = mx+h-y • Initially
e(x1, y1) = 0 • On each iteration:
update x: update e: if (e ≤ 0.5): if (e > 0.5):
x' = x +1 e' = e + m y' = y (choose pixel E) y' = y +1 (choose pixel NE) e' = e - 1
e
e’
Summary of Bresenham • Initialize e = 0 • for (x = x1; x ≤ x2; x++)
– plot (x,y) – update x, y, e
• Generalize to handle all eight octants using symmetry • Still using floating point! e' = e + m • Can we use only integer arithmetic?
ENE
-
12
Bresenham with no Floating Point • Error function e(x, y) = mx+h-y, • At selected pixel (x, y): e(x, y)
-
13
Bresenham Line Pseudocode BresenhamLine(x1,y1,x2,y2) { int dx = x2 – x1; int dy = y2 – y1; int f = -dx; int y = y1; for(x = x1; x
-
14
(x, y)
(y, x)
(y, -x)
(x, -y) (-x, -y)
(-y, -x)
(-y, x)
(-x, y)
2R
Circle Rasterization • Analog of Bresenham’s Line Algorithm • A circle has an 8-way symmetry • Generate pixels for 2nd octant
Circle Rasterization: Naïve algorithm • Circle equation: x2+y2-R2 = 0 • Simple algorithm:
for x = xmin to xmax
y = sqrt(R*R - x*x)
draw pixel(x,y)
• Work by octants and use symmetry
-
15
Circle Rasterization: Bresenham • Choice between two
pixels, E and SE • Mid-point algorithm:
– If the midpoint between pixels is inside the circle, E is closer, draw E
– If the midpoint is outside, SE is closer, draw SE
R
+ + + + E
SE
Circle Rasterization: Bresenham • In/Out decision function
e(x, y) = x2 + y2 – R2
• Point inside circle: e(x, y) < 0
If the last pixel drawn is (x,y), then E = (x+1, y), and SE = (x+1, y-1). Hence, the midpoint = (x+1, y-1/2). e = (x+1)2 + (y - 1/2)2 - R2 e < 0: draw E e ≥ 0: draw SE
R
+ + + + E
SE
-
16
Circle Rasterization: Bresenham • Update error:
• Incremental on each iteration: update x: update e: if (e < 0): if (e ≥ 0):
• Two multiplications, two additions per pixel • Can you do better?
x' = x + 1 e' = e + 2x + 3 y' = y (choose E) y' = y - 1 (choose SE), e' = e'-2y+2
e' = (x+2)2 + (y - 1/2)2 – R2 (if E)
R
+ + + + E
SE
e' = (x+2)2 + (y - 3/2)2 – R2 (if SE)
Circle Rasterization: Better Bresenham • On each iteration:
update x: update e: if (e < 0): if (e ≥ 0):
• The error is not linear • However, what gets added to the error is linear • Keep Δx and Δy. At each step:
Δx += 2, Δy += 2 e += Δx, and if y gets decremented, e += Δy
• 4 additions per pixel
x' = x + 1 e' = e + 2x + 3 y' = y (choose E) y' = y - 1 (choose SE), e' = e'-2y+2
-
17
Bresenham Circle Pseudocode BresenhamCircle(x0,y0,r) { int dx = 3; int dy = -2*r+2; int e = 5/4-r; int y = r; for(x = 0; x = 0){ e += dy; dy +=2; y -= 1;
} e += dx; dx += 2;
} }
/* floating point! */
Circle Rasterization: Better Bresenham • For integer additions only: multiply by 4 • Initial values: Δx = 4*3, Δy = 4*(2-2*r), e = 5-4*r • At each step:
update x: update e: if (e < 0): if (e ≥ 0):
update Δx: update Δy:
• 4 integer additions per pixel
x' = x + 1 e' = e + Δx y' = y (choose E) y' = y - 1 (choose SE), e' = e'+Δy Δx += 8 Δy += 8
-
18
Extensions to Other Functions • Midpoint algorithm easy to extend to any curve
defined by: f(x,y) = 0
2D Scan Conversion • Geometric primitive
– 2D: point, line, polygon, circle... – 3D: point, line, polyhedron, sphere...
• Primitives are continuous; screen is discrete
-
19
Use line rasterization • Compute the boundary pixels
Scan-line Rasterization • Compute the boundary pixels • Fill the spans • Requires some initial setup to prepare
-
20
Next: • Anti-Aliasing
Effect of Anti-Aliasing
-
21
Line Anti-aliasing
Additional Benefit of Anti-aliasing • Note: brightness can vary with slope
– What is the maximum variation? • Compensate for this with antialiasing
√2 * L
L
-
22
How do we remove aliasing? • Solution 1 – Super Sampling:
– Divide pixel into “sub-pixels”: 2x 2, 3x3, 4x4, etc. – Pixel color is the average of its sub-pixel colors
Pixels Pixel Subdivision (4x4)
Super Sampling a Zero-Width Line
Pixel Subdivision
Bresenham at sub-pixel level
Each pixel can have a maximum of 4 colored sub-pixels
How many sub-pixels are colored?
0 0 0 4
2 4 4 0
2 0 0 0 Assign color
Fraction line color for the pixel
0.0 0.0 0.0 1.0
0.5 1.0 1.0 0.0
0.5 0.0 0.0 0.0
-
23
How do we remove aliasing? • Solution 2 - Area Sampling:
– Treat line as a single-pixel wide rectangle – Color pixels according to the percentage of each pixel
that is “covered” by the rectangle
OpenGL Antialiasing • Can enable separately for points, lines, or polygons • For points and lines:
• For triangles:
glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);