1 puan yazan GN⁺ 2024-06-06 | 1 yorum | WhatsApp'ta paylaş
  • Gökyüzü arka planındaki ay ve gaz gezegenleri, gerçek bir küre mesh'i olmadan da dairesel disk ve piksel shader ile yüzey, dönüş ve atmosfer ifadesini işleyebilir
  • Geleneksel UV sphere, 2×1 doku eşlemesini kolaylaştırsa da köşeli dış hat, mipmap örnekleme kaybı, tekrar eden desenler, seam, kutup bozulması ve atmosfer halo sınırları gibi sorunları birlikte getirir
  • Disk yöntemi, merkez UV'den küre yüzey konumunu yeniden oluşturduktan sonra asin tabanlı küresel UV, dönüş matrisi ve u koordinatı kaydırmalı spin ile piksel düzeyinde küre gibi görünen bir yüzey üretir
  • Gölgelendirme, yüzey konumunu normal olarak kullanan Lambertian aydınlatmadan başlar; kayalık yüzeylerde TBN matrisi ve normal map uygulanır, atmosferde ise halo parlaklığı ve kanal bazlı soğurma yaklaşık olarak hesaplanır
  • Substance Designer statik dokuları ile Unreal dinamik render texture'ları aynı şekilde ele alınabildiğinden, daha küçük dinamik dokular ve tiling ayarıyla performans yükü azaltılabilir

Skybox gezegenlerinin görsel hedefi

  • Projenin skybox'ı, animasyonlu ay ve gaz gezegeni ile uzaylı bir gökyüzü hissi oluşturmaya odaklanır
  • İki gezegen de döner; gaz gezegeninde hareket eden atmosfer akışları da bulunur
    • Gerçek hareket ince düzeydedir ama görsel etki için hız artırılmıştır
  • Sanat yönü, 1970–80'ler bilim kurgu sanatından ilham alan yarı gerçekçi (semi-realistic) bir stildir

Yüzey doku girdileri ve kısıtlar

  • Gaz gezegeninin yüzeyi, piksel shader ve render-to-texture yaklaşımıyla gerçek zamanlı üretilir
  • Ay dokusu Substance Designer'da oluşturulur; renk paleti ve material seed değiştirilerek farklı görünümler denenebilir
  • Dinamik gaz gezegeninde dokunun her karede render edilmesi gerektiği için performans maliyeti yüksektir
    • Doku çözünürlüğü 2 kat artırılırsa render maliyeti 4 katına çıkar
  • Hem statik Substance Designer dokularında hem de Unreal içinde dinamik render edilen dokularda tutarlı çalışan bir çözüme ihtiyaç vardır
  • Cubemap başta düşünülse de kare dokuya göre 6 kat kaynak tüketebilir ve Substance Designer cubemap üretimini desteklemediğinden pratik değildir

UV sphere'de ortaya çıkan sınırlamalar

  • UV sphere, 2×1 dikdörtgen doku ile koordinatları eşleştirmeyi kolaylaştırdığı için varsayılan seçenek gibi görünür
  • Aynı anda kürenin yalnızca bir yüzü görüldüğünden, tamamen özgün dikdörtgen doku yerine tile edilen kare doku da kullanılabilir
  • Pratikte ise birden çok sorun üst üste gelir
    • Dış hat fark edilir biçimde köşeli görünür; bunu çözmek için subdivision artırmak ya da piksel shader maskesiyle gizlemek gerekir
    • Küre yüzeyinin büyük kısmı eğik görüldüğünden daha düşük mipmap'lerden örneklenir; dinamik dokularda ise her kare üretilen piksellerin önemli bir bölümü neredeyse görünmeyen alanlara gider
    • Tiling, tüm desenin devam etmesi için tam sayı katlarıyla büyütülmelidir; yalnızca 2 kat artışta bile tekrar belirginleşir
    • Kesirli tiling, kuzey kutbundan güney kutbuna uzanan bir seam oluşturur
    • Kutuplarda texture pinching ve üçgen eşleme bozulması oluşur; bu da PSX'teki titreyen dokulara benzer bir bozulma gibi görünür
    • Yalnızca yüzey çizilebildiği için atmospheric halo için ayrı bir model gerekir
  • UV sphere, gezegen modellemede hâlâ kullanılabilir ama skybox kullanımında çok sayıda düzeltme ve hack gerektirir

