Unity Shader Boyutu Optimizasyonu

Yayınlandı: 06 Eylül 2020 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde

Merhabalar,

Daha önce Unity projenize gerek Asset Store‘dan gerekse başka bir yerden büyükçe bir shader paketi eklediyseniz, oyunun hem build alma süresinin hem de boyutunun ciddi anlamda arttığına şahit olmuş olabilirsiniz. Ben bu duruma Toony Color Pro 2 asset’ini projeme eklediğimde denk geldim: beraberinde gelen shader, Unity’nin tüm scriptable render pipeline‘larını destekliyordu: LWRP/URP, HDRP ve varsayılan olarak gelen built-in. Ben LWRP/URP veya HDRP kullanmadığım halde shader bu render pipeline’lar için de build alınıyordu ve build boyutu 50 MB artıyor (iOS), build süresi de 1 saat uzuyordu (build alınan shader’lar cache’lendiği için sonraki build’lerde bu süre tabi ki çok daha kısa oluyor).

Bu durumla ilgili napabilirim derken Unity’nin şu blog yazısına denk geldim ve oradan öğrendiğim teknikle bir editör script’i yazdım: https://gist.github.com/yasirkula/d8fa2fb5f22aefcc7a232f6feeb91db7

Bu editör script’i, shader’larımdaki kullanmadığım özellikleri kapatıyor ve shader’ların boş yere LWRP/URP ve HDRP için build alınmasının önüne geçiyor (bu işleme shader stripping deniyor). Bu şekilde build sürem birkaç dakikaya indi ve build boyutu ise shader’ın farkına varılmayacak düzeylere düştü.

Daha fazla bilgi için yazının devamını okuyabilirsiniz…

Bu editör script’ini, Unity’nin varsayılan olarak gelen built-in render pipeline‘ı ve varsayılan olarak kullanılan Forward Rendering (çoğu mobil projede bu kullanılır) için optimize ettim. Eğer LWRP/URP, HDRP veya Deferred Rendering kullanıyorsanız, script’ten benim kadar verim alamayabilirsiniz.

Yapmanız gereken, projenizin Editor klasöründe (bu klasör yoksa oluşturun) ShaderStripper adında yeni bir C# script oluşturmak ve script’in içeriğini linkteki kodla değiştirmek.

Bu editör script’i, Unity’nin IPreprocessShaders interface’ini kullanıyor; yani build esnasında Unity otomatik olarak bu script’in OnProcessShader fonksiyonunu çağırıyor. Ben de bu fonksiyonda istemediğim shader özelliklerinin build alınmasını engelliyorum.

Shader’ın nasıl çalıştığını anlatacak olursam:

  • Öncelikle HiddenUnlitLegacy Shaders ve Particles kategorilerindeki shader’ları hiç ellemiyorum. Bu shader’ların zaten build süresine veya boyutuna kayda değer bir etkisi olmuyor ve özellikle Hidden kategorisindeki shader’ları Unity farklı farklı yerlerde kullandığı için, nolur nolmaz bu shader’lara dokunmamak en iyisi
  • Deferred Rendering kullanan shader’ların build alınmasını engelliyorum (PassType.Deferred, PassType.LightPrePassBase, PassType.LightPrePassFinal). Eğer siz deferred rendering kullanıyorsanız, bu koşulları if’ten silin
  • Shader’ların LWRP/URP ve HDRP için build alınmasını engelliyorum (PassType.ScriptableRenderPipeline, PassType.ScriptableRenderPipelineDefaultUnlit). Eğer siz bu scriptable render pipeline’lardan birini kullanıyorsanız, bu koşulları if’ten silin
  • Shader’ların light cookies özelliklerini kapatıyorum (ışıklara Cookie verildiğini çok ender gördüm; bu ender durumlarda da genelde korku oyunlarındaki el fenerine veriliyordu)

Shader optimizasyonundan daha da verim almak için kurcalayabileceğiniz başka birkaç ayar daha var:

  • Eğer Fog (sis) kullanmayı planlamıyorsanız, Edit-Project Settings-Graphics-Fog Modes‘un değerini Custom yapın ve karşınıza gelen 3 fog seçeneğini de kapatın. Artık shader’ların Fog özelliği kapanacak
  • Eğer projenizde GPU instancing‘den faydalanmaya gerek yoksa (sahnede aynı objenin binlerce klonunu aynı anda render almıyorsanız), Edit-Project Settings-Graphics-Instancing Variants‘ın değerini Strip All yapın. Böylece shader’ların GPU instancing özelliği kapanacak
  • Eğer Forward Rendering kullanıyorsanız, Edit-Project Settings-Graphics-Built-in Shader Settings‘teki DeferredDeferred Reflections ve Legacy Deferred özelliklerini kapatın
  • Edit-Project Settings-Graphics-Built-in Shader Settings‘teki Motion VectorsLight Halo ve Lens Flare özelliklerinden kullanmadıklarınızı kapatın (Motion Vectors özelliği motion blur’da kullanılır, diğerleri ise Halo ve Flare component’lerinde kullanılır)

Eğer script’in başındaki #define SHADER_COMPILATION_LOGGING satırının comment’ini kaldırırsanız, build alınan tüm shader’ların listesini build’dan sonra UNITY_PROJESİ_KONUMU/Library/Shader Compilation Results.txt dosyasında bulabilirsiniz.

Eğer script’in başındaki #define SKIP_SHADER_COMPILATION satırının comment’ini kaldırırsanız, oyunu build alırken shader’ların hiçbiri build alınmaz ancak bu shader’lar yine de Shader Compilation Results.txt dosyasında listelenirler. Hangi shader’ların build alındığını öğrenmek istiyor ama shader’ların gerçekten build alınmasını beklemek istemiyorsanız, bu satırın ve bir önceki bahsettiğim satırın comment’lerini kaldırabilirsiniz.

Böylece bu dersin sonuna geldim. Başka derslerde görüşmek üzere!

Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.