1 puan yazan GN⁺ 2026-02-09 | 1 yorum | WhatsApp'ta paylaş
  • Game Boy Color üzerinde gerçek zamanlı 3D gölgelendirme uygulayan bir proje; oyuncu ışığın yörüngesini kontrol ederken nesneyi döndürebiliyor
  • Normalize vektörler ve Lambert gölgelendirmesi (dot product) hesabını temel alıyor; işlemleri basitleştirmek için küresel koordinat sistemi kullanılıyor
  • Çarpma komutu olmayan SM83 CPU kısıtlarını aşmak için log dönüşümü ve lookup table'lar kullanılarak işlemler 8 bit hassasiyetle yürütülüyor
  • Kendi kendini değiştiren kod (self-modifying code) ile yaklaşık %10 performans artışı sağlanıyor ve kare başına 15 tile render ediliyor
  • Yapay zeka ile kod üretme denemeleri büyük ölçüde başarısız olmuş; çekirdek algoritma ve shader'lar elle yazılmış kodla tamamlanmış

Proje özeti

  • Game Boy Color'da gerçek zamanlı görüntü render eden bir oyun geliştirildi
    • Oyuncu, yörünge biçimindeki bir ışığı kontrol ederken nesneyi döndürüyor
  • Tüm kod GitHub deposunda (nukep/gbshader) açık olarak yayımlandı

3D üretim süreci

  • Başlangıçtaki lookdev çalışması için Blender kullanıldı; görsel sonuç tatmin edici bulununca projeye devam edildi
  • Cryptomatte ve özel shader'larla normal map üretildi
    • Teapot modeli için kamera döndürülerek PNG dizisi halinde normal map çıktı alındı
    • Game Boy Color modelinin ekran bölümü ayrı bir sahnede render edilip sonradan birleştirildi

Matematiksel temel

  • Normal map, her pikselin normal vektörünü kodlayan bir vektör alanı olarak kullanılıyor
  • Lambert gölgelendirmesi, v = N·L biçimindeki bir iç çarpımla (dot product) hesaplanıyor
  • Küresel koordinatlara dönüştürülerek v = sinNθ sinLθ cos(Nφ−Lφ) + cosNθ cosLθ biçiminde sadeleştiriliyor
    • Tüm vektörlerde yarıçap r=1 varsayılarak işlem yükü azaltılıyor

Game Boy üzerindeki uygulama

  • Lθ (ışığın dikey açısı) sabit tutuluyor, yalnızca Lφ (ışığın dönme açısı) oyuncu tarafından kontrol ediliyor
  • ROM'da her piksel (Nφ, log(m), b) biçiminde saklanıyor
  • Çarpma komutunun olmaması sorununu çözmek için log dönüşümü ve lookup table'lar (log, pow) kullanılıyor
    • Negatif işlemleri desteklemek için işaret (sign) biti üst bitlerde saklanıyor
  • Tüm skaler değerler -1.0 ile +1.0 aralığında 8 bit kesirler olarak ifade ediliyor
    • Toplama lineer uzayda, çarpma ise log uzayında yapılıyor
    • Payda olarak 127 kullanılarak hem +1 hem -1 temsil edilebiliyor

cos_log ve temel işlemler

  • cos_log, log(cos x) biçiminde birleşik bir lookup olup çarpma işlemini logaritmik toplamaya dönüştürüyor
  • Piksel başına işlem miktarı
    • 1 çıkarma, 1 cos_log erişimi, 1 toplama, 1 pow erişimi, 1 toplama
    • Toplamda 3 toplama/çıkarma ve 2 lookup yapılıyor

Performans

  • Kare başına 15 tile işleniyor; bazı boş satırlar daha hızlı hesaplanabiliyor
  • Piksel başına yaklaşık 130 cycle, boş satırlarda ise 3 cycle gerekiyor
  • CPU'nun yaklaşık %89'u shader hesaplamaları için, kalanı giriş ve I/O işlemleri için kullanılıyor

Kendi kendini değiştiren kod (Self-Modifying Code)

  • Kare başına yaklaşık 960 piksel işleyen çekirdek döngüyü optimize etmek için komutların kendisi değiştiriliyor
    • Değişken yüklemek yerine sabitler doğrudan koda gömülerek daha hızlı işlem yapılıyor
    • Örnek: sub a, 8, sub a, variable'dan 12 cycle daha hızlı
    • Toplamda yaklaşık 11.520 cycle (%10) tasarruf sağlanıyor

Yapay zeka kullanım denemeleri

  • Tüm projenin %95'i elle yazıldı
  • Yapay zeka, Game Boy assembly'si (SM83) yazmakta zorlandı
  • Yapay zekanın kullanıldığı alanlar
    • Python: OpenEXR katmanlarını okuma
    • Blender: sahne otomasyon betikleri
    • SM83: bazı işlev parçacıkları (ör. VRAM DMA)
  • Başarısız denemeler
    • Yapay zekayla shader assembly kodu üretme girişimi → verimsiz ve çok hatalı sonuçlar
  • Claude Sonnet 4 modeliyle sözde koddan assembly üretme denemesi
    • Kısmen çalıştı ancak yavaştı; ayrıca Z80 ile SM83'ü karıştırma gibi hatalar yaptı
    • Nihai kod sonunda tamamen elle yeniden yazıldı