Dairesel disk ve piksel shader yaklaşımı

  • Skybox gezegenleri uzaktan ve tek bir konumdan gözlemlendiğinden, karmaşık bir 3D küre mesh'i şart değildir
  • Basit bir dolu dairesel poligon disk kullanılır ve doku eşleme piksel shader içinde yapılır
  • Atmospheric halo da aynı mesh içinde çizilebilir
  • Diskin UV orijini tam merkezde olmalıdır
    • Gezegen yarıçapı 1 kabul edilirse, atmosferi çizecek alan bırakmak için UV koordinatları bunun dışına da uzanmalıdır

Küre yüzeyinin yeniden oluşturulması

  • Koordinat sistemi olarak DirectX ile uyumlu left-handed, Y-up sistem kullanılır
    • Unreal Engine de left-handed'dir ama up yönü Z olduğu için yön ve normal map formatı kontrol edilmelidir
  • Yüzey denklemi, disk düzlemindeki 2D konumu küre yüzeyindeki 3D konuma eşler
  • Önce pikselin küre yüzeyi içinde olup olmadığını anlamak için UV vektörünün uzunluğunun yarıçaptan küçük olup olmadığı kontrol edilir
float CircleMask( float2 uv, float radius)
{
    return length(uv) < radius? 1.0: 0.0;
}
  • Bu yöntem yalnızca UV koordinatları mesh merkezine hizalıysa doğru çalışır
  • Küre yüzeyinin local position değeri oluşturulurken UV'nin x ve y'si aynen kullanılır, yalnızca z yeniden hesaplanır
float3 ReconstructSurface(float2 uv)
{
    float zSquared = 1.0 - dot(uv, uv);
    float z = sqrt(zSquared);
    return float3(uv, z);
}

Küresel UV üretimi

  • Kare bir dokuyu küre yüzeyine eşleme süreci üç adıma ayrılır
    • Silindire sarma
    • Aynı işlemi y ekseni için tekrarlama
    • Sonucu dairesel biçime dönüştürme
  • x doku koordinatı, silindiri saran açıyla orantılıdır; arcsine(x) hesaplandıktan sonra [-π, π] aralığı yeniden [0, 1] aralığına eşlenir
  • Kürenin local width değeri olan generatrix kullanılarak koordinatlar kutuplarda sıkıştırılır
float2 GenerateSphericalUV(float3 position)
{
    float width = sqrt(1.0 - position.y * position.y);
    float generatrixX = position.x / width * sign(position.z);
    float2 generatrix = float2(generatrixX, position.y);
    float2 uv = asin(generatrix) / 3.14159 + float2(0.5, 0.5);
    return float2(uv);
}

Eksen eğimi ve dönüş

  • Daha doğal gezegen kompozisyonu için gezegen ekseni pitch ve roll ile eğilir
    • Bilim kurgu sanatındaki gezegenler genellikle eğik çizilir; bu da kompozisyonu daha dinamik gösterir ve kutup buzullarını göstermeyi mümkün kılar
  • Yaw dönme hareketine karşılık gelir ve seam sorunundan kaçınmak için ayrı bir aşamada ele alınır
  • Mesh kürelerde gezegen genelde bir matrisle dönüştürülür; disk yaklaşımında ise her piksel yüzey konumunu tanımladığı için yalnızca dönüş içeren basit bir 3×3 matris yeterlidir
float3x3 CreateRotationMatrix(float pitch, float roll) {
    float cosPitch = cos(pitch);
    float sinPitch = sin(pitch);
    float cosRoll = cos(roll);
    float sinRoll = sin(roll);

    return (float3x3)(
        cosRoll, -sinRoll * cosPitch, sinRoll * sinPitch,
        sinRoll, cosRoll * cosPitch, -cosRoll * sinPitch,
        0.0, sinPitch, cosPitch
    );
}
  • Unreal'ın material editor'ü matrisleri veri türü olarak desteklemese de bunun için dolaylı çözümler vardır

