Şu anda pürüzsüz prosedürel geometriyi görüntülemek için imzalı mesafe alanlarını kullanan bir oyun motoru geliştiriyorum (şu anda bağlantınızdakiler gibi basit ilkellerle oluşturulmuş, gelecekte Julia ve IFS fraktallarını uygulamak istiyor). Motorum prosedürel üretime odaklandığından ve rakamları ray-marcher'ı kolaylaştıracak şekilde tanımlaması gerektiğinden , bu soruyu cevaplamak için iyi bir yerdeyim.
Akışla ilgili olarak, basit çözüm, bir tür yazılan bir tampon kullanmak ve ışın yürüyüşü yapmak istediğinizde GPU'ya atmaktır. Tamponun her elemanı karmaşık bir tiptir (örn. C / C ++ 'da bir yapı) ve her tür, onu temsil etmek için hangi işlevi kullanmanız gerektiğini, konumunu, dönüşünü, ölçeğini, vb. Ve ortalama bir rengi tanımlayan öğeler içerir. İşlem daha sonra aşağıdakileri basitleştirir:
- Sahnenizi yönetilebilir bir alt kümeye itin (frustum ayıklama ve oklüzyon ayıklamanın kısmen de olsa ışınlama algoritması tarafından otomatik olarak yapıldığını unutmayın)
- Alt kümeyi oluşturma giriş arabelleğinize geçirin
- Tamponu henüz yoksa GPU'ya geçirin, ardından sahnenizi sıradan geleneksel ışın yürüyüşüyle render edin. Ray-marcher'ın her yinelemesi için giriş arabelleğindeki hangi öğenin her ışına en yakın olduğunu değerlendirmek için bir tür adım başına arama yapmanız gerekir ve ışınlardan birine dönüşümler uygulamanız gerekir (bu durumda GPU'ya ulaşmadan önce şekil dönüşlerini ters çevirmeniz gerekir) veya mesafe işlevleri kendileri (konum değişiklikleri için işlev başlangıç noktasını hareket ettirme, örneğin ölçek değişiklikleri için kübik yan uzunlukları ayarlama, vb.) En basit yaklaşım, daha önce ışınları değiştirmektir. bunları gerçek çekirdek mesafe işlevine iletirsiniz.
Şekil renkleriyle ilgili olarak, gölgelendiricilerin ilkellerin yanı sıra karmaşık türleri tanımlamanıza izin verdiğini unutmayın;). Bu, her şeyi C stili bir yapıya atmanıza, ardından bu yapıları mesafe işlevinizden geri aktarmanıza olanak tanır.
Motorumda, her yapı bir mesafe, renk ve onu giriş arabelleğindeki karşılık gelen şekil tanımına bağlayan bir kimlik içerir. Her kimlik, ilgili mesafe fonksiyonunun çevre bağlamından çıkarılır (eşleme fonksiyonum, her adım için her ışına en yakın rakamı bulmak için giriş arabelleğinden geçtiği için, her bir SDF çağrıldığında döngü sayacının değerini güvenli bir şekilde tedavi edebilirim mesafe değerleri rasgele bir çekirdek SDF kullanılarak tanımlanırken (ör.point - figure.pos
bir küre için) ve renkler ya şekil arabelleğindeki uygun öğenin ortalama renginden (bu nedenle şekil kimliğini çevresinde tutmak yararlıdır) veya depolanan ortalamaya doğru ağırlıklı bir prosedür rengi aracılığıyla tanımlanır (bir örnek alıyor olabilir Mandelbulb üzerinde bir nokta için bir yineleme sayımı, "ortalama renginizi" FP renk uzayından tamsayı renk uzayına eşleme, ardından eşlenen rengi yineleme sayısına göre XOR'lama yoluyla bir palet olarak kullanma).
Prosedürel dokular başka bir yaklaşımdır, ancak onları asla kendim kullanmadım. iq bu alanda oldukça fazla araştırma yaptı ve Shadertoy hakkında bazı ilginç gösteriler yayınladı, bu yüzden ekstra bilgi toplamanın bir yolu olabilir.
Ne olursa olsun bir renk, her şekil, prosedür üretilen veya sihirli usul doku örneklenmiş statik olup olmadığı, temel mantık aynıdır: orta kompleks tipte bir tür (örneğin, bir yapı) içine Özet rakamlar, depolamak hem yerel mesafe ve yerel bu tür bir örnekte renk ekleyin, ardından karmaşık türü uzaklık işlevinizden bir dönüş değeri olarak iletin. Uygulamanıza bağlı olarak, çıktı rengi doğrudan ekrana geçebilir veya çarpışma noktasını aydınlatma kodunuza kadar takip edebilir.
Yukarıdakilerin yeterince açık olup olmadığını bilmiyorum, bu yüzden bir şeyin mantıklı olmadığını sormak için endişelenmeyin. HLSL ve hesaplama gölgelendirme ile çalıştığım için gerçekten herhangi bir GLSL / piksel gölgeleme kodu örneği veremiyorum, ancak ilk etapta düzgün bir şekilde yazmadığım bir şeyi denemekten mutluluk duyuyorum :).