三角形ラスタライゼーションと深度バッファの実装

実装目標

  1. 三角形ラスタライゼーションアルゴリズムの正確な実装
  2. 点の三角形内外判定テストの実装
  3. 深度バッファを用いた三角形の正順描画

三角形ラスタライゼーション処理

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グリッド)によるアンチエイリアスが有効です。各サンプルポイントで深度値を個別に管理する必要があり、処理負荷が増加することに留意してください。

タグ: ラスタライゼーション 深度バッファ 三角形描画 グラフィックスパイプライン

5月15日 19:26 投稿