Scale, seam ve spin işlemleri

  • Doku scale değeri değiştirildiğinde, normalde dokunun kenarına denk gelip gizlenen UV seam görünür hâle gelir
  • Seam'i tamamen kolayca kaldırmak mümkün değildir ama arka tarafa taşınırsa daha az görünür olur
  • Küre, konum işaretine göre dört bölgeye ayrılır ve back-left ile back-right bölgelerine u yönünde offset uygulanır
float2 GenerateSphericalUV(float3 position, float spin, float scale)
{
    float leftRightSign = sign(position.x);
    float frontBackSign = sign(position.z);
    float width = sqrt(1.0 - position.y * position.y);
    float generatrixX = position.x / width * frontBackSign;
    float2 generatrix = float2 (generatrixX, position.y);
    float2 uv = asin(generatrix) / 3.14159 + float2 (spin, 0.5);
    if(frontBackSign < 0.0)
    {
        uv = float2 (uv.x + 1.0 * leftRightSign, uv.y);
    }
    return float2 (uv / scale);
}
  • Seam yine kuzey ve güney kutbunu birleştirir ama arkaya taşındığı için çok daha az fark edilir
  • Dönüş, kürenin kendisini çevirmek yerine yüzey dokusunu u koordinatı yönünde kaydırarak sağlanır
float2 GenerateSphericalUV(float3 position, float scale, float spin)
{
    float width = sqrt(1.0 - position.y * position.y);
    float generatrixX = position.x / width * sign(position.z);
    float2 generatrix = float2(generatrixX, position.y);
    float2 uv = asin(generatrix) / 3.14159 * scale + float2(0.5 + spin, 0.5);
    return float2(uv);
}
float2 sphericalVU = GenerateSphericalUV(position, scale, time*speed)

Yüzey gölgelendirmesi ve normal map

  • Gezegenin yuvarlak görünmesi için gölgelendirme kritik önemdedir
  • Standart motor gölgelendirmesinden farklı olarak gezegen iki katmandan oluşur: yüzey ve atmosfer; bu yüzden iki katmanın aydınlatması ve blending'i manuel tanımlanmalıdır
  • Yarıçap 1 ise, dönüş uygulanmadan önceki yüzey konumu doğrudan surface normal olarak kullanılabilir
  • Aydınlatmada basit bir Lambertian model kullanılır
    • Amaç tam fiziksel gerçekçilik değil, NASA fotoğraflarından ilham alan stilize bir bilim kurgu kapak estetiğidir
float LambertianLight(float3 normal, float3 lightDirection) {
    float NdotL = max(dot(normal, lightDirection), 0.0);
    return NdotL;
}
  • Gaz devi gibi pürüzsüz yüzeylerde basit normal yeterli olabilir
  • Kayalık gezegenlerde dağ sıraları, çıkıntılar ve krater gibi topoğrafyayı normal map ile simüle etmek daha uygundur
  • Normal map kullanmak için Tangent, Bitangent ve Normal'den oluşan bir TBN matrisi gerekir
    • Kürede bu hesap piksel başına yapılmalıdır
    • TBN matrisi, normal map'teki normal'i World Space Coordinates'e dönüştürmek için kullanılır

UV süreksizliği ve mipmap artifact'leri

  • Piksel shader içinde üretilen UV'lerde süreksizlik (discontinuity) sorunu ortaya çıkabilir
  • Arka seam'de yatay UV bileşeni sınırda 0.0 ile 1.0 arasında kusursuz biçimde bağlanmalıdır ama pratikte seam boyunca bloklu artifact'ler oluşur
  • Bu çizgi, UV'nin DDX değeriyle ilişkilidir
    • DDX ve DDY, ekran uzayı eksenlerinde UV değişim oranını ölçer
    • Texture sampler, hangi mipmap'in kullanılacağını belirlemek için bu değerleri kullanır
    • Düşük UV derivative yüksek çözünürlüklü mipmap'e, yüksek derivative ise düşük çözünürlüklü mipmap'e karşılık gelir
  • Seam'in iki yanındaki değerler aniden sıçrarsa DDX büyür ve en düşük mipmap'den örnekleme yapılarak gri bir çizgi gibi görünebilir
  • Gezegenlerde bu kısım polar patch ile örtüleceği için büyük bir sorun değildir; ama dikkat çekerse seam'in DDX ve DDY değerleri manuel düzeltilip sampler'a verilmelidir
  • Verilen fix örneği yalnızca açıklama amaçlıdır; gerçek değerler kullanılan eşlemeye göre formül türetilerek hesaplanmalıdır

