Kafayı 2D bir oyunun atmosferini değiştirecek hafif bir ekran titremesi efekti yapmakla yemiştim. "Shader yazayım, havalı olsun" dedim. Godot'un ShaderLanguage'ı ile uğraşıyordum. Amacım, sadece karakter vurduğunda veya büyük bir şey olduğunda ekranın kenarlarının hafifçe bükülmesiydi. Basit bir noise texture'ı ve UV manipülasyonu işte...
Kodumu yazdım, CanvasLayer'a bağladım ve "Çalıştır"a bastım. O an gördüğüm şey beni benden aldı. Ekranın tamamı, sanki bir bardak suyun altındaymış gibi, delicesine bükülüp dalgalanıyordu. Karakter, arkaplan, UI, her şey eriyor gibiydi! İlk düşüncem "Ben ekran kartını mı yaktım?" oldu, cidden korktum.
Kod:
void fragment() {
vec2 distorted_uv = UV + (noise.rg - 0.5) strength;
COLOR = texture(TEXTURE, distorted_uv);
}
strength değişkenine 0.1 gibi küçük bir değer vermiştim ama meğerse noise texture'ının rg kanalları (yani x ve y eksenleri) -0.5 ile 0.5 arasında değil de, çok daha geniş bir aralıkta değerler üretiyormuş. O küçük 0.5 çıkarma işlemi hiçbir işe yaramamış. UV koordinatları, ekranın dışına fırlamış, texture sampling tamamen sapıtmış ve bu distortion kıyameti ortaya çıkmış. StackOverflow'da bile böyle absüld bir görüntü aramazsın.
Debug etmek için tüm değerleri print ile yazdıramazsın ya shader'da, en temel yönteme döndüm: değerleri renge çevirmek. noise.rg değerlerini direkt COLOR'a atayıp baktım. Gördüğüm, siyah-beyaz gürültü değil, rengarenk, vahşi bir desendi. Anladım ki kullandığım NoiseTexture'ın formatı ve range'i benim sandığım gibi değildi. Çözüm, noise değerlerini doğru aralığa (genellikle 0.0-1.0) scale'lemek ve strength değerini neredeyse 0.01 gibi komik seviyelere çekmekti.
Sonuçta kasıtlı olmayan, Hollywood yapımı bir uzay-zaman bükme efekti elde etmiştim. Aslında yaptığım hatayı düzelttikten sonra, bu aşırı efekti bir "büyük boss geliyor" veya "sahne değişimi" anı için not aldım. Çöpe atılacak bir bug değil, keşfedilmiş bir özellik oldu!
Siz de shader yazarken böyle "kontrolümden çıkan güç" anları yaşadınız mı? Bu tarz full-screen efektler için sizin daha temiz bir yönteminiz var mı?