Soyut 2d yukarıdan aşağıya su dokusu canlandırmak nasıl?


24

Şu anda okyanusu yukarıdan aşağıya bakan bir oyun uyguluyorum. Aşağıdaki, biraz soyut bir doku kullanın:görüntü tanımını buraya girin

Asıl doku saydamdır, berraklık için yeşilimsi rengi ekledim.

Şimdi sahip olduğum problem şu ki, bu dokuyu nasıl canlandıracağımı bilmiyorum, böylece su güzel görünüyor. Ben günah dalgasıyla dokusunu taşımak için çalıştı: texture.y += sin(angle). Elbette şimdi tüm doku hareket ediyor ve bu da gerçekçi değil gibi görünüyor. Çalıştığım bir sonraki şey, başka bir katman eklemek ve bir paralaks efekti uygulamak. Böylece su yüzeyinin altındaki yansımalar da hareket ederdi, ama çok daha yavaş. Biraz daha iyi görünüyor ama yine de ... yeterince iyi değil.

En iyi görünen animasyonun, eğer münferit hücreler büyüyüp büzülürse, bir ağ veya kumaş parçası gibi olacağını düşünüyorum. Birinin bu hücrelerin bir köşesine hafifçe vuracağını ve komşu hücrenin genişleyeceğini ve kendime doğru çektiğim (ya da iteceğim) hücrenin büzüşeceğini hayal edin. Bir çeşit yay gibi. (?). Ancak böyle bir şeyin nasıl uygulanacağı hakkında hiçbir fikrim yok:

  • Bunun için matematik modeli nedir? Yaylı bir şey, kuvvetler itme / çekme?
  • Ve eğer öyleyse, bu modeli verilen dokuya nasıl eşlerim? Tüm eğrileri tutmak ve ne olmasın ...

(Aynı zamanda verilen dokuyu nasıl canlandıracağınıza dair farklı fikirlere / cevaplara açığım. Gerçekçilik burada mesele değil, sadece hareketler gibi güzel görünen sular ...)

DMGregory'den Çözüm

Bu yazıda bir libgdx örneği yayınladım: 2d su animasyonu pürüzlü ve pürüzsüz değil (doku filtreleme hakkındaki cevaba bakınız)

Yanıtlar:


41

Bunu yapmanın yaygın bir yolu, ekran dokusunu bozmak için gölgelendiricide dolaylı bir doku araması kullanmaktır:

Su animasyonunu gösteren animasyonlu gif

Burada bazı düşük frekanslı renk gürültüsüne sahip bir doku kullanıyorum (rastgele renklerin yumuşak damlalarını döşerim) ve zaman içinde onu ekran geometrisinde kaydırıyorum.

görüntü tanımını buraya girin

Renkleri bu dokudan çizmek yerine, kırmızı ve yeşil kanalları alıp, 0.5fzaman ve uzayda düzgünce değişen bir takma 2B vektöre dönüştürmek için çıkarırım .

Daha sonra, ana su dokusundan örneklemeden önce UV koordinatlarına bu vektörün küçük bir katını ekleyebilirim. Bu okuduğumuz ve görüntülediğimiz dokuyu değiştirir, etrafını eğirir.

Bu gürültünün iki örneğini ortalayarak, zıt yönlerde ilerleyerek hareket yönünü gizleyebiliriz, böylece amaçsız bir çalkalamaya benziyor.

Birlik'te gölgelendirici şöyle görünür - seçtiğiniz gölgelendirici diline çevirmek için yeterince basit olmalıdır:

fixed4 frag (v2f i) : SV_Target
{               
    float2 waveUV = i.uv * _NoiseScale;
    float2 travel = _NoiseScrollVelocity * _Time.x;

    float2 uv = i.uv;
    uv += _Distortion * (tex2D(_Noise, waveUV + travel).rg - 0.5f);
    waveUV += 0.2f; // Force an offset between the two samples.
    uv += _Distortion * (tex2D(_Noise, waveUV - travel).rg - 0.5f);

    // Sample the main texture from the distorted UV coordinates.
    fixed4 col = tex2D(_MainTex, uv);

    return col;
}

1
Bu gerçekten çok hoş görünüyor. Tüm özellikleri anladığımdan emin değilim: _NoseScale = "gürültü haritasını" ölçeklemek için skaler. _NoiseScrollVelocity = Gürültü haritası boyunca hangi hızda hareket ettiğimizi Vector2. _Noise =? _Distortion = Skaler Bir distorsiyon faktörü olarak mı seçiyorum? v2f = Vertex rengini belirleriz. i =?
morpheus05

_NoiseYukarıdaki küçük kanlı rasgele dokuyu okuyan bir doku örnekleyicisidir. v2f iKöşe gölgelendiricisinin enterpolasyonlu verileri - esas olarak çizdiğimiz piksel için doku koordinatlarını almak için kullanıyoruz i.uv. Ve geri kalan her şey hakkında tamamen haklısın.
DMGregory