Kutup yaması ve pinching düzeltmesi

  • Kutuplardaki bozulma, kanıtlanmış bir yöntem olan polar patch ile kapatılır
  • Gezegen ve aylarda kutup bölgeleri çoğu zaman buzla kaplıdır ve diğer alanlardan görsel olarak ayrılır; bu nedenle ayrı bir doku yaması hem sorunu gizler hem de görsel ilgi ekler
  • Polar patch, dönme eksenine dik bir düzleme eşlenip çıkan koordinatların döndürülmesiyle eklenebilir
float2 PolarPatchMapping(float3 position, float scale, float spin)
{
    float cosSpin = cos(spin);
    float sinSpin = sin(spin);
    float scale = 0.4;

    float2 uv = float2(position.x, position.z) * scale;
    float2 spinningUV = float2(uv.x * cosSpin - uv.y * sinSpin,
                               uv.x * sinSpin + uv.y * cosSpin);

    return spinningUV;
}
  • UV map vertekslere yazılmadığı, her piksel için üretildiği için kutup pinching düzeltmesinde daha fazla esneklik sağlanır
  • Basit bir bölme ile kutup dokusunun aspect ratio'su düzeltilebilir
uv = float2(uv.x, uv.y/pow(width, 1/3));
  • Düzeltme sonucu başka artifact'ler gibi görünebilir; ancak gerçekçi sahnelerde polar patch ile daha pürüzsüz birleşir ve görsel uyumsuzluk azalır

Atmosfer halo yaklaşımı

  • Diskte gezegen yüzeyi tüm alanı kaplamadığından, boş kalan alana atmospheric halo çizilebilir
  • Halo'yu aynı shader içinde çizmek, gezegen üzerindeki atmosferle daha doğal birleşmesini sağlar
  • Fizik tabanlı atmosfer render'ı genellikle Rayleigh scattering ve raymarching kullanır, ancak burada bunlar tercih edilmez
  • Bunun yerine Quake 1·2'deki dinamik nesne aydınlatma hilesine benzer bir yaklaşım kullanılır
    • Quake'in static lighting'i önceden lightmap olarak hesaplanırdı
    • Dinamik canavarlar, altlarındaki lightmap'i örnekleyerek renklerini ayarlardı; fiziksel olarak doğru olmasa da çevreyle uyumlu görünürdü
  • Benzer şekilde, atmosfer halo aydınlatması gezegen yüzeyi kullanılarak yaklaşık olarak hesaplanır
    • Bump mapping öncesindeki yüzey normal'i genişletilerek halo parlaklığı hesaplanır
    • Kanal bazında parlaklığın farklı yeniden eşlenmesi, farklı ışık dalga boylarının soğurulmasını basit biçimde simüle eder
    • Atmosfer eğik açılarda daha görünür olduğu için surface normal'in Z bileşeni yeniden eşlenir
    • Halo fade etkisi için küre yüzeyine olan uzaklık da hesaplanır
  • Son aşamada yüzey ile atmosfer alpha blending ile birleştirilir

Nihai sonuç ve kullanım

  • Beklenenden daha fazla adım gerekse de nihai sonuç tam bir küre gibi görünür ve istenen doku/shader manipülasyonlarını destekler
  • Tek bir Substance Designer graph ile yüzey dokusu üretilebilir ve sonuca ek bir post-processing gerekmez
  • Animasyonlu dokular da aynı şekilde ele alınabilir
    • Daha küçük doku boyutları kullanılarak performans kazanılabilir
    • Tiling istenen ölçüde ayarlanabilir
  • Sonuç videosu Video 3 bağlantısında görülebilir

