Mapping ve Hammer

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

  1. Dipten yüzeye kadar tüm su hacmini dolduran bir brush oluştur.
  2. Brush'ın tamamına tools/toolsnodraw uygula.
  3. Yalnızca üst yüzeye bir su materyali ver, örneğin nature/water_canals_water2.
  4. Brush'ı world brush olarak bırak. Onu func_detail ya da başka bir entity'ye bağlama.
  5. Havuzu katı world brush'larla çevrele ve haritaya bir water_lod_control yerleş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:

RenderYansımaYüzeyin altındaki görünümEk render geçişleri
PahalıGerçek zamanlıKırılmaİki, yansıma ve kırılma için
OrtaCubemapKırılmaBir
UcuzCubemapKırılma yokYok

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.

  1. Materyal $forcecheap 1 ayarlıyorsa su her zaman ucuzdur. Bir örnek nature/water_canals_cheap001 materyalidir.
  2. Gerçek zamanlı yansıma, materyalde bir $reflecttexture ve buna ek olarak ya $forceexpensive 1 ya da r_waterforceexpensive 1 oyuncu ayarını gerektirir. HL2 ile gelen su materyallerinin çoğu $forceexpensive 1 ayarlar, nature/water_canals_water2 de bunlardan biridir.
  3. Gerçek zamanlı yansıma yoksa mesafe belirleyici olur. water_lod_control entity'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.

KeyvalueHammer'daki adıVarsayılan
cheapwaterstartdistanceStart Transition to Cheap Water1000
cheapwaterenddistanceEnd Transition to Cheap Water2000

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 1 iç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

BelirtiNedenÇözüm
Su görünmüyor ya da doğru render edilmiyorHaritada 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ı bozukAynı PVS içinde ikinci bir su yüksekliği var ya da bir func_viscluster veya areaportal su yüzeyini kesiyorYükseklikleri ayır, func_viscluster ve areaportal'ları yüzeyden uzak tut
Yansıma siyah, mor-siyah damalı ya da fazlasıyla parlakCubemap'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üyorGerçek zamanlı yansıması olmayan su, bitiş mesafesinden itibaren ucuza geçiyorwater_lod_control içindeki mesafeleri artır, cubemap'leri oluştur
**** leaked ****, çizgi suyun içinden geçiyorSu 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.