Cnrtnbl

Unreal MVP
24 Kas 2020
216
162
43
36
(35) İzmir
Herkese selamlar. Foruma faydalı olmak adına optimizasyon ile ilgili bir şeyler yazmak istedim. 1 yıl içinde 10-15 fpslerle uğraşıp sonrasınra toparlayıp ani fps düşüşlerinde kıvrandığım ve sonunda 210 fps altına düşmediğim bir süreçte neler yaşayıp neler keşfettiğimi anlatmak istedim. Biraz da hikaye gibi olarak inişli çıkışlı bir dönem. Bir çay alıp okuyabilirsiniz. İyi okumalar. Aslında çoğumuzun bildiği şeyler, ama bu süreçte pek çok yerde yazmayan birkaç detayı da kendim deneyip gördüm. 

İlk olarak unreal engine e 1 sene önce başladım ve ilk öğrenme çalışmalarım orta çağ şehir kurma üzerineydi. Hazır assetler ile bir deneme sahnesi yaptım ve youtube a liste dışı arkadaşlara göstermek için yüklemiştim. o zamanlar daha konsol komutlarını bilmiyordum net fps i ve statları bilemeyeceğim. Oyun proje dosyaları da yok. Ama videodan anladığım 10 FPS civarlarında geziyor. İşte video:

Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Assetler hazırdı ve low polydi bunu biliyorum. Landscape auto materialdi ama sadece dağ yamacı ve çim vardı. Sistemim şöyleydi:

İşlemci: İntel i5 3470 3.2Ghz->3.4Ghz 4 çekirdek 4 thread 6mb cache.
Ram: 6Gb
Ekran kartı: Nvidia Gtx 750 Ti 2gb vram.

Bu testten sonra dedim ki bu ekran kartı bile bir oyun yapılamaz işkence. Ben de o dönem gidip bir ekran kartı aldım. AMD 5600XT 3400 TL ydi sanırım. Fiyat performans olarak bunu seçtim bir daha fps sorunu yaşamak istemiyordum. Youtube ta RTX 2060 tan iyi, RTX 2070 den kötü performans gösteriyordu. Onların fiyatını düşününce gayet makuldü benim için.

Neyse aldım almasına ama fps değerlerim hani 150-200 olmuyor? 60-70 taş çatlasa. Baked light kullandığımda 120 lere çıkabiliyor ama ben gece gündüz döngüsü istiyorum napcaz? 60-70 de aslında sorun da yok ama 5-6 saniyede bir ani fps drop oluyor 15-12 fpslere ve topdown kamera hareketinde sinir bozucu bir kesinti yapıyor. O zaman dedim ki bu sadece ekipmana bağlı değil. Optimizasyon konularını araştırmaya başladım.

Benim için işe yarayan optimizasyonları önem sırasız şekilde yazacağım. Sıralamam keşfetme sırama göre olacak.

Optimizasyon 1 Early-Z Pass-> İlk olarak performansı en kötü etkileyen şeyin çimler olduğunu okudum. Bir sonraki projemde de bolca çim kullanıyordum. Proje ayarlarında early z-pass ı aktif edince masked tipindeki materyaller tek sefer ve ilk olarak işleniyor ve ondan sonra diğerlerine geçiliyormuş. Bu da bolca masked material sahibi asetlerin olduğu sahnelerde performans artışı sağlıyormuş. Bu sefer yine bir şehir kurma oyunu ama third person bakış açısıyla. O oyunda 40-45 FPS alıyordum. Early z pass aktif edince fps 80-85 e çıktı. Her oyunumda bu kadar performans değişimi olmadı tabi sahnede ne kadar masked material olduğuna bağlı. Bir de denize bakarken fps daha yüksekken early-z pass sonrası denize baktığımda öncekine göre 10 fps düşük alıyordum ama her türlü daha iyiydi genel olarak. O oyunun sahnelerin videosu da var:) Animasyonlar uydurma rastgele animasyonları seçmiştim ona aldırmayın. Anim notify kullanmak için bir animasyon seçmem gerekti.

Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Optimizasyon 2 Runtime Virtual Texture-> İlk ticari oyunuma girişmiştim. İlk oyun gibi topdown orta çağ şehir kurma oyunuydu. Ama nedense topdown bakış açısında hiçbir zaman third person ya da first person FPSlerini yakalayamıyordum. 40-50 FPS lerde kalıyordu. Üstten görünüm oyun olduğu için landscape materlali kompleks olmak zorunda kalıyordu çünkü varyaysyonlar ve yollar için farklı farklı katmanlar oluyordu.