1 yorum

 
GN⁺ 2024-06-06
Hacker News görüşleri
  • Yazara göre cube map’i fazla hızlı elemiş gibi; kişisel bir projede dinamik gaz gezegeni render ederken kullandığımda en basit çözüm buydu
    Cube map kullanmak belleği 6 katına çıkarmıyor; yalnızca büyük bir dikdörtgen texture’ı 6 küçük dikdörtgen yüze bölüyorsunuz, yani toplam texture detayı aynı kalıyor
    Avantajı, kutuplardaki sıkışmayı dert etmemeniz ve 3 boyutlu ya da 4 boyutlu noise function ile texture animasyonu/bozulması için dikişsiz akış alanlarını kolayca üretebilmeniz
    https://www.junkship.net/News/2016/06/09/jupiter-jazz

    • Garip dikiş artefaktlarından kaçınmak için 2 stereografik yarımküre kullanmak daha iyi olabilir
      Her yarımküre bir diske izdüşürülür, ancak texture’ı kare sınırına kadar doldurabilir ve her yarımkürenin bir kısmını diğerinin texture kenarlarında üst üste bindirebilirsiniz
      Disk merkezi ile kenarı arasında 1:2 ölçek farkı olduğundan, minimum detay ölçütüne göre piksel israfı var denebilir; ama bu, eşaçılı projeksiyon olduğu için hedef piksel rengini keskin perspektiflerde örneklemeyi çok daha az zahmetli hale getirir ve ileri/geri dönüşüm hesapları da projeksiyon noktası başına bir bölme ile birkaç toplama ve çarpmadan ibarettir; cube map’in merkezi projeksiyonundan bile ucuzdur
      Ölçek değişimini ve kenar piksel israfını daha da azaltan ama kavramsal olarak aşırı karmaşık olmayan bir eşaçılı yöntem istiyorsanız, birbirine dik ve hafifçe örtüşen 2 Mercator projeksiyonu kullanarak küreyi bir beyzbol topunun iki deri parçası gibi kaplayabilirsiniz
      Her parça bir dikdörtgen texture olabilir; NOAA makaleleri arasında, Dünya hava durumu simülasyonlarının diferansiyel denklem ızgaraları için bu yaklaşımı önerenler de var
      Bildiğim en piksel verimli projeksiyon, küreyi bir oktahedrona bölüp her oktantı “küresel alan koordinatları” tabanlı altıgen piksel ızgarasıyla kaplamak
      Her oktant, normal bir kare piksel görüntüsünde yarım kare yani 45-45-90 dik üçgen olarak ifade edilebilir; https://observablehq.com/@jrus/sac-quincuncial gibi sonuçlar verir ve https://observablehq.com/@jrus/sphere-resample gibi altıgen ızgaralar da kullanılabilir
      Ama sınırların ötesinden örnekleme gerektiğinde ayrıntıları ele almak, 2 stereografik yarımküre yöntemine göre çok daha zahmetlidir ve dikiş artefaktları da oluşabilir
    • https://en.wikipedia.org/wiki/Peirce_quincuncial_projection
    • Bozulmayı daha da azaltmak istiyorsanız, düzenli ikosahedronun üçgen yüzlerini 10 eşkenar dörtgene gruplayıp her eşkenar dörtgeni tek bir kare texture ile de kaplayabilirsiniz
      Biraz daha fazla matematik gerekir ama başka nedenlerle yüzeyi daha fazla alt bölümlere ayırmayı planlamıyorsanız, genelde buna değmez
    • Şu anda yaptığım gezegen ölçekli oyunda bulut üretimi için şu curl noise’u deneyebilirim
  • Kutuplardaki texture sıkışması aslında tüm yüzeyde var olan bozulmanın uç bir görünümüdür
    Genellikle yalnızca kutuplarda belirgin olur, ancak küreyi üçgenlerle uyarlamalı olarak alt bölümlere ayırırsanız, alt bölüm seviyesi değiştikçe bozulma da değişir ve başka yerlerde de görünür olabilir
    Sorun şu ki küre dörtgenlere bölünür ve her dörtgen UV uzayında eşit alanlı 2 üçgen olarak temsil edilir, ama 3D uzayda üçgenlerden biri, özellikle yatay kenarı kutba daha yakın olan, daha küçüktür
    Buna rağmen UV, üçgen içinde doğrusal enterpolasyonla hesaplandığı için texture’ın yarısı sıkışır, yarısı gerilir
    Kutupta bir üçgenin 3D alanı gerçekten 0 olur; böylece texture’ın yalnızca yarısı render edilir ve üçgenler arasındaki dikiş belirginleşir
    Doğru çözüm, tepe noktası başına doğrusal enterpolasyon yerine pixel shader içinde her piksel için UV koordinatlarını hesaplamaktır; düzgün yapıldığında kutuplar da dikişsiz işlenir

    • Render, shader ve oyun geliştirmeyle yeni yeni uğraşmaya başladım; araştırabileceğim ipuçları, anahtar kelimeler ya da bağlantılar varsa duymak isterim
    • XYZ öğelerindeki W’yi 1 bırakmak yerine W’yi ölçeklemek bu sorunu çözmez mi?
    • Böyle sıkışmaları azaltmak için küreyi birden fazla render kutbuyla render eden durumlar var mı?
      Örneğin “gerçek kuzey” kutbu olan bir küreyi render ederken, yandan bakıldığında gerçek kuzeye göre ayarlanmış render kutbu kullanmak, gerçek kuzeye yakın bir açıdan bakıldığında ise 0',0’ ekvator render’ını kullanmak gibi
  • Displacement mapping’e tekrar bakmak istettirdi
    Yazarın çözmeye çalıştığı problemin alternatifi olmayabilir ama daha basit ve epey eğlenceli
    Yaklaşık 25 yıl önce SoundJam için “Eclipse” adlı bir müzik görselleştiricisi yapmıştım; girdi olarak işitilebilir frekans aralığındaki seviye dizisi ile sol ve sağ kanallar vardı
    Amaç, korona püskürmeleri olan tutulmuş bir güneş görünümüydü ve müzik verisi bu “püskürmeleri” oluşturuyordu
    Verinin frekansı, bunun güneş diskinin çevresinde nerede görüneceğini belirliyordu
    Zaman geçtikçe püskürmeler güneşten uzaklaşıyor ve “soğuyarak” siyaha dönüp kayboluyordu; güçlü sinyaller beyaz başlıyor, zayıfladıkça sarı, turuncu, kırmızı ve kahverengi oluyordu
    Ses verisi değerlerinden oluşan diziyi, püskürmelerin siyaha dönüp yok olmasına kadar geçen süreyi tutacak kadar büyük bir circular buffer içinde saklamam gerekiyordu
    Tüm “Eclipse” ve püskürme gösterimi sonuçta bir displacement map’ti; her piksel değerinin ses seviyesi buffer’ındaki bir ofsete karşılık geldiği bitmap’i önceden hesaplamıştım
    Güneş yüzeyine yakın pikseller yeni gelen veri ofsetlerine, daha dıştaki pikseller ise süresi dolmak üzere olan buffer kuyruğundaki ofsetlere sahipti
    Dairesel/radyal püskürmeleri Kartezyen koordinatlara eşlemeye çalıştığım için displacement değerlerini üretmek biraz matematik gerektirmişti
    Ana döngü, yeni ses değerlerini alıp en eski değerlerin üstüne yazıyor; sonra displacement map’i satır satır, sütun sütun dolaşıp ilgili ses verisini çekiyor, bunu sabit palet renklerine eşleyip görüntü buffer’ına koyuyordu
    Diğer görselleştiriciler kadar gösterişli değildi ama sakin bir güzelliği vardı ve müzik verisini oldukça iyi yansıtıyordu
    Sonraki görselleştiricilerde olduğu gibi sessizlikte bile yerinde duramayan bir hissi yoktu

  • Yazı harika ama aşağı indikçe çok sayıda shader yüklüyor; çok güçlü bir bilgisayarınız yoksa tarayıcı neredeyse kilitlenebilir

    • “Çok güçlü bir bilgisayar” derken ne kastediliyor? Son 10 yıl içindeki bir dizüstünün entegre grafikleri bile böyle bir şeyi render etmekte zorlanır mı?
  • İnsanların “gerçekçiliği” ne kadar farklı yorumladığını görmek ilginç.
    Kaynakların çok daha kısıtlı olduğu dönemlerin oyunlarında bu fark özellikle belirgindi; bazı oyunlar kare, pikselli ve düşük paletli grafiklerle bile günümüzün yüksek bütçeli oyunlarından daha fazla içine çekebiliyordu.

    the gas giant’s surface texture will be generated in realtime using a pixel
    shader and a render-to-texture approach
    En baştan pratik olmayan ve sınır tanımayan bir yaklaşımla başlayıp performans darboğazı yaratacak yöntemleri aramak, sonra da bunu sürdürüp tavşan deliğinden aşağı inişi izlemek ilgi çekici.
    Sonuçta asıl yazının yazarının bunu gerçekten çalıştırıp çalıştırmadığını merak ediyorum.
    Bu, gerçek dünya kısıtları olan projelerle hobi projeleri arasındaki fark da olabilir.
    Gaz devi için önceden render edilmiş animasyonlu bir doku kullanıp projenin geri kalanına geçebilir, her şey çalıştıktan sonra Slartibartfast cosplay yapmaya geri dönebilirsin.

    • Düşük sadakatli oyunların daha sürükleyici olmasının nedeni, hayal gücünün devreye gireceği alan bırakmaları olabilir.
      Bu yüzden insan muhtemelen daha aktif biçimde oyuna kapılıyordu.
  • Benzer bir yaklaşımı ele alan şu yazı aklıma geldi: https://bgolus.medium.com/rendering-a-sphere-on-a-quad-13c92...

  • GPU’larda ya da 3D kütüphanelerde, çemberin her yatay satırını soldan sağa tarayıp dokunun X,Y koordinatlarını küre üzerindeki “3D” konuma eşleyen bir fonksiyon yok mu?
    Küre bir çemberdir ve çember çizme algoritmaları basittir; buna karşılık üçgenler için milyonlarca köşeyi döndürüp projeksiyona sokmak inanılmaz bir kaynak israfı gibi görünüyor.
    Yatay tarayıp bir satır aşağı inerek devam edersen tüm satırları çizebilirsin.
    80’lerin sonunda Second Reality’deki büyüteç benzeri şeyleri önceden hesaplamak için buna benzer işler yaptığımı hatırlıyorum.

    • Muhtemelen spherical linear interpolation, doğrusal enterpolasyondan daha yavaş ve daha özel amaçlı olduğu içindir.
      Tüm render pipeline zaten doğrusal enterpolasyonu işleyecek şekilde kurulmuş durumda.
      Tek bir shader programı ve 1 üçgenle bile kusursuz anti-aliased bir küre çizilebilir.
    • GPU, eski yazılım render’ları gibi satır satır rasterize etmez; temelde yalnızca triangle rasterization bilir.
      Bu yüzden GPU’da render edeceksen, görünürdeki karmaşıklığına rağmen yazıdaki yaklaşım aslında gayet makul görünüyor.
      GPU tabanlı render yapısını anlatan harika bir yazı dizisi var: https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-...
      6. bölüm rasterization’ı ele alıyor.
    • GPT’nin verdiği kodda yöntem, çember içindeki her piksel için z hesaplamak, döndürmek, ardından atan2 ve asin ile doku koordinatlarını bulup rengi yazmaktı; çalıştırınca gerçekten işliyor gibi görünüyordu.
  • Arka plan üzerindeki 2D pixel shader impostor gezegenler, procedural space gibi çok sayıda gezegen içeren işler için gerçekten çok faydalı.
    Bellek ve GPU bant genişliği nedeniyle küresel küp tabanlı gezegenleri 1 instance ile sınırlayıp yakın gökcisimlerini arka plan tekniğiyle çiziyoruz.
    Uzayda, iki gökcisminin arasında kabaca ikisinin de impostor olarak render edildiği bir mesafe var; sonrasında en yakın gökcismi spherical quadtree yöntemiyle işleniyor.
    Mükemmel değil ama yarattığı göz yanılsamasında kusur bulmak neredeyse imkansız.
    Ayrıca düzlem üzerinde oldukları için, uzaktaki galaksiler veya gökcisimleri için kamera lensine ait hafif fiziksel etkiler eklemek de kolaylaşıyor.
    Örneğin Ay’ın doğarken gerçekte olduğundan daha büyük görünmesi ya da uzak bir galaksinin kütleçekim nedeniyle bükülmüş görünmesi gibi.

  • Gaz deviyle ilgili şu sayfayı beğendim: https://emildziewanowski.com/flowfields/

  • Icosphere, çok daha düzgün biçimde açılabilir ve köşe konumlarıyla öğe boyutları da daha düzenlidir.
    Açma işlemi önemsiz değil ama yapılabilir.