设
a
(
x
1
,
y
1
)
,
b
(
x
2
,
y
2
)
a(x_1,y_1),b(x_2,y_2)
a(x1,y1),b(x2,y2),叉乘:
a
⋅
b
=
x
1
y
2
−
x
2
y
1
a\cdot b=x_1y_2-x_2y_1
a⋅b=x1y2−x2y1
实现叉乘,代码意思对即可
static bool insideTriangle(int x, int y, const Vector3f* _v)
{
Vector3f v[3];
for(int i=0;i<3;i++)
v[i] = {_v[i].x(),_v[i].y(), 1.0};
Vector3f f0,f1,f2;
f0 = v[1].cross(v[0]);
f1 = v[2].cross(v[1]);
f2 = v[0].cross(v[2]);
Vector3f p(x,y,1.);
return (p.dot(f0)*f0.dot(v[2])>0) && (p.dot(f1)*f1.dot(v[0])>0) && (p.dot(f2)*f2.dot(v[1])>0);
}
利用三角形的顶点求 BoundingBox,即xmin,xmax,ymin,ymax。剩余部分按部就班实现即可,注意看Rasterizer类中有什么函数和变量。
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();
float xmin = std::min(t.v[0].x(), std::min(t.v[1].x(), t.v[2].x()));
float xmax = std::max(t.v[0].x(), std::max(t.v[1].x(), t.v[2].x()));
float ymin = std::min(t.v[0].y(), std::min(t.v[1].y(), t.v[2].y()));
float ymax = std::max(t.v[0].y(), std::max(t.v[1].y(), t.v[2].y()));
for(int x = (int)std::ceil(xmin); x <= xmax; x++){
for(int y = (int)std::ceil(ymin); y <= ymax; y++){
if(!insideTriangle(x, y, t.v)) continue;
auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
z_interpolated *= w_reciprocal;
if(z_interpolated < depth_buf[get_index(x, y)]){
depth_buf[get_index(x, y)] = z_interpolated;
Vector3f v(x, y, 0);
set_pixel(v, t.getColor());
}
}
}
}
采样懒得实现了,原理懂就行