Shading with Scan Conversion�for Pixels
Lecture 15
6.837 Fall 2001
Tong-Yee Lee
Bump Mapping and
Displacement Mapping
Phong Illumination Model
Per line scan conversion
Shading on each pixel
Four Different Shading Methods
Lecture 15
Slide 5
6.837 Fall 2001
Lecture 15
Slide 7
6.837 Fall 2001
Flat Shading
Lecture 15
Slide 8
6.837 Fall 2001
Flat Shading Or Facet Shading
The simplest shading method applies only one illumination calculation for each primitive. This technique is called constant or flat shading. It is often used on polygonal primitives.
Drawbacks:
Nonetheless, often illumination is computed for only a single point on the facet. Which one? Usually the centroid.
OpenGL picks any vertex of a polygon such as the first vertex
Solution: increase the resolutions of polygons
OpenGL: Flat shading
Compute shading at a representative point and apply to whole polygon
OpenGL uses one of the vertices
Advantages:
Fast - one shading value per polygon
Disadvantages:
Inaccurate
Discontinuities at polygon boundaries
Constant Shading with Ambient�Illumination Only
Lecture 15
Slide 12
6.837 Fall 2001
Obvious disadvantage: it looks like a 2D shape
instead of a 3D shape!!
Facet Shading With Diffuse Reflection
Lecture 15
Slide 13
6.837 Fall 2001
Facet Shading
Even when the illumination equation is applied at each point of the faceted nature of the polygonal nature is still apparent.
To overcome this limitation normals are introduced at each vertex.
Some terms in polygons
Lecture 15
Slide 16
6.837 Fall 2001
Try to smooth shading rather than on shape.
So, boundary is still not smooth on shape!
Gouraud Shading
The Gouraud shading method applies the illumination model on a subset of surface points and interpolates the intensity of the remaining points on the surface. In the case of a polygonal mesh the illumination model is usually applied at each vertex and the colors in the triangles interior are linearly interpolated from these vertex values.
The linear interpolation can be accomplished using the plane equation method discussed in the lecture on rasterizing polygons.
Gouraud v.s. Phong shading
Lecture 15
Slide 18
6.837 Fall 2001
Gouraud
Phong
Lecture 15
Slide 19
6.837 Fall 2001
Lecture 15
Slide 20
6.837 Fall 2001
Naïve Barycentric coordinate
/
So, it is very slow……
Simple but its computational cost is expensive
Lecture 15
Slide 21
6.837 Fall 2001
Simple linear
Interpolation
for each pixel
Lecture 15
Slide 22
6.837 Fall 2001
Gourand Shading
Shade each vertex with it’s own location and normal
Linearly interpolate across the face
Advantages:
Fast - incremental calculations when rasterizing
Much smoother - use one normal per shared vertex to get continuity between faces
Disadvantages:
Specularities get lost
No highlights
Highlight is loss
if Gourand shading
is applied
Wrong highlight via simple linear color
Interpolation
(left): wrong interpolation of highlight,
So, the highlight is bigger than
expected!
Gouraud Shading with Diffuse Reflection
Lecture 15
Slide 24
6.837 Fall 2001
Do not average normals
everywhere. Only for the
approximately curve surface
i.e., usually difference <=30 degrees, it can be averaged!
Shading and OpenGL
OpenGL defines two particular shading models
Controls how colors are assigned to pixels
glShadeModel(GL_SMOOTH) interpolates between the colors at the vertices (the default)
glShadeModel(GL_FLAT) uses a constant color across the polygon
GL_SMOOTH by Gouraud shading
GL_FLAT
by Gouraud Shading
Phong Shading
In Phong shading (not to be confused with the Phong illumination model), the surface normal is linearly interpolated across polygonal facets, and the Illumination model is applied at every point.
A Phong shader assumes the same input as a Gouraud shader, which means that it expects a normal for every vertex. The illumination model is applied at every point on the surface being rendered, where the normal at each point is the result of linearly interpolating the vertex normals defined at each vertex of the triangle.
Phong shading will usually result in a very smooth appearance, however, evidence of the polygonal model can usually be seen along silhouettes.
Phong Shading
Lecture 15
Slide 27
6.837 Fall 2001
- compute illumination model for each pixel
So, many parameters need to interpolate
such as 3D point, normal vector etc.
at each pixel. Then, we can use these
information to compute illumination model
If done by Ground
shading, hightlight
is lost (see yellow position)
Lecture 15
Slide 30
6.837 Fall 2001
Example
Only differences in
these teapots are
the parameters
in the Phong model
Phong Shading with Correct Highlight
Slide 33
6.837 Fall 2001
3D shape boundary silhouettes can not be smooth by phong shading
Can be improved by increasing
the quality of triangles etc., i.e.
small triangles
Raytracing using math equation to
describe an object such as sphere
equation!
Gouraud shading
lerp(c1,c2): linear interpolation
Lecture 15
Slide 35
6.837 Fall 2001
Note that:
vi can be either r,g,b, normal
vector, 3D vertex, z (depth)
v1
v2
a
b
Note that:
vi can be either xi,r,g,b, normal
vector, 3D vertex, z (depth)
🡺 change diffuse term by a fixed table value
a fixed table value
Similarly, we can compute (x,y,z) for phong shading and Z (depth) , but do not need to normalize them
i.e.,=1
OpenGL
Zbuffer
0<=Z<=1
1 is maxmum
50
Goal: speedup interpolation by adding 1/m to from current y to
i.e., use linear interpolation
along x direction
i.e., add 1/m to x for xi on yi to xi+1 on yi+1
Scanline Conversion.
Convex
(凸多邊形)
Lecture 15
Slide 52
6.837 Fall 2001
Basic Idea
Note that: a.b is passed by a line => pixel a is red
Concave
(凹多邊形)
Ex:
floor(0.22) = 0�floor(1.22) = 1
ceil(0.22) = 1�ceil(1.22) = 2
ceil(1.0) =1
floor(1.0)=0
Note that: for Y: from ceil (Yi) to floor (Yj), too.
So, if Yi is integer, Yi will not be drawn!
Ceil (x):天花板
=> X 最小整數
Floor(x): 地板
< X 最大整數
54
integer position at ?: belongs to right polygon!
55
56
insert at x
ceil(x)
ceil(1.2)=2
ceil(1.0)=1
Ceil (x):天花板
=> X 最小整數
Floor(x): 地板
< X 最大整數
57
output at x
floor(x)
floor(1.2)=1
floor(1.0)= 0
Ceil (x):天花板
=> X 最小整數
Floor(x): 地板
< X 最大整數
floor(p1)
is not equal
to ceil(p1)
Ex:
floor(3.0) =2.0
ceil(3.0) = 3.0
Note that: for Y: from ceil (Yi) to floor (Yj)
For X: from ceil (Xi) to floor (Xj)
P1: e1’s end
And e2’ start
p1 is at bottom
e1 : p1 is ending point, (i.e. m<0), so do not draw p1 using color at e1
e2 : p1 is starting point, (i.e. m>0),
so draw p1 using color at e2
So, p1 will be drawn only once from e2
P1: for e1, it is an end point (i.e, m<0), ignore it!
: for e2, it is top point. So, it is deleted
P”: it is top point, so it is ignored!
floor(p1) for e2, so it will not include
p1 from e2 but will be included from e1
p1
top
bottom
P1: for e1, it is an end point and m<0, ignore it!
: for e2, it is top point. So, it is deleted
Problem: It does not use top edge to write colors, i.e., lost these colors
It does not use top edge to write colors, i.e., lost these colors
Note that: for Y: from ceil (Yi) to floor (Yj)
For X: from ceil (Xi) to floor (Xj)
Lecture 15
Slide 64
6.837 Fall 2001
Share same vertex but at highest position => So, ignore it!
Delete parallel edge
P1
P2
x = x +1/m
1/m = dx/dy
y_i = mx_i +a;
y_(i+1) = mx_(i+1)+a;
1 = mx_(i+1)-mx_i
1/m=x_(i+1)-x_i
x_(i+1) = x_i + 1/m
(x_i,y_i)
(x_i+1,y_i+1)
y=mx+a
Note: xmin is the x at the minimum y for the edge
ymax
x at when ymin
m>0
m<0
(1) B is at bottom
A--B : B is ending point, m<0, so do not
draw B using color
at AB
B--C : B is starting pint, m>0, so draw B using color at BC
(2) F or D is at top
Omit this by removing it such as F, D
Scan Conversion (Rasterization)
The Algorithm (page 98 in Computer Graphics FvDFH second ed.)
Create an Edge Table for the polygon being rendered, sorted on y.
Don’t include horizontal edges, they are handled by the edges they connect to (see page 95 in text).
68
(FvDFH, pages 92, 98)
Note: xmin is the x at the minimum y for the edge, not necessarily the minimum x of the edge. Hence xmin = 7 for edge AB.
Horizontal and
Vertical edges.
x = x +1/m
1/m = dx/dy, horizontal edge i.e., dy=0
(Ymax,Xcurrent, 1/m)
Each edge’s top Y will be not rendered!!!
So, when y=9. FA and EF will be deleted!!
Scan Conversion (cont.)
Once you have your Edge Table (ET) for the polygon, you’re ready to step through y coordinates and render scan lines:
1. Set y to the first non-empty bucket in the ET. This is bucket 1 in the example.
2. Initialize the Active Edge Table (AET) to be empty. The AET keeps track of which edges cross the current y scan line.
3. Repeat the following until the AET and ET are empty:
3.1 Add to the AET the ET entries for the current y. (edges AB, BC in example)
3.2 Remove from the AET entries where y = ymax. (none at first in example)
Then sort the AET on x. (order: {AB, BC})
3.3 Fill in pixel values on the y scan line using the x coordinates from the AET. Be wary of parity– use the even/odd test to determine whether to fill (see next slide).
3.4 Increment y by 1 (to the next scan line).
3.5 For every non-vertical edge in the AET update x for the new y (calculate the next intersection of the edge with the scan line).
Note: the algorithm in the book (presented here and in course lecture notes) attempts to fix the problems that occur when polygons share an edge, by not rasterizing the top-most row of pixels along an edge.
70
Active Edge Table Example
Example of an AET containing edges {FA, EF, DE, CD} on scan line 8:
71
(FvDFH pages 92, 99)
Current X
Slope
Y val
Y = 9
Y = 8
Active Edge Table Example (cont.)
72
(FvDFH pages 92, 99)
(FvDFH pages 92, 99)
Current X
Slope
Y val
Y = 8
Y = 9
Some problem with average
normals at shared vertex.
In this example, all average N
at each vertex is the same, i.e.
wrong normal vectors!
Solution : with more subdivision
Lecture 15
Slide 74
6.837 Fall 2001
but, P may be rendered
with different colors !!
Ideal rotation result
Maybe it cab be
improved by
by revising it
to smaller triangles
Or find rotation-invariant
Shading method
Illumination, scale and rotation invariant algorithm for vision-based uav navigation, May 2013
International Journal of Pattern Recognition and Artificial Intelligence 27(5):1359003
texture的RGB表示法向量的XYZ,利用此資訊計算光強,產生凹凸陰影的效果。(normal map)
R:x, G:y, B: z, (change color (0,1) to normal vector [-1,1]
i.e., 0.5 -> 0, positive: > 0.5, negative: < 0.5
Lecture 15
Slide 76
6.837 Fall 2001
As we already know, a bump map uses grayscale values to provide either up or down information. A normal map uses RGB information that corresponds directly with the X, Y and Z axis in 3D space. This RGB information tells the 3D application the exact direction of the surface normals are oriented in for each and every polygon. The orientation of the surface normals, often just referred to as normals, tell the 3D application how the polygon should be shaded.
A bump map can be thought of as an older normal map. Bump maps were used before normal maps became a thing. Bump maps are less advanced than normal maps because they can only show the height values (i.e., y value) of a texture (or 3 bump textures for x,y,z), whereas normal maps can show angle as well—which allows them to show detail more realistically.
Bump map – Normal Map
| Image-Credit: Unity
Lecture 15
Slide 77
6.837 Fall 2001
Lecture 15
6.837 Fall 2001
case 2: real surface
case 3: bump map, i.e. normal vector is changed
Lecture 15
6.837 Fall 2001
https://slideplayer.com/slide/14885749/
Lecture 15
Slide 80
6.837 Fall 2001
(a) OpenGL-default Gouraud shading, (b) custom smooth Phong shading, and (c) custom bump shading.
�
Lecture 15
Slide 81
6.837 Fall 2001
Simple method:P1 = P0 + (N * df * uf)
P0是原本頂點的位置、P1是經過displace後頂點的位置、N是model原本的法向量(displace後不變)、uf是自訂尺度、df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z,dv是displacement map的值,由R、G、B轉為灰階。
http://ycpcs.github.io/cs470-fall2014/labs/lab12-2.html
Displacement Map
Lecture 15
Slide 82
6.837 Fall 2001
Bump shading v,s. displacement shading.
Displacement� Map�: change 3D �surface’s �height�along normal�vectors
Lecture 15
Slide 83
6.837 Fall 2001
Lecture 15
Slide 84
6.837 Fall 2001
Bump shading
v.s.
Displacement shading.
Ocean Animation Using OpenGL
Lecture 15
Slide 85
6.837 Fall 2001
在這裡我多加Bump Mapping的效果,來彌補就算Displacement Mapping能改變vertex的位置,但卻無法改變normal的缺點(就算shader會做內插,但內插結果往往跟理想的不一樣)。��此外,Displacement Mapping暴露了一個缺點,就是當model的vertex不多時,得到的效果相當有限。到這裡,vertex和pixel都有運算來改變model的特性,做到相當真實的效果,若還想要再真實一點,還可以加入陰影,用AO(Ambient Occlusion) map來做。�vertex shader程式碼:��
Slide 86
6.837 Fall 2001
原理:
運算:P1 = P0 + (N * df * uf)
P0是原本頂點的位置、P1是經過displace後頂點的位置、N是model原本的法向量(displace後不變)、uf是自訂尺度、df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z,dv是displacement map的值,由R、G、B轉為灰階。
https://cg2010studio.com/2011/10/21/glsl-%E4%BD%8D%E7%A7%BB%E6%98%A0%E5%B0%84-displacement-mapping/�
Lecture 15
Slide 87
6.837 Fall 2001
原理:
運算:P1 = P0 + (N * df * uf)
P0是原本頂點的位置、P1是經過displace後頂點的位置、N是model原本的法向量(displace後不變)、uf是自訂尺度、df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z,dv是displacement map的值,由R、G、B轉為灰階。
Lecture 15
Slide 88
Lecture 15
Slide 89
6.837 Fall 2001
Lecture 15
Slide 90
6.837 Fall 2001
varying vec3 vertex_position;
varying vec3 vertex_light_vector;
varying vec3 vertex_light_half_vector;
varying vec3 vertex_normal;
uniform sampler2D displacement_texture;
void main() {
vec4 newVertexPos;
vec4 dv;
float df;
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
dv = texture2D( displacement_texture, gl_MultiTexCoord0.xy );
df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z;
newVertexPos = vec4(gl_Normal * df * 0.3, 0.0) + gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * newVertexPos;
// Calculate the normal value for this vertex, in world coordinates (multiply by gl_NormalMatrix)
vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
vertex_position = vec3(gl_ModelViewMatrix * newVertexPos);
// Calculate the light position for this vertex
vec3 light_position = gl_LightSource[0].position.xyz;
vertex_light_vector = normalize(light_position.xyz - vertex_position.xyz);
// Calculate the light's half vector
vertex_light_half_vector = normalize(gl_LightSource[0].halfVector.xyz);
Lecture 15
Slide 91
6.837 Fall 2001
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | varying vec3 vertex_position; varying vec3 vertex_light_vector; varying vec3 vertex_light_half_vector; varying vec3 vertex_normal; const vec3 eye_position = vec3(0.0,0.0,0.0);
uniform float updown, leftright, farnear;
uniform sampler2D color_texture; uniform sampler2D normal_texture;
void main() {
// Extract the normal from the normal map vec3 normal = normalize(texture2D(normal_texture, gl_TexCoord[0].st).rgb * 2.0 - 1.0);
// Determine where the light is positioned vec3 light_pos = normalize(vec3(leftright, updown, farnear) + vertex_light_vector);
// Calculate the lighting diffuse value float diffuse = max(dot(normal, light_pos), 0.0);
vec3 E = normalize(vec3(eye_position - vertex_position)); //vec3 R_d = normalize(vec3(reflect(-light_pos, vertex_normal))); vec3 R_n = normalize(vec3(reflect(-light_pos, normal)));
// Defining The Material Colors const vec4 AmbientColor = vec4(0.0, 0.0, 0.0, 1.0); const vec4 DiffuseColor = vec4(0.5, 0.5, 0.5, 1.0); const vec4 SpecularColor = vec4(1.0, 1.0, 1.0, 1.0);
// Calculate the ambient term vec4 ambient_color = AmbientColor * gl_LightSource[0].ambient + gl_LightModel.ambient * gl_FrontMaterial.ambient;
// Calculate the diffuse term vec4 diffuse_color = DiffuseColor * gl_LightSource[0].diffuse; // Set the diffuse value (darkness). This is done with a dot product between the normal and the light // and the maths behind it is explained in the maths section of the site. float diffuse_value = max(dot(normalize(vertex_normal), vertex_light_vector), 0.0);
// Calculate the specular value //vec4 specular_color_d = SpecularColor * gl_LightSource[0].specular * pow(max(dot(E, R_d), 0.0) , 100.0); vec4 specular_color_n = SpecularColor * gl_LightSource[0].specular * pow(max(dot(E, R_n), 0.0) , 100.0);
vec3 color = diffuse_value * texture2D(color_texture, gl_TexCoord[0].st).rgb + specular_color_n;
// Set the output color of our current pixel gl_FragColor = vec4(color, 1.0); } |