16
1 From Ver(ces to Fragments: Rasteriza(on determine fragments to be covered interpolate attributes per fragment From Ver(ces to Fragments vertex shader 2D screen fragment shader final pixels rasterizer fragments 3D vertices

From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

1

From  Ver(ces  to  Fragments:    

Rasteriza(on    

l  determine fragments to be covered l  interpolate attributes per fragment

From  Ver(ces  to  Fragments  

vertex shader

2D screen

fragment shader

final pixels rasterizer

fragments

3D vertices

Page 2: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

2

•  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

Rasteriza(on  

This  Lecture  •  Line-drawing algorithm

– Naïve algorithm – Bresenham algorithm

Page 3: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

3

Scan  Conver(ng  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  Rasteriza(on  Requirements  •  Transform continuous primitive into discrete samples

•  Uniform thickness & brightness •  Continuous appearance •  No gaps •  Accuracy •  Speed

(x1, y1)

(x2, y2)

Page 4: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

4

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  Rasteriza(on  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!!!

Page 5: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

5

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  Rasteriza(on  

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 <= x2; x++) { PlotPixel(x, Round(y)); y = y + slope; } }

One floating point operation per pixel !!!

Round is expensive!!!

Page 6: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

6

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.

Page 7: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

7

BeHer:  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)

ENE

P

Page 8: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

8

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

Page 9: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

9

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

Page 10: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

10

Bresenham  with  no  Floa(ng  Point  •  Error function e(x, y) = mx+h-y, •  At selected pixel (x, y): e(x, y) <= ½ •  Simplify:

2·e(x, y) – 1 <= 0 2mx + 2h – 2y – 1 <= 0

2x·dy + 2h·dx – 2y·dx – dx <= 0 (Note that h·dx = y1·dx – x1·dy is an integer)

•  Define F(x,y) = 2x·dy + 2h·dx – 2y·dx – dx –  If F <= 0 stay horizontal –  If F > 0 move up

ENE

dxdy

xxyym =

−=

12

12

Bresenham  with  no  Floa(ng  Point  •  Define

F(x, y) = 2x·dy + 2h·dx – 2y·dx – dx

–  If F <= 0 stay horizontal –  If F > 0 move up

•  Incremental update for next pixel: –  If stay horizontal: x+=1, F += 2dy –  If move up: x+=1, y+=1, F += 2(dy –dx)

ENE

Page 11: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

11

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 <= x2; x++) { if(f <= 0) f += 2*dy; else { f += 2*(dy-dx); y++; } PlotPixel(x, y); } }

Algorithm = single instruction on graphics chips!

2D  Scan  Conversion  •  Geometric primitive

– 2D: point, line, polygon, circle... – 3D: point, line, polyhedron, sphere...

•  Primitives are continuous; screen is discrete

Page 12: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

12

Use  Line  Rasteriza(on  •  Compute the boundary pixels

Scan-­‐line  Rasteriza(on  •  Compute the boundary pixels •  Fill the spans

Page 13: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

13

Next:  •  Anti-Aliasing

Effects  of  An(-­‐aliasing  

Page 14: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

14

Addi(onal  Benefit  of  An(-­‐aliasing  •  Note: brightness can vary with slope

– What is the maximum variation? •  Compensate for this with antialiasing

√2 * L

L

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)

Page 15: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

15

Super-­‐Sampling  

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

How  do  we  remove  aliasing?  •  Super-sampling is expensive

– Render internally at higher resolution –  Invoke fragment shader once per sub-fragment – Down-sample to fit the screen resolution

•  Solution 2: Multi-Sampling – Faster alternative to super-sampling –  Invoke fragment shader once per fragment

Page 16: From%Ver(ces%to%Fragments:% Rasteriza(on%%mdamian/Past/csc8470sp15/notes/Rasterization.pdf(x 2, y 2) m= y 2 −y 1 x 2 −x 1 h=y 1 −mx 1 DDARasteriza(on%Algorithm% • Simply compute

16

OpenGL  

glfwWindowHint(GLFW_SAMPLES, 4);!glEnable(GL_MULTISAMPLING);!

•  On most OpenGL drivers, multisampling is enabled by default so this call is then a bit redundant, but it's usually a good idea to enable it anyways