Source haritalarında su: doğru kurulum ve hataların çözümü
Source ve GMod haritalarında su: su brush'ının yapısı, pahalı ve ucuz su, water_lod_control, cubemap'ler ve render hatalarının çözümleri.
Source Engine'de su, üst yüzeyi bir su materyali taşıyan, diğer tüm yüzeylerine ise tools/toolsnodraw verilen bir world brush'tır. Ayrıca bir water_lod_control, katı brush'lardan oluşan kapalı bir kabuk ve ucuz render yolu için env_cubemap entity'leri gerekir. Su çoğunlukla şu dört nedenden biri yüzünden yanlış render edilir: brush bir entity'ye bağlıdır, haritada leak vardır, farklı yüksekliklerdeki iki su yüzeyi aynı yerden görünür ya da cubemap'ler eksiktir.
Su brush'ı nasıl kurulur
- Dipten yüzeye kadar tüm su hacmini dolduran bir brush oluştur.
- Brush'ın tamamına
tools/toolsnodrawuygula. - Yalnızca üst yüzeye bir su materyali ver, örneğin
nature/water_canals_water2. - Brush'ı world brush olarak bırak. Onu
func_detailya da başka bir entity'ye bağlama. - Havuzu katı world brush'larla çevrele ve haritaya bir
water_lod_controlyerleştir.
Bu kurallar bir mekanizmadan kaynaklanır. Su materyalleri %compilewater 1 parametresini taşır. Bunun üzerine VBSP visleaf'leri su yüzeyi boyunca keser ve her su hacmi için tam olarak bir yükseklik kaydeder. Üst yüzeyin yatay olmak zorunda olmasının ve bunun yalnızca world brush'larla çalışmasının nedeni budur: func_detail'e bağlı bir su brush'ıyla yapılan bir testte GMod'un VBSP'si BSP'ye hiçbir su hacmi yazmadı (leafwaterdata 0).
Su ayrıca katı değildir. Bir su brush'ı bir dış duvarın yerini alırsa VBSP **** leaked **** bildirir. Açıklığı nasıl bulacağın harita leak hatasını düzeltme yazısında anlatılıyor.
Yan yüzeyler nodraw kalır, çünkü aksi halde yüzey olarak derlenirler. Altı yüzeyin hepsinde su materyali olduğunda test 40 yerine 60 yüzey üretti. Alttan görünümü VBSP, materyalin $bottommaterial parametresinden kendisi oluşturur.
Pahalı ve ucuz su
Aynı su üç şekilde çizilebilir:
| Render | Yansıma | Yüzeyin altındaki görünüm | Ek render geçişleri |
|---|---|---|---|
| Pahalı | Gerçek zamanlı | Kırılma | İki, yansıma ve kırılma için |
| Orta | Cubemap | Kırılma | Bir |
| Ucuz | Cubemap | Kırılma yok | Yok |
Hangi varyantın geçerli olacağına motor her karede karar verir. Valve Developer Community wiki'si (VDC) yalnızca pahalı ve ucuz ayrımı yapar; "orta", aradaki durum için bizim verdiğimiz addır. Aşağıdaki sıra, Source SDK 2013'ün yayımlanmış istemci kodundan gelir. GMod kendi motor dalını kullanır, bu yüzden ayrıntılar farklı olabilir.
- Materyal
$forcecheap 1ayarlıyorsa su her zaman ucuzdur. Bir örneknature/water_canals_cheap001materyalidir. - Gerçek zamanlı yansıma, materyalde bir
$reflecttextureve buna ek olarak ya$forceexpensive 1ya dar_waterforceexpensive 1oyuncu ayarını gerektirir. HL2 ile gelen su materyallerinin çoğu$forceexpensive 1ayarlar,nature/water_canals_water2de bunlardan biridir. - Gerçek zamanlı yansıma yoksa mesafe belirleyici olur.
water_lod_controlentity'sinin bitiş mesafesinden itibaren su ucuz çizilir, bunun altında ise kırılma ve cubemap ile.
Yani render biçimini esas olarak materyal seçiminle belirlersin. Cubemap yansımasının yine de her zaman çalışması gerekir, çünkü orta ve ucuz su buna başvurur. Pahalı su, sahnenin büyük bölümlerini üç kereye kadar çizer. Bu tür maliyetleri nasıl ölçeceğin GMod harita performansını optimize etme yazısında gösteriliyor.
water_lod_control doğru nasıl kullanılır
Bu entity, haritadaki tüm su için motorun hangi kamera mesafesinde ucuz suya geçeceğini kontrol eder.
| Keyvalue | Hammer'daki adı | Varsayılan |
|---|---|---|
cheapwaterstartdistance | Start Transition to Cheap Water | 1000 |
cheapwaterenddistance | End Transition to Cheap Water | 2000 |
Her iki değer de birim cinsindendir. Başlangıç ile bitiş arasında materyal yumuşak bir geçiş yapar; bunun için, hazır gelen su materyallerinde olduğu gibi WaterLOD proxy'sini içermesi gerekir.
Entity eksikse derleme durmaz. VBSP varsayılan değerlerle bir tane oluşturur ve şunu yazar:
Water found with no water_lod_control entity, creating a default one.
Mesafeleri haritana göre ayarlamak için yine de kendin bir tane yerleştir. Ama çok şey bekleme: SDK koduna ve VDC'ye göre mesafe, gerçek zamanlı yansıması olan materyallerde geçerli değildir.
Farklı yüksekliklerde su
Kuralı VDC söyler: pahalı suda bir PVS içinde, yani bir yerden görülebilen alanların kümesinde, yalnızca tek bir su yüksekliği olabilir. Nedenini SDK kodu gösterir: istemci her kare için tek bir görünür su hacmi belirler ve yansıma ile kırılmayı tam olarak o yükseklik için render eder. Farklı yükseklikteki ikinci bir yüzey bu durumda yanlış düzlem için hesaplanmış görüntüler alır. Bunun oyunda tam olarak nasıl göründüğünü test etmedik. Bir uyarı da çıkmaz: farklı yüksekliklerde iki havuzu olan bir test haritası hiçbir mesaj olmadan derlendi.
- Görünür alan başına tek yükseklik. Farklı yüksekliklerdeki havuzları world brush'larla ayır ki hiçbir zaman aynı PVS'e düşmesinler.
- Aynı yüksekliği kullan. Kural yalnızca farklı yükseklikleri ilgilendirir. Aynı yükseklikteki birden fazla havuz yansıma düzlemini paylaşır.
- Türleri karıştırma. VDC'ye göre pahalı ve ucuz su da aynı PVS'i paylaşmamalıdır. İki yüksekliğin birlikte görünür kalması gerekiyorsa oradaki tüm suya
$forcecheap 1içeren bir materyal ver. Bu su, cubemap'i üzerinden yansıtır.
Cubemap'ler, 3D skybox ve displacement'lar
Cubemap'ler. Su materyalleri $envmap env_cubemap içerir. Orta ve ucuz su bununla en yakındaki env_cubemap entity'sini yansıtır. Su bulunan her alana en az bir tane yerleştir ve son derlemeden sonra buildcubemaps komutunu çalıştır. O zamana kadar BSP yalnızca skybox texture'ından yapılmış bir yedek içerir. İzlenecek yol cubemap yansımalarını düzeltme yazısında anlatılıyor, HDR'nin temelleri ise Source Engine ışıklandırma rehberinde yer alıyor.
3D skybox. SDK koduna göre 3D skybox, kendine ait yansıma ve kırılma olmadan tek bir geçişte çizilir. Orada $forcecheap 1 içeren bir materyal kullan. VDC'ye göre skybox'taki ucuz su, haritadaki pahalı suyla yan yana çalışır. Yükseklik ölçekten çıkar, çünkü sky_camera ana haritanın origin'ini temsil eder: su orada Z = 128'deyse ve sky_camera ölçeği 16 ise skybox'taki yüzeyin yeri sky_camera entity'sinin 8 birim üzeridir. Öte yandan SDK koduna ve VDC'ye göre ana haritadaki gerçek zamanlı yansıma 3D skybox'ı değil, 2D skybox'ı gösterir. VDC, CS:GO ve Garry's Mod için bunu değiştirmesi amaçlanan $reflect3dskybox adlı bir materyal parametresi listeler. Bunu test etmedik. Daha fazlası 3D skybox rehberinde.
Displacement'lar. Displacement'lardan yapılmış bir kıyı da tıpkı suyun kendisi gibi haritayı kapatmaz. Su brush'ını arazinin altında devam ettir ve ikisinin altına katı bir world brush koy. Nodraw'ı yalnızca arazinin onu gizlediği yerde kullan: VDC, suyu nodraw kapattığında oluşan bir iz bırakma efektine karşı uyarır. Daha fazlası Hammer'da displacement yazısında.
Tipik hatalar ve nedenleri
| Belirti | Neden | Çözüm |
|---|---|---|
| Su görünmüyor ya da doğru render edilmiyor | Haritada leak var ya da su brush'ı bir entity'ye bağlı | Leak'i kapat, brush'ı Tools → Move to World ile geri al |
| Su opak ya da yansıması bozuk | Aynı PVS içinde ikinci bir su yüksekliği var ya da bir func_viscluster veya areaportal su yüzeyini kesiyor | Yükseklikleri ayır, func_viscluster ve areaportal'ları yüzeyden uzak tut |
| Yansıma siyah, mor-siyah damalı ya da fazlasıyla parlak | Cubemap'ler eksik ya da etkin mod için oluşturulmamış | env_cubemap yerleştir, buildcubemaps komutunu LDR ve HDR için çalıştır |
| Su uzakta birdenbire farklı görünüyor | Gerçek zamanlı yansıması olmayan su, bitiş mesafesinden itibaren ucuza geçiyor | water_lod_control içindeki mesafeleri artır, cubemap'leri oluştur |
**** leaked ****, çizgi suyun içinden geçiyor | Su dış sınır olarak kullanılmış | Havuzun çevresine katı world brush'lar |
Su uzaktan tamamen kayboluyorsa bunun belgelenmiş tek bir nedeni yoktur. Önce ikinci bir su yüksekliğinin görüş alanına girip girmediğini kontrol et. Ayrıca compile log'u Map Scanner aracına yapıştırabilirsin. VBSP, VVIS ve VRAD log'larında asıl nedenleri, zincirleme hataları ve bunlara uygun çözümleri tespit eder.
Sık sorulan sorular
Su seviyesi yükselip alçalabilir mi?
Evet, func_water_analog ile. Bu entity bir su brush'ını Open, Close ve SetPosition input'larıyla hareket ettirir. Normal su shader'ı orada çalışmaz, çünkü sabit visleaf'lere ihtiyaç duyar. nature/water_movingplane gibi bir materyal kullan. Yalnızca cubemap üzerinden yansıtır.
Su oyuncuları ve prop'ları da yansıtır mı?
Yalnızca materyal $reflectentities 1 ayarlıyorsa ya da oyuncu r_waterforcereflectentities 1 ayarını açmışsa. Aksi halde gerçek zamanlı yansıma yalnızca dünyayı ve gökyüzünü içerir.
Özel bir su materyalinde neler olmalı?
En azından %compilewater 1, $abovewater, $fogcolor, $bottommaterial ve $envmap env_cubemap. $abovewater ya da $fogcolor eksikse shader konsolda uyarır. $bottommaterial eksikse VBSP uyarır. Uzaktaki yumuşak geçiş için WaterLOD proxy'sini ekle.