Kıvrımlı yollar yapmam gerekiyordu oyun için ve decal ile bu mümkün değil. Küçük küçük decal yapıp bir spline üzerinde spawn edersem oluyordu ama kısa sürede ekranda bine yakın decal oluyor ve fps aşırı düşüyordu. Bunun çözümünü çok araştırdım ve sonunda Runtime Virtual Texture e ulaştım. Ama buna ulaştığımda öğrendiğim bir şey de runtime virtual texture kullanan materyallerin her tickte her pixelin hesaplanmasına gerek kalmıyordu. Bir kere hesaplanıp ram e atılıyor ve sadece değişiklik olursa yeniden hesaplanıyordu. Bu da sana baked lighting gibi bir performans artışı sağlıyordu. Denedim ve gördüm ki gerçekten de runtime virtual texture kullandığım zaman 80-90 FPSleri alıyordum ve spline mesh componentin materyalini bir virtual texture e yazdırdığım zaman hem kompleks materyalden kurtuluyor hem de runtime olarak kıvrımlı yollar inşa ediyordum.

AMA bir sıkıntı var. Third person ya da first personda görmediğim bir sorunu topdown da görüyorum. Runtime virtual texture landscape i ufak parçalara bölerek hafızada tutuyor. Her birini farklı olarak işliyor. Topdown da gördüğüm şuydu. Bazı bölümler geç işleniyor ya da bulanık görünüyordu. Bazen glitchler oluyor ve beni baya sıkıyordu. Bu şekilde ticari bir oyun yapılamaz. Görsel buglar oluyordu sürekli. Bir diğer engel de kar yağdığı zaman dinamik olarak zemini karla kaplamam gerekiyor yavaş yavaş. Runtime virtual texture tekrar işleme yaparken bu bir tickte değil 2-3 saniyesini alan birşeydi ve yine bir bug gibi duruyordu. Bununla istediğim dinamik dünyayı yapamazdım.

O zaman çok zekice bir şey geldi aklıma ve sadece yolların olduğu yerleri runtime virtual texture olarak kullanıp, geri kalan yerleri auto material kullanmakdı. Runtime virtual texture alpha kanalını material blendde alpha olarak kullandım. Çimlerin olduğu yerler artık düzeldi ama yolların olduğu kısımlar yine bölüm bölüm görsel buglara yem oluyordu. Ben de bu sefer RVT'yi sadece alpha olarak kullanmak istedim. Yolu auto material ye taşıdım. Spline mesh componentin materyalini kırmızı yapıp RVT ye yazdırıp bunu da alpha olarak kullandım. Artık Ne yollar ne de çimler RVT materyali kullanmadığı için dinamik olarak yağmur kar efekti alıyordu. Tek sorun yol inşa ederken görsel buglar oluyordu çünkü her mouse hareketinde o bölümdeki RVT yeniden işleniyordu ve bu da birkaç saniye bulanık olmasına neden oluyordu. Hangi RVT ayarını değiştirdiysem sonuç alamadım. Ben de yol inşa ederken decal kullanıp, yol inşası bitince tek tickte RVT işlenip alpha olarak kullanılmasını sağladım. 

TADAA işte full dinamik bugsuz kıvrımlı yollarım artık çalışıyor. Ama RVT ile optimizasyon olarak elime hiçbirşey geçmedi çünkü landscape materyali yine yüzde yüz auto materyal kullanıyor. Geldik mi yine 40-50 FPSlere. Ama olsundu çünkü RVTnin sonsuz kullanım fırsatı olduğunu gördüm. Third person ya da first person gibi çok geniş alanı net göremediğin yerlerde buglar dert değil orada çok rahat kullanılır ama topdownda değil. Ortalama bilgisayarları biri buglarla karşılaşır. Buglar build aldığımda da vardı bu arada merak edenler olursa.

Optimizasyon 3 Shader complexity - Triangle sayısı ve LOD'ler-> Oyunum 40-50 FPS arası oynanıyor. Build aldığımda 60 FPS e çıkıyordu maksimum. Arada bir 12-14 FPS de düşüyordu o anlarda tekliyordu oyun ama bunu çözerim dedim. Oyunun basit mekaniği hazır olunca açıp şehri biraz büyüteyim nasıl görünüyor dedim. Oyunun 5-6. dakikalarında artık arada bir 12-14 e düşen fps artık 5 saniyede bir düşüyordu çok sinir bozucuydu. Benim ekran kartıma sahip biri oyunu böyle oynayacaksa vay halime. Dedim bu bu iş ekran kartında materyallerde değil başka şeyler de var işin içinde. Yine optimizasyon konularına daldım. Stat rhi, stat scene rendering, profile gpu gibi pek çok şeyi öğrenip irdeledim.

