Graphics Reference
In-Depth Information
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const float
w = -1.0f / T.vertex(v).z;
vertexW[v] = w;
vertexPw[v] = T.vertex(v)
*
w;
vertexNw[v] = T.normal(v)
*
w;
}
// For each pixel
for
(
int
y = y0; y < y1; ++y) {
for
(
int
x = x0; x < x1; ++x) {
// The pixel center
const
Point2 Q(x + 0.5f, y + 0.5f);
...
}
}
}
}
Listing 15.28: Inner loop of a barycentric (edge align) rasterizer (see
Listing 15.27 for the loop setup).
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
// For each pixel
for
(
int
y = y0; y < y1; ++y) {
for
(
int
x = x0; x < x1; ++x) {
// The pixel center
const
Point2 Q(x + 0.5f, y + 0.5f);
// 2D Barycentric weights
const float
weight2D[3] =
{bary2D(V[0], V[1], V[2], Q),
bary2D(V[1], V[2], V[0], Q),
bary2D(V[2], V[0], V[1], Q)};
if
((weight2D[0]>0) && (weight2D[1]>0) && (weight2D[2]>0)) {
// Interpolate depth
float
w = 0.0f;
for
(
int
v = 0; v < 3; ++v) {
w += weight2D[v]
*
vertexW[v];
}
// Interpolate projective attributes, e.g., P', n'
Point3
Pw;
Vector3
nw;
for
(
int
v = 0; v < 3; ++v) {
Pw += weight2D[v]
*
vertexPw[v];
nw += weight2D[v]
*
vertexNw[v];
}
// Recover interpolated 3D attributes; e.g., P' -> P, n' -> n
const
Point3
&P=Pw/w;
const
Vector3
&n=nw/w;
const float
depth = P.length();
// We could also use depth = z-axis distance: depth = -P.z
// Depth test
if
(depth < depthBuffer.get(x, y)) {
// Shade
Radiance3
L_o;
const
Vector3
& w_o = -P.direction();
// Make the surface normal have unit length
const
Vector3
& unitN = n.direction();