実装目標
- 三角形ラスタライゼーションアルゴリズムの正確な実装
- 点の三角形内外判定テストの実装
- 深度バッファを用いた三角形の正順描画
三角形ラスタライゼーション処理
void Rasterizer::drawTriangle(const Triangle& polygon) {
auto vertices = polygon.getVertices();
int min_x = std::floor(std::min({vertices[0].x(), vertices[1].x(), vertices[2].x()}));
int max_x = std::ceil(std::max({vertices[0].x(), vertices[1].x(), vertices[2].x()}));
int min_y = std::floor(std::min({vertices[0].y(), vertices[1].y(), vertices[2].y()}));
int max_y = std::ceil(std::max({vertices[0].y(), vertices[1].y(), vertices[2].y()}));
for (int x = min_x; x < max_x; x++) {
for (int y = min_y; y < max_y; y++) {
if (pointInTriangle(x + 0.5f, y + 0.5f, vertices)) {
auto coords = calculateBarycentric(x, y, vertices);
float depth = interpolateDepth(coords, vertices);
if (depthBuffer[getPixelIndex(x, y)] > depth) {
depthBuffer[getPixelIndex(x, y)] = depth;
setFragmentColor(x, y, polygon.getColor());
}
}
}
}
}
三角形内外判定処理
float edgeFunction(const Vector3f& a, const Vector3f& b, const Vector3f& p) {
return (b.x() - a.x()) * (p.y() - a.y()) - (b.y() - a.y()) * (p.x() - a.x());
}
bool pointInTriangle(float px, float py, const std::array<Vector3f, 3>& verts) {
Vector3f point(px, py, 1.0f);
float crossProducts[3];
for (int i = 0; i < 3; i++) {
crossProducts[i] = edgeFunction(verts[i], verts[(i+1)%3], point);
}
return (crossProducts[0] > 0 && crossProducts[1] > 0 && crossProducts[2] > 0) ||
(crossProducts[0] < 0 && crossProducts[1] < 0 && crossProducts[2] < 0);
}
描画結果と注意点
三角形のエッジにジャギーが確認できる場合、ピクセル単位のサブサンプリング(例:2×2グリッド)によるアンチエイリアスが有効です。各サンプルポイントで深度値を個別に管理する必要があり、処理負荷が増加することに留意してください。