İlk olarak dikkatimi çeken şey RHI da ekranda 4-7 milyon triangle olduğunu gördüm. Yuh, oha, brrrüsssst. Kullandıklarım low poly assetler nerden çıkıyor bu kadar triangle. En cafcaflı evim 35 bin triangle. Assetler bu kadar düşük olunca ve hala triangle yüksek olunca LOD lere yöneldim düşürmek için ama yok nerden geliyor bu kadar triangle dedim. Wireframe modunda baktığımda landscape baya bir sıkıntıydı. Herşeye LOD yapmıştım ama Landscape'e yapmamıştım çünkü onuna da LOD yapılabileceğini bilmiyordum. Topdown bakış açısındasın ve landscape in büyük bölümünü görüyorsun. Ve bilin bakalım shader complexity e bakınca neresi kırmızı? Tabi ki landscape. Landscape e LOD yapmadan gözden çıkarabileceğim tüm katmanları parametreleri çıkardım landscape auto materialden. Sadece deniz kıyısı, çim, yol ve kar katmanı kaldı. Shader complexity kırmızıdan koyu yeşile döndü ve artık 60-65 FPS alıyordum. 

Sonra Landscape e nasıl nereden LOD yapacağımı öğrendim. Direkt detaylarında LOD bölümü var ve 3 tane girdisi var. Bu 3 girdi ile oynadım biraz deformasyonu kabul edilebilir seviyede tutup. RHI da triangle count artık 300 binlerdeydi. Kaç milyon miylar triangle kaplıyordun yahu sen. Artık FPS 80 lerdeydi. İyiydi güzeldi ama LOD'lerin bir dezavantajı olduğunu bilmiyordum. Eminim çok az kişi biliyordur. 

Optimizasyon 4 Draw Calls ve instanced mesh çeşitleri -> Artık 80 FPS lere çıkmıştım ama ani FPS düşüşleri yine oluyordu. Ben de bunu en az seviyeye çekmek için elimden ne geliyorsa yapacaktım. 100 FPS den aşağı düşmek istemiyordum. Yine yazdım konsol komutlarımı ve sırada Drawcalls vardı. Sahnede sadece deniz, landscape, ağaçlar ve taşlar varken hiç ev yokken kaç drawcall beklersiniz? Benim 800 drawcall'um vardı. Yine yuh yuh yine brrrssst. Neyin drawcallı bu bu kadar. Aslında modern pc ler binlerce Draw Call ile başa çıkabilir ama benim sahnemde birşey yokken nasıl bu kadar yüksek o şaşırttı. Draw Call hakkında bildiğim şuydu 1 Draw call => 1 Mesh-1Material. Yani her bir mesh için bir draw call ve o mesehe ait her ekstra material için 1er draw call daha. Yani tek materialli bir taş için 1 draw call çağırılıyor. Tabi mesh dışında farklı pass ler de var onları ayrı tutalım. Peki draw call nereyi ilgilendiriyor CPU'yu. Stat unit yaptığımda game thread 4ms, draw thread(draw call lar burada) 23ms, GPU 23 ms gibiydi. Oyun oynarken GPU kullanımı %25lerde CPU kullanımı %100 lerde. Bu ne demek? Benim GPU ile sorunum yok aslında sorun CPU da. 

O ana kadar oyun için en önemli bileşenin GPU olduğunu sanıyordum ve şimdi CPU da bir okadar önemli onu anladım.

O an için procedural fooliage spawner kullanıyordum. 4 farklı ağaç, 2 farklı taş ve 1 tane bush vardı. Çok da sık değildi ekranda. Acaba dedim bu procedural fooliage spawner bunları instanced fooliage mesh olarak kullanmıyor mu dedim. Nedir bu instanced mesh falan?

Şöyle ki sahnedeki her bir mesh için ayrı ayrı draw call çağırılır. Sen aynı meshleri instanced static mesh olarak birleştirirsen CPU ya diyorsun ki. Sahnede 300 tane aynı materyale sahip aynı static mesh var. Bunların hepsini bir paket yapıver diyorsun. O da hepsini 1 draw call yapıyor. Efsane performans kazancı CPU da. Ama bu kadar basit mi?

Test ettim tüm fooliage silersem draw call ve FPS kaç olacak diye. Bir sildim. Drawcall 25 ve FPS 160. Suçluyu buldum. Fooliage ler.

Bir deneme yaptım ve şimdi yaptığım denemenin sonucu ilginizi çekebilir ve bilmediğiniz bir şey öğrenebilirsiniz.