Sonuç ve çıkarımlar

  • Yapay zeka basit betiklerde yararlı olsa da, doğruluk ve doğrulama şart
  • OpenEXR işleme kodunda yapay zeka kanal sıralama hatası (BGR vs RGB) oluşturarak haftalar süren bir bug'a yol açtı
  • Deneyim, “yapay zeka kullanırken en önemli şey doğrulamadır” dersini öne çıkarıyor
  • Proje, eski donanımın sınırlarını aşan deneysel bir shader uygulaması örneği olarak değerlendiriliyor

1 yorum

 
GN⁺ 2026-02-09
Hacker News yorumları
  • HN'de gerçekten hacker ruhu taşıyan bir yazı görmek sevindirici.

    • Bunun sadece bir AI prompt'uyla yapılmış bir şey olup olmadığını merak etmiştim. Nasıl gerçekleştirildiğini öğrenmek istiyorum 😉
  • Ortaya çıkan sonuç gerçekten harika. Benim anladığım kadarıyla bu, “3D gibi görünen ama aslında 2D normal map önceden render edilip üzerine ışıklandırma efektleri uygulanmış bir shader”
    Kareler bu GitHub bağlantısında yer alıyor

    • Aslında “gerçek 3D” bir renderer'dan çok da farklı değil. deferred rendering pipeline'da da shader'lar depth map, normal map, color buffer gibi 2D buffer'lar üzerinde çalışır.
      3D üçgen işleme kısmı basit tutulur ve maliyetli ışıklandırma shader'ları 2D görüntü üzerinde yalnızca bir kez çalıştırıldığı için verimlidir
      Shader açısından bakıldığında girdi 3D vektörse bu bir 3D shader'dır. 3D rasterizer olup olmaması ayrı bir konudur
      Modern 3D oyunlar da bu yöntemi çeşitli şekillerde kullanır. Farklı açılardan önceden render edilmiş modellerin kullanıldığı imposter tekniği de gerçek 3D motorlarda kullanılan resmi bir tekniktir
    • Eski Mac oyunlarının 3D hızlandırıcı donanım olmadan 2D texture'lara ışıklandırma uygulama yöntemine benziyor.
      Ancak bu kez bunun Game Boy Color'da çalışıyor olması şaşırtıcı
  • Merhaba, yazının yazarı benim. Bunun burada paylaşıldığını duydum ve hesap açtım. Paylaştığınız için teşekkürler
    Environment map kullanarak daha da basitleştiren denemeler de yapıyorum; Bsky'de paylaştığım bağlantıdan görebilirsiniz

  • Gerçekten ilginç bir proje. Eskiden C64 assembly kodlama yaptığım günleri hatırlattı.
    O zaman da çarpma komutu olmadığı için donanım kısıtlarını aşmanın yaratıcı yollarını bulmak gerekiyordu

  • AI kullanmayı deneme girişimiydi ama sonuçta başarısız bir deney oldu.
    Sektör AI konuşmalarıyla çalkalanırken bunu bizzat deneyimlemek istedim ve generative AI kullanılıp kullanılmadığını şeffaf biçimde açıklamanın önemli olduğunu düşünüyorum.
    Gizlemek güveni zedeler; açıklamak ise farklı düşünen insanlarla da açık bir diyalog kurmayı mümkün kılar

    • Başlangıçta tonum nötrdü ama insanlar AI'ı övdüğümü sandığı için biraz daha şüpheci bir tona çevirdim.
      Sadece bu süreci kayda geçirmek istemiştim
  • Bu GBC shader'ı, “bütün hesaplamalar kısıtlar altında yapılan birer yaklaştırmadır” gerçeğini gösteriyor.
    Çarpma işlemi tablo bakışı ve toplamayla değiştirilmiş, hassasiyet ise gözle görülen sonuca göre ayarlanmış

  • Gerçekten etkileyici. Özellikle bunun gerçek Game Boy Color donanımında çalışıyor olması şaşırtıcı.
    Bazen karta güçlü bir işlemci koyup GBC'yi yalnızca basit bir terminal gibi kullananlar oluyor, ama bu öyle bir hack değil

  • Açıkçası Nintendo'nun GBC ya da GBA'yı yeniden piyasaya sürmesini isterdim.
    İçinde birkaç oyun bulunan kartuş biçiminde satsalar hemen alırdım

    • İkinci elde oldukça ucuza bulunabiliyor. Bir flash cartridge eklerseniz tamamdır.
      Ama bugünlerde aynı form faktördeki Android el konsolları daha pratik.
      Bende de bir Game Boy koleksiyonu var ama artık emülatörler çok daha kullanışlı geliyor
    • Oculus VR'ın kurucusunun yaptığı ModRetro Chromatic'i alabilirsiniz.
      Nintendo yeniden yapsa bile bunun kadar iyi olacağını sanmıyorum
  • İşte HN'in var olma nedeni tam da böyle yazılar.
    Eski teknoloji dergilerini karıştırdığım günlerdeki keyfi yeniden hissettiriyor

  • Bu yazar iyi anlamda çılgın bir dahi