Nesneler yüzeye yakın olduğunda yanan bir gölgelendiriciyi nasıl yazarım?


15

Gelen bu Overwatch oyun videosu , karakterin kalkanı diğer nesnelerin geometrisine yakın bölgelerde beyaz yanar.

Reinhart'ın kalkanı bir miktar geometri kırpıyor

Mavi kalkanın zemine, duvarlara ve direğe yakın beyaz kenarlarına dikkat edin.

Kalkanın kendi modeli olduğuna ve etkinin bir gölgelendirici ile yapıldığına inanıyorum, ancak "yakınlık" kavramının gölgelendirici programlamaya nasıl çevrileceğini anlamaya çalışıyorum.


2
Unity kullanıyorsanız bu konuşma ilginizi çekebilir . 26. slayttan başlayarak "Kavşak vurguları" bölümünü kontrol edin.
DMGregory

Bu nedenle cevap aşağıda ele alınmıştır, ancak şimdi bunu açıklayan bir video: youtube.com/watch?v=C6lGEgcHbWc
CobaltHex

Yanıtlar:


28

Genel bir özet:

  1. Kalkan olmadan sahnenizin derinlik haritasını oluşturun . Saydam nesneler genellikle daha sonraki bir geçişte işlendiğinden, bunu etkili bir şekilde ücretsiz olarak alabilirsiniz. Aksi takdirde, sahne sans kalkanını bir derinlik gölgelendirici ile bir RTT'ye oluşturarak derinlik haritasını oluşturabilirsiniz .

  2. Sahnenizi normal şekilde oluşturun, derinlik haritasını kalkan gölgelendiricinize iletin.

  3. Gölgelendiricide, sahne derinliğindeki farkı kalkan parçasının derinliğinden hesaplayın ve bu farkı parça rengini değiştirmek için kullanın.

gösteri

Bunun basit bir WebGL demosunu yazdım.

demo ekran görüntüsü

Satır satır

Parça gölgelendirici kodunu ayrıntılı olarak inceleyelim:

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

Her parçadaki derinlik haritasını örnekleyin. Parçanızı ekran boşluğundan [0, genişlik / yükseklik] normalleştirilmiş [0.0, 1.0] koordinatlarına dönüştürmek için görüntü alanı boyutlarınıza bölmeyi unutmayın. Bu noktada, parça rengini örneklenen derinlik eşlemesi pikseline ayarladığınızda, şöyle görünür:

derinlik haritasının ekran görüntüsü

Derinlik haritası gri tonlama olduğundan, değeri herhangi bir kanaldan alabilirsiniz ( rburada kullandım ).

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

Ardından, sahne derinliği ile kalkan parçasının derinliği arasındaki farkı bulmak için bu derinlik örneğini kullanabilirsiniz. Derinliğinizi de normalleştirmeyi, [zNear, zFar] 'dan (kameranızın yakın ve uzak düzlemleri) [0.0, 1.0]' a götürmeyi unutmayın. smoothstepbunu güzel yapar. Bu 1.0 -değer solidsDiff, fark maksimum (zFar - zNear) olduğunda 1,0 ve minimumda (0,0) 0,0 olacak şekilde ters çevrilmektir.

solidsDepthDerinlik haritasını oluşturan derinlik gölgelendiricisinde zaten normalleştirilmiş olduğumu varsayıyorum .

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

Ardından, derinlik farkına bağlı olarak kalkanınızın alfa kanalını değiştirebilirsiniz. Burada minimum alfadan başlıyoruz 0.3, sonra alfaya yakın bir farkla keskin bir artış sağlıyoruz0.0 .

- 0.005Sadece "kavşak" kalın yapmak için beyaz marjı ekler ofset. Değiştirmeyi deneyin!

gl_FragColor = vec4(vec3(1.0), alpha);

Ve son olarak, bu alfa parça renginize uygulayın.


geliştirmeleri

Kavisli bir kalkan yapabilir, "enerji kalkanı" görünümü (demo) için plazma ekleyebilir veya sadece kavşakları (demo) gösteren efektleri keşfedebilirsiniz .

Gökyüzü Ekran kartınız sınırdır!


Ah. Benim. İyi haberler. Harika öğretici için ty.
Blue Bug

5

Sadece derinlik haritasını kullanıyor. Dünyayı daha sonra kalkanı oluşturur ve pikseli daha beyaz renklendirmek için kalkanın işlenmiş z değeri ile derinlik tamponu z değeri arasında bir fark alır.


3

Hangi Motoru kullandığınızı bilmiyorum. Veya hangi dilde çalıştığınızı. Yine de, çevrimiçi olarak bulabileceğiniz şeylerin çoğu, aradığınız şeyi elde etmek için bir ortamdan diğerine geçmek zor değildir.

Ve kesinlikle size yardımcı olabilecek malzeme çevrimiçi var. Birlik ile ilgili şu tartışmaya bakın: http://www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/ ve bu soru UE4 ile ilgili: https: //answers.unrealengine. com.tr / sorular / 74858 / dynamic-forcefield-shader.html . Komple bir gölgelendirici örneği için, bu kalkan efektini uygulamak, Reddit'teki oldukça yeni bir tartışmadan sonra şunları görebilirsiniz: https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ Ve olmayan bir öğretici için tam olarak bununla ilgileniyor, ancak ilgilenecek kadarıyla ilgili: http://www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

Ayrıca, daha önce bu sitede yapılan 3 ilgili soru için, elde etmek istediğiniz şeyin arkasındaki kavramları kavramak için büyük yardımcı olabilecek bağlantılar:

Uzay Gemisi Kalkanı Parlaması

Oyunda bir starwar enerji kalkanı nasıl uygulanır

Bir Primative küre problemi ile XNA kalkan etkisi

Son olarak, bu motorlardan herhangi birini kullanıyorsanız, Unity'de ve Unreal Engine'de kendi sanal mağazalarında kalkan gölgelendiricilerinin birkaç güzel uygulaması vardır. Bunlar genellikle ödenen varlıklardır, ancak satın aldıktan sonra neredeyse her zaman açık kaynaklıdır - ve genellikle ucuzdur. Bu motorları kullanmasanız bile, bu varlıklar oynamak ve öğrenmek için yardımcı olabilir.

Umarım yardımcı olur.


Bu bağlantılar yardımcı olsa da, bu yanıt temel olarak sadece bağlantılardır ve aslında soruyu doğrudan ele almaz. Bağlantıların ilgili içeriğini gerçek bir açıklamaya çıkarmak daha iyi olur.
Anko

Bu bağlantı soruyu cevaplayabilirken, cevabın önemli kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir. - Yorumdan
Vaillancourt

@Anko Tabii, benim hatam. Genellikle bir açıklama ve bir bağlantı koleksiyonu ekliyorum, ama bu sefer haklısın, gerçek açıklama eksikti. O zaman muhtemelen cevabı sileceğim.
mand

@AlexandreVaillancourt OP'yi orijinal kaynağa yönlendirmek yerine başka bir bağlantıdan kopyalayıp yapıştırma fikrinden hoşlanmıyorum. O zaman, en iyi olduğunu düşündüğüm soruya yorumlarda bağlantılar vermek. Buradaki sorun, yardımcı olabilecek bol miktarda malzeme bildiğinizde ancak yorum yapmak için çok büyük olduğunda. Ama yine de, burada iyi bir açıklama cevabı gönderildiğinden, bunu sileceğim
MAnd
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.