Gölgelendiriciyi uyguladım ve bir şekilde işe yaramadı (hareket etmiyor ya da bozulma çok büyük), değerleri doğru ayarlamadığımı farz ediyorum. time = ms cinsinden son kareden farkı. noise_scale = 1 (Ben doku, sarma modu tekrar kullanım) noise_scroll_velocity = [0.01, 0.01] bozulma = 0.02
morpheus05

Değişkenin DeltaTime değil, Zaman olarak adlandırıldığını unutmayın. Zaman içinde bir fark kullanırsanız ve kare hızınız tutarlıysa, her zaman aynı sayıyı alırsınız ve gölgelendiriciyi aynı girdilerle yeniden çalıştırırsınız, aynı çıktıyı alırsınız (hiçbir şey hareket etmez). Daha kötüsü, kare hızınız tutarsızsa, ileri geri titreşim elde edersiniz. Delta zamanı değil, toplam süre dolmasını istiyorsun.
DMGregory

Yakında gönder vurdum fark ettim ve şimdi neredeyse işe yarıyor. Animasyon sağ alt köşeden dalgaları bölüyor gibi gözüküyor ve 10 ya da öylesine bir saniye sonra, durmuş dalgalar gibi kayboluyor. Bunun nedeni ne olabilir?
morpheus05

6

Buna kostik bir etki adı verilir ve bu efektlerin çalışma zamanında oluşturulması oldukça zaman alıcıdır, bu nedenle geleneksel olarak önceden oluşturulmuş kare kare animasyonla yapılır. Ticari olmayan kullanım için ücretsiz bir sürümü olan Caustics Generator gibi sizin için yakıcı animasyon kareleri üretecek araçlar var . Bahsettiğim aracın pro sürümünden çok daha ucuza alabileceğiniz önceden hazırlanmış bazı ürünler de var.

Kostik etkilerin genellikle bir su altı arazisinde veya su altı yüzeyinde hafif bir çerez olarak uygulanan bir etki olduğunu unutmayın. Diğer bir deyişle, suyun içine bakarken onu suya koymak normalde suyun göründüğü gibi değildir.


Bu çok ilginç, bu jeneratöre de bir göz atacağım (olay olsa da, eğer anlarsam gölgelendirici varyantını deneyeceğim ...)
morpheus05

4

Bu, bir voronoi grafiğinden oluşturabileceğiniz bir dokuya benzer, örneğin:

görüntü tanımını buraya girin

Noktaları hareket ettirerek grafiğe küçük, pürüzsüz ayarlar yapabilirsiniz; grafiği her kareyi yeniden çizmek oldukça pahalı olurdu, bu nedenle büyük olasılıkla animasyonu önceden oluşturmak isteyebilirsiniz.


4
Aslında geçmişte bu şekilde kostikler yaptım. Kesin olarak düşündüğünüz kadar pahalı değildir ( işte Voronoi'nin WebGL gölgelendiricisinde gerçek zamanlı olarak görünmesini sağlayan bir örnek ), ancak sivri çokgenler yerine, kenarlarda doğru yumuşak bir şekil almak zor olabilir.
DMGregory

Ooo, bu çok hoş; Çok kullanışlı olacak bazı arazi jeneratörleri var.
FacticiusVir

0

Bir alt doku tabakası ve üstüne yansıma için iki yarı saydam dokular içeren bir oldschool yöntemi vardır.

Bütün yol boyunca gitmek ve suyun klonlanmış dalgalarla ya da samish mavisi çorbalarla dolu görünmesini istemiyorsanız, flowmaps hedefleridir.

https://steamcdn-a.akamaihd.net/apps/valve/2010/siggraph2010_vlachos_waterflow.pdf


3
Bağlantılar yardımcı olsa da, asla iyi cevaplar vermezler. Her iki tez yöntemini de genişletebilir misiniz? Uygulamayı nasıl sürdürürdü?
Vaillancourt

İlk yöntem, temel olarak suyu canlandırmak için kullanılan çok eski bir yöntemdir - UVW Koordinatları, seçtiğiniz yöne kaydırılan bir taban katmanı su dokusunu alırsınız. Şimdi ek olarak başka bir yöne kaydırdığınız normal bir harita / çarpma haritası uygulayın - eğer iyi yapılırsa, bu küçük nehirler için ikna edici görünüyor. Büyük su kütleleri için çok sınırlı olsa da - dalgaları birleştiren her şey hareli etkiler. Bağlantı, yapabildiğim kadar uzaktaki akış haritalarının kullanımını açıklar.
Pica

Lütfen buraya ekleyeceğiniz soruyu geliştirmek için düzenleme özelliğini kullanın. :) Yorumlarda değil, gönderilerde yanıtları aramak için kullanılır.
Vaillancourt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.