Bölüm 4: Sahneye Küre Ekleme
Bir ışın izleyici (ray tracer) yazarken sahneye ekleyeceğimiz ilk nesne geleneksel olarak küredir (sphere). Bunun sebebi analitik geometride bir ışının küreyle kesişip kesişmediğini hesaplamanın hem çok kolay olması, hem de temiz bir cebirsel çözüme sahip olmasıdır.
Işın-Küre Kesişimi Matematiği
Analitik geometride, merkezi \((C_x, C_y, C_z)\) noktasında ve yarıçapı \(r\) olan bir kürenin yüzeyindeki herhangi bir \((x, y, z)\) noktası şu denklemi sağlar:
Eğer bir nokta kürenin içindeyse, bu ifadenin değeri \(r^2\)'den küçüktür; eğer dışındaysa, \(r^2\)'den büyüktür; tam yüzeyindeyse \(r^2\)'ye eşittir.
Bu ifadeyi vektör cebiriyle çok daha zarif bir şekilde yazabiliriz. Küre üzerindeki herhangi bir noktayı \(\mathbf{P} = (x, y, z)\) ve kürenin merkezini \(\mathbf{C} = (C_x, C_y, C_z)\) vektörleri olarak tanımlarsak, \(\mathbf{C}\) noktasından \(\mathbf{P}\) noktasına giden vektör \((\mathbf{P} - \mathbf{C})\) olur.
Bir vektörün kendisiyle nokta çarpımı (dot product), boyunun karesine eşittir:
Dolayısıyla küre denklemimiz tek satırda şuna dönüşür:
Bu denklemi şöyle okuyabiliriz: "Merkeze (\(\mathbf{C}\)) olan uzaklığının karesi \(r^2\) olan tüm \(\mathbf{P}\) noktaları kürenin yüzeyindedir."

Işın Denklemini Küre Denklemine Yerleştirmek
Bizim bir ışınımız var: Başlangıç noktası \(\mathbf{Q}\) (origin), doğrultusu \(\mathbf{d}\) (direction) olan ve parametresi \(t\) olan doğru:
Sorumuz şudur: "Işın üzerinde öyle bir \(t\) parametresi var mıdır ki, o noktadaki \(\mathbf{P}(t)\), aynı zamanda kürenin denklemini de sağlasın?"
Bunu bulmak için \(\mathbf{P}(t)\) ifadesini küre denklemindeki \(\mathbf{P}\) yerine koyarız:
Burada vektör çıkarma işleminin yerini değiştirip terimleri gruplayalım:
Nokta çarpımının dağılma özelliğini kullanarak parantezleri açalım:
\(r^2\) terimini sol tarafa alıp sıfıra eşitleyelim:
Dikkatle bakın: Bu denklemde \(t\) bilinmeyen bir skaler sayıdır; \(\mathbf{d}\), \(\mathbf{Q}\), \(\mathbf{C}\) ve \(r\) ise bizim bildiğimiz sabit değerlerdir!
Bu tam olarak lise matematiğinden bildiğimiz ikinci dereceden (kuadratik) denklemdir:
Burada katsayılar şunlardır: - \(a = \mathbf{d} \cdot \mathbf{d}\) - \(b = 2 \mathbf{d} \cdot (\mathbf{Q} - \mathbf{C})\) - \(c = (\mathbf{Q} - \mathbf{C}) \cdot (\mathbf{Q} - \mathbf{C}) - r^2\)
Diskriminant (\(\Delta\)) ve Köklerin Anlamı
Kuadratik bir denklemde çözümlerin sayısı Diskriminant ile belirlenir:
- \(\Delta < 0\) (Negatif): Gerçel kök yoktur. Işın küreyi tamamen ıskalar, boşluktan geçer.
- \(\Delta = 0\) (Sıfır): Tek bir gerçel kök vardır. Işın kürenin yüzeyine tam olarak teğet geçer.
- \(\Delta > 0\) (Pozitif): İki gerçel kök (\(t_1\) ve \(t_2\)) vardır. Işın kürenin ön yüzeyinden içeri girer (\(t_1\)) ve arka yüzeyinden dışarı çıkar (\(t_2\)).
Çözüm kökleri genel kuadratik formülle bulunur:
Biz kameraya en yakın olan çarpışma noktasını görmek istediğimiz için genellikle küçük olan pozitif kökü (\(t = \frac{-b - \sqrt{\Delta}}{2a}\)) seçeriz.
İlk Kesişim Testi Kodu
Şimdilik sadece ışının küreye çarpıp çarpmadığını test eden basit bir fonksiyon yazalım:
| hit_sphere Fonksiyonu | |
|---|---|
Not: Kodda
ocvektörünü(center - r.origin())yani \((\mathbf{C} - \mathbf{Q})\) olarak aldık. Bu durumda formüldeki \((\mathbf{Q} - \mathbf{C}) = -(\mathbf{C} - \mathbf{Q})\) olduğu için \(b\) katsayısının başına eksi işareti gelir:-2.0 * dot(r.direction(), oc).
ray_color Fonksiyonunun Güncellenmesi
Eğer ışınımız \(Z = -1\) noktasında duran \(0.5\) yarıçaplı küreye çarpıyorsa kırmızı bir renk döndürelim; çarpmıyorsa önceki bölümdeki gökyüzü gradyanını gösterelim:
| main.cc | |
|---|---|
İlk 3B Kırmızı Küre Renderımız
Programımızı derleyip çalıştırdığımızda:
Karşımıza çıkan görüntü:

Tebrikler! Düz bir çizim değil, 3 boyutlu uzayda ışınların fiziksel olarak çarptığı gerçek bir küreyi render ettiniz!
Şu anda bu küre düz kırmızı bir disk gibi görünüyor; çünkü kürenin üzerindeki eğrilik ve derinlik hakkında hiçbir görsel ipucumuz yok. Bir sonraki bölümde yüzey normallerini hesaplayarak küremize gerçek bir 3B hacim kazandıracağız!