Düzensiz şekilli sağlık çubuklarını prosedürel olarak nasıl yapabilirim?


35

Geleneksel dikdörtgen veya kalp temelli sağlık çubuğunun konusu iyi anlaşılmış ve kolayca çözülebilen bir şeydir. Peki aşağıda yaptığım maketler gibi daha "yaratıcı şekilli" sağlık barları için kabul edilen çözüm nedir?

Boş sağlık Tam sağlık, kısmi sağlık

Bunu yapmanın bariz yolu "aralarında" spritelara sahip olmak olacaktır, bu nedenle üçüncü görüntü farklı sağlık seviyeleri için diğer birçok geçişle birlikte kendi sprite olacaktır. Ancak bu gerçekten kararsız görünüyor ve sağlık devletleri arasında yumuşak bir geçiş oluşturmak için ihtiyaç duyulan Betweens sayısı büyük olacaktır.

Ortaya çıkarabileceğim diğer tek fikir, “boş sağlık” sprite üstüne “tam sağlık” sprite'ı yerleştirmek ve her sağlık keneğini temsil etmek için önceden yapılmış piksel koordinat kümelerini üst üste koymak ve daha sonra bunları opak veya şeffaf hale getirmek. yukarı veya aşağı gider.

Bu soruyu dil ve platform agnostik olmak niyetindeyim, ancak cevaba yardımcı olursa, herhangi bir dilde / kütüphanede / çerçevede somut bir örnek vermekten çekinmeyin.


5
"N̶a̶n̶o̶m̶a̶c̶h̶i̶n̶e̶s̶ Shader, oğul"
Mukesh Ingham

Geçişin matematiksel olarak tanımlanabileceğini hissediyorum, oradan bilgisayarın önceden yazdırmak yerine göstermek / gizlemek için piksel koordinatlarını hesaplamasını sağlayabilirsiniz
Richard Tingle 23

Kalp şeklindeki sağlık barı nasıl "kolayca çözülebilir"?
MooseBoys,

1
@ MooBoys Ben kalp şeklinde değil, kalp bazlı sağlıktan bahsediyordum. Zelda oyunlarının efsanesini düşün. Daha net olmadığım için üzgünüm.
msd7734

@RichardTingle, iyi fikir :)
Jon,

Yanıtlar:


48

Gölgelendiricilerle bunu başarmanın çok basit bir yolu var, üç dokuya ihtiyacınız var: boş sağlık çubuğu, sağlık çubuğu dokusu ve bir uçta bir aşırı (örneğin en karanlık siyah veya en şeffaf alfa değeri olan) ile sağlık dağılımı gradyanına sahip maske ve diğer ucunda. En iyi görüntü gösteriliyor, şu anda sadece doğrusal olan eğimli degrade çizemiyorum - ancak sanatçılarınızın herhangi bir sıkıntısı görüntü tanımını buraya girin olmayacağına eminim: Şimdi, gölgelendirici örneğinde hem dokuları hem de eşik değerini, eşleştirmeyen tüm pikselleri atmak giriş eşiğinden daha parlak (% sağlık gölgelendirici girdisine dayanarak).
Sen coulddoku yerine maskeleme için matematiksel formülü kullanın, ancak bunu yaptıysanız, söz konusu formüllerle oluşturabileceğiniz (= basit olanlar) söz konusu formüllerle oluşturabileceğiniz (ve basit olanları) hala çok sınırlı kalacaksınız - ve birini bulmak önemsiz değil.
* yorumları görün


9
Pek çok durumda (OP örneğini de içeren), renk için ayrı bir doku kullanmak çok önemlidir. Çoğu durumda, gri tonlamalı maske degradesini gölgelendiricinin üniformaları olarak belirtilen renklere yeniden eşleştirirken, yine de belirli bir eşiğin altındaki maske değerlerini atarsınız.
bcrist

1
Aslında siyah değil en koyuya ihtiyacınız yok, istemediğiniz pikselleri taramak için alfa kanalını kullanabilirsiniz.
Jack Aidley

1
@JackAidley bunun mümkün olacağından eminim, ancak çözümü mümkün olduğunca esnek istedim - çoğu AAA başlığında hp sadece "kırmızı" değil ancak dokulu.
wondra

1
bcrist iyi nokta, bunu bir optimizasyon olarak önermeyi düşündüm. Ancak düzgün çizemedim bu yüzden mümkün olduğunca basit tutmaya ve uygulama için optimizasyon bırakmaya karar verdim.
wondra