1-)Sahneye 25 tane aynı ağaçtan attım ve Draw Call a baktım. Bu ağaçlarda 4 materiyal var. 2 si yaprak ve gövde için. Biri düşük LOD için biri de imposter. Draw Callın 125 civarına çıkmasını beklersiniz. Aynen de öyle oldu. 110-130 arası değişiyordu bakış açısına göre.

2-)Bu ağacı procedural fooliage spawner a yükledim ve 23-25 tane spawn edecek şekilde ayarladım aynısını. Bu sefer hepsini tek bir mesh gibi alıp 4 drawcall ekleyip 30 civarına çıkmasını bekliyoruz değil mi drawcall'ın. Ama 85 civarına çıktı. Aklım karıştı hani bunlar instanced değil mi?

3-) 2 de uyguladığım bu sefer landscape fooliage tool da yaptım. Sonuç yine 85 drawcall!! 3-4 çeşit ağaç, 2-3 çeşit taş ve bush ekleyip tüm dünyayı doldurunca oluyor sana 800-900 drawcall. FPS'im de 160 tan 80 lere düşüyor. 

4-)Ağaç çeşidini teke indirdim. 1 tane de taş ekledim. Tüm sahneyi aynı yoğunlukla doldurdum. Sonuç 600 drawcall ve 100FPS. İşte ilginç keşfim şimdi geliyor.

5-)Acaba bu draw calllar LOD'lerden mi geliyor? Çünkü mantık olarak her bir LOD farklı bir mesh gibi davranmalı çünkü triangle yapıları farklı. Aynen de öyle oluyormuş Ben de fooliage deki tüm LODleri sildim. Yaptığım assetlerdeki tüm LODleri sildim. Oyunda LOD kullanan tek şey landscape. Bir optimizasyon kuralını komple iptal ettim.  Sonuç? Oyun oynarken evler dahi varken draw call 250, FPS 130..

Burda anladığım instanced statich meshlerde LOD ler bazı oyun türlerinde faydadan çok zarar veriyor. Bu sancılı sürecimde yeni ekran kartından sonra 40 FPS den 130 FPS e deneme yanılma test etme yöntemleri ile geldim. 

Son olarak geçenlerde işlemcimi yeniledim. Çünkü shader complie süreleri uzundu ve artık ısınma sorunları ve bundan kaynaklı ani fps düşüşlerinden kurtulmak istiyordum. Gittim bir hınçla AMD FX 5600 aldım fiyat performans olarak yine en iyilerden biri. Tabi bununla birlikte anakart ve ram de almam gerekti. Bana 5600 TL ye daha mal oldu. Ama şimdi tüm CPU işlemleri 5 kat daha hızlı. Oyunda ani FPS düşüşüyo yok. Stabil 220-260 FPS lerde gidiyor dinamik ışık ve üstten görünümde. Unreal engine 5 te lumenli sahnelerde ek ışık olduğunda 50FPS olmadığında 75 FPS lerde. Fena sistem olmadı ama eski işlemcimden sonra cennet gibi oldu. Son olarak az önce 220-260 FPSli, kötü işlemciden kaynaklı ekstra ektra optimize edilmiş oyunun videosunu da koyuyorum.

Ekstra ektra derken harbiden öyle. Deniz materyali çok pahalı olduğu için onu bile 50 parcaya bölüm instanced static mesh yaptım çünkü tüm koca denizi renderlıyordu freeze render ile baktığımda. Şimdi sadece kameranın gördüğü kadarını renderliyor ve tek drawcall ile. Bana bunu bile yaptırttı eski CPU.

Umarım faydalı bir yazı olmuştur baya bir zamanımı aldı yazmak. Yazarken keyif aldım inşallah siz de okurken almışsınızdır. Herkese iyi günler!

Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.


https://www.youtube.com/watch?v=UIbOIcLuTQ0
 
hocam öncelikle çok teşekkür ediyorum kıymetli bilgileriniz için bazı sorularım olacak size 
öncelikle medieval house assetslerini nerelerden buldunuz link verebilir misiniz?
ağacı kesince düşmeyi, düştükten sonra toplamayı ve araca koymayı, koyduktan sonra aracı taşımayla ilgili videolar var mıdır?
bunları merak ediyorum eline emeğine sağlık çok teşekkür ediyorum tekrardan.
 
enes' Alıntı:
hocam öncelikle çok teşekkür ediyorum kıymetli bilgileriniz için bazı sorularım olacak size 
öncelikle medieval house assetslerini nerelerden buldunuz link verebilir misiniz?
ağacı kesince düşmeyi, düştükten sonra toplamayı ve araca koymayı, koyduktan sonra aracı taşımayla ilgili videolar var mıdır?
bunları merak ediyorum eline emeğine sağlık çok teşekkür ediyorum tekrardan.


