Ana içeriğe geç

Bölüm 12: Odak Bulanıklığı (Alan Derinliği)

Fotoğrafçılıkta ve sinemada en çok sevilen görsel tekniklerden biri Alan Derinliğidir (Depth of Field / Bokeh). Ana karakter veya nesne jilet gibi netken, arka plandaki ve ön plandaki detaylar sanatsal bir şekilde bulanıklaşır.

Şu ana kadar kullandığımız kamera bir İğne Deliği (Pinhole) kameraydı; sonsuz netliğe sahipti çünkü tüm ışınlar tek bir noktadan (center) çıkıyordu.

Gerçek fotoğraf makinelerinde ise merceğin (diyaframın) belirli bir fiziksel boyutu vardır.


İnce Mercek Yaklaşımı (A Thin Lens Approximation)

Gerçek bir fotoğraf makinesinde odak düzlemindeki (focus_dist) nesneler film sensöründe tek bir noktaya odaklanırken; odak düzleminin önündeki veya arkasındaki nesneler geniş bir disk şeklinde yayılarak bulanıklaşır:

İnce Mercek Modeli Odak Düzlemi ve Film

Bunu simüle etmek için ışınlarımızı tek bir center noktasından değil, kameranın etrafında küçük bir odak diski (defocus disk) içindeki rastgele noktalardan fırlatırız!

Odak diskinden çıkan tüm bu ışınlar, odak düzlemi (focus_dist) üzerindeki aynı hedef noktada birleşir. Dolayısıyla odak düzlemindeki nesneler jilet gibi net kalırken, önündeki veya arkasındaki nesneler farklı ışın açıları yüzünden bulanıklaşır!


Odak Diski İçinde Rastgele Nokta Seçimi

vec3.h dosyamıza birim daire içinde 2B rastgele nokta üreten fonksiyonumuzu ekleyelim:

vec3.h (Odak Diski Yardımcısı)
1
2
3
4
5
6
7
inline vec3 random_in_unit_disk() {
    while (true) {
        auto p = vec3(random_double(-1,1), random_double(-1,1), 0);
        if (p.length_squared() < 1)
            return p;
    }
}

Kameraya Alan Derinliği Eklenmesi

Kameramıza iki yeni ayar ekleyelim: - defocus_angle: Işınların mercekten çıkış koni açısı. \(0\) ise mükemmel iğne deliği kamera (sıfır bulanıklık); değer büyüdükçe bulanıklık artar. - focus_dist: Tam olarak net olmasını istediğimiz düzlemin kameraya olan uzaklığı.

camera.h (Defocus Blur Entegrasyonu)
class camera {
  public:
    // ...
    double defocus_angle = 0;   // Bulanıklık koni açısı
    double focus_dist = 10;     // Netleme mesafesi

  private:
    vec3   defocus_disk_u;      // Yatay odak diski yarıçap vektörü
    vec3   defocus_disk_v;      // Dikey odak diski yarıçap vektörü

    void initialize() {
        // ...
        // Odak düzlemindeki viewport boyutları
        auto viewport_height = 2 * h * focus_dist;
        auto viewport_width = viewport_height * (double(image_width)/image_height);

        // ...
        // Odak diski boyutları
        auto defocus_radius = focus_dist * std::tan(degrees_to_radians(defocus_angle / 2));
        defocus_disk_u = u * defocus_radius;
        defocus_disk_v = v * defocus_radius;
    }

    ray get_ray(int i, int j) const {
        auto offset = sample_square();
        auto pixel_sample = pixel00_loc
                          + ((i + offset.x()) * pixel_delta_u)
                          + ((j + offset.y()) * pixel_delta_v);

        auto ray_origin = (defocus_angle <= 0) ? center : defocus_disk_sample();
        auto ray_direction = pixel_sample - ray_origin;

        return ray(ray_origin, ray_direction);
    }

    point3 defocus_disk_sample() const {
        auto p = random_in_unit_disk();
        return center + (p[0] * defocus_disk_u) + (p[1] * defocus_disk_v);
    }
};

Alan Derinliği Test Renderı

Merkezdeki küreye odaklanıp defocus_angle = 10.0 verdiğimizde:

Alan Derinliği Renderı

Öndeki ve arkadaki nesnelerin nasıl yumuşacık bulanıklaştığına, merkezdeki kürenin ise nasıl kristal netliğinde kaldığına bakın!

Artık ışın izleyicimiz profesyonel bir sinema kamerası optiğine sahip. Şimdi son bölüme geçerek kitabın efsanevi kapak sahnesini inşa edelim!