@wondra OP'deki örneğe bakmayı içeren birçok durum için, doku yerine prosedürsel bir gradyan veya tek boyutlu bir renk araması (giriş olarak maske seviyesi) kullanabilirsiniz.
Random832

34

Piksel gölgelendirici olarak matematiksel olarak uygulanır:

İşlemcide VD ile HealthDirection ve 'dot ürünlerini hesaplayın görüntü tanımını buraya girin

GPU'da, her piksel için merkez noktasından uzakta normalize edilmiş bir yön hesaplayın. Her "dot" ürününü HealthDirections ile karşılaştırın, "arka planın" gölgesini mi yoksa renkli mi olacağını seçin. görüntü tanımını buraya girin

Bu algoritmayı "tersine çevirdiyseniz" ve diğer yönden çalıştıysanız, her bir pikselin yönünü "% s" işaretini kaldırabilir ve bunun yerine her birini HealthPercent ile karşılaştırabilirsiniz. Her pikselin yüzdesi hesaplanırken, GPU'daki solmaya kırmızıdan yeşile ayarlama önemsiz hale gelir.

Önce algoritmayı bir dörtlüye uygulayan çubuğu çizin; rangeMin ve rangeMax (fırınlanabilir) ve clip () arasında çıktı renkleri veya her yerde saydam çıktı. Daha sonra, alfa kullanarak (değiştirilmiş) hareketli grafiği çizin. Çubuğunu CAD'de izledim, sele doldurdum, sonra onu silmek için Paint'teki düz renk şeklini "sihirli değnekledim". Maden, AutoCAD ve Paint'in elle karıştırılması nedeniyle boka benziyor; İç kenarları saydamla karıştırdığınızı varsayarsak, sizinki mükemmel görünecek .

Beyaz kenarlık dörtlünün sınırlarıdır. O ve kırmızı X'ler sadece referans içindir:

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

"Delikli sprite" sağlık çubuğuyla aynı anda yapılmasına gerek yoktur. Tüm sağlık çubukları tamamlandıktan sonra, bir kerede instantane olmalı ve çizilmelidirler. Algoritma gölgelendiricinin içinde bulunduğundan, buna bir örnek ekleyebilir ve ardından tüm sağlık çubuğunu tek bir beraberlik çağrısı çağrısı ile çizebilirsiniz. Ekrandaki her sağlık çubuğunun çizilmesi 2 DrawInstanced (...) çağrısı almalı ve "çılgınca hızlı" olmalıdır.


1
Bunun gibi dairesel bir şekilde maskeleyecekseniz, dairesel bir renk solması için çizdiğiniz üçgenleri değiştirerek daha verimli bir şekilde uygulayabilirsiniz.
Jack Aidley

@ JackAidley, lütfen daha spesifik olun, çünkü bu maskelemeyi düşünmüyorum; ilerleme çubuğu, ilk geçişten sonra, örneklemesiz, yalnızca iki üçgen üzerinde tam olarak oluşturulur. Sprite içinde bir delik var ve sonunda her şeyi "güzelleştiriyor". (Bir çeşit maskedir, ancak algoritmanın ayrılmaz bir parçası olarak değil mi?) Teşekkürler
Jon

Yaptığınız şey, renkli çubuğun renkli maskeli bir versiyonunu, zaten gri renge sahip bir arka plan sprite üzerine çizmeye eşdeğerdir. Çünkü yönteminiz özel bir gölgelendirici gerektiriyor ve formun yalnızca istenen kısmını çizmekten daha yavaş bir yöntemle elde ettiğiniz her piksele yazıyor.
Jack Aidley

@ JackAidley, ama arka plan sprite yok mu? Gökkuşağı sadece dört yüzer3 dünya konumu kullanılarak çizilir; UV yok, "arkaplan sprite" yok. Ayrıca, piksel gölgelendiricinin bazı küçük dörtlüler üzerinde çalışırken tıkanacağından endişe ediyorsunuz? Ayrıca, RangeMin ve RangeMax, bu parçaların çoğunu anında yakalar.
Jon,

Orijinal görüntüde gösterildiği gibi kenarlıkları elde etmek için bir arka plan sprite gerekecektir; Bunları ihmal ediyorsanız, evet, yöntemler farklıdır.
Jack Aidley
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.