rica ederim ne demek. İlk videodaki medieval evler epic games magazasından almıştım her ay ücretsiz verdiği paketlerden biriydi o dönem. Diğer oyunlardaki assetleri blender ile yaptım. Ağacı kesince düşme olayı kolay ama biraz da karmaşık.

1-)Ağaca bir can veriyorsun. Her vurduğunda o can düşüyor. Sıfırın altına düşünce ağaç için set simulate physics deyip karakterin baktığı yönde force uyguluyorsun ağaca. Ağaç da bu sırada gövdesinin yerden yüksekliğini hesaplıyor tickte. Yere belli bir miktardan fazla yaklaşınca kendini yok edip gövdesinin ortasına denk gelen yerde kütükleri spawn ediyor. Basitçe sistem böyleydi.

Ama bir sorun var. Her ağacı bir aktör olarak sahneye koyarsan performans kötü olur her biri çünkü bir draw call olacak vs. Fooliage olacak instanced fooliage mesh olarak koymalısın performanstan kazanmak için. Baltayı salladığında baltanın çarptığı şeyi alıp cast to instanced fooliage mesh diyorsun. Onu alıp get static mesh diyorsun. Bir de get instance transform diyorsun. Sonra o meshin ismine göre yarattığın aktörü aldığın transform ile spawn edip remove instance diyorsun.

Yani olay şu: Baltayı salladın -> Bir instanced fooliage mesh e çarptı-> Bu fooliage mesh in ismini ve trasformunu aldın -> Bu mesh ismi hangi aktöre aitse(5 çeşit ağaç aktörü var diyelim hangisine aitse) o aktörü spawn ediyorsun-> baltanın çarptığı instanced fooliage meshin o instance sini dünyadan siliyorsun. Sonrası ilk anlattığım olay.

2-) Arabada taşıma olayı yeni öğrendiğim için 1 haftamı almıştı. O araç fizik simule eden bir araç yani herhangi bir kod yok içinde yer çekimine fizik kurallarına göre hareket ediyor. 2 tane teker tanımlaman lazım tabi youtube videoları vardır. Tuttuğun yere gidip F e basınca 2 saniyeliğine set simulate physics false diyorsun. Tutamaçları bel hizasına getirecek dönme hareketini yaptırıyorsun. Sonra tekrar set simulate physics true diyorsun ve karaktere constraint ile bağlıyorsun. O noktadan sonra sen nereye gidersen o da geliyor. Çok kesin dönüş yaparsan constrainti koparacak bir fonksiyon da eklemiştim. 

Kütük ya da taş koyma olayı da yanına gidip F e basında ne taşıyorsan o aktöre ait taşıma için modellenen static meshi alıp araçta eklemiş olduğum static mesh componentte set statik mesh component diyorsun. Miktarına göre sıradaki static mesh componentine geçiyor.

Muhtemelen bunları anlamadın çünkü başlangıç için çok karmaşık şeyler bunlar. Biraz daha basitten başla. Sonra tekrar bunları oku o zaman ne kadar kolaymış dersin.

Ayrıca ağacı kesince düşmeyi, düştükten sonra toplamayı ve araca koymayı, koyduktan sonra aracı taşımayla ilgili videolar var mıdır? -> Her türlü video vardır ararsan. Parça parça ara youtube da. ue4 tree falling de bu kadar basit bunlara erişmek.
 
çok sağol hocam çok teşekkür ederim verdiğin cevaplar inan çok değerli benim için. Bir sorum daha var bunun cevabını bulamadım Ben tek bir assets için değil de birden çok assets için fps'i çok etkilememesi için triangles ve vertices'i düşürmek istiyorum. Yani özetle toplu olarak triangles ve vertices'i düşürebilir miyim? Tek tek assets'in içine girip düzeltmek istemiyorum.
 
enes' Alıntı:
çok sağol hocam çok teşekkür ederim verdiğin cevaplar inan çok değerli benim için. Bir sorum daha var bunun cevabını bulamadım Ben tek bir assets için değil de birden çok assets için fps'i çok etkilememesi için triangles ve vertices'i düşürmek istiyorum. Yani özetle toplu olarak triangles ve vertices'i düşürebilir miyim? Tek tek assets'in içine girip düzeltmek istemiyorum.


Vardır illa bir yöntem unreal engine resmi youtube kanalına bir bak araştır LOD konularını