Minecraft'ta suya baktığınızda daha koyu olana bakarsınız. Böyle bir şeyi nasıl kodlayacağını bilen var mı?
Etkili Minecraft
etkisi olmadan benzer oyun
Minecraft'ta suya baktığınızda daha koyu olana bakarsınız. Böyle bir şeyi nasıl kodlayacağını bilen var mı?
Etkili Minecraft
etkisi olmadan benzer oyun
Yanıtlar:
Suyu aydınlatmak için derinliğe dayalı olarak temelde iki farklı yaklaşım vardır:
Minecraft voksel esaslı aydınlatmayı kullanır; bu, bitişik küplere ışık yayılarak çalışır ve blok tipine bağlı olarak parlaklığı azaltır. Karanlık okyanuslar bu sistemin bir yan etkisidir.
Su güneş ışığını bloke eder ve ışığı blok başına 3 seviye azaltır (varsayılan 1 seviye yerine), bir okyanustaki parlaklık, yüzeyden her mesafeye göre:
0 (surface): 15 (direct sunlight)
1: 12
2: 9
3: 6
4: 3
5 and below: 0 (darkness)
Kaynak: Minecraft Wiki - Işık
Geleneksel aydınlatma modeline sahip oyunlarda, bu etki ışık kaynağı ile okyanus tabanı arasındaki su miktarı ölçülerek yaratılabilir. Işık daha sonra bu mesafeye bağlı olarak kaybolur. Bunu yapmanın birkaç yöntemi vardır:
Düz bir yüzeye sahipseniz, yüzeyi normal olarak su kütlesinden uzağa ve bu normalin nokta ürününe ve bir yüzey pozisyonunu geometri gölgelendiricisine geçirirseniz ışığın suya kat ettiği mesafeyi kolayca hesaplayabilirsiniz .
Etkili su mesafesi
burada tepe pozisyonu ve su gövdesine doğru, normal ışık yüzeyinin altında yönü ve su yüzeyinin arasındaki açıdır.
Gün batımında, suya girerken ışık kırıldığı için sadece 50 ° 'nin biraz altına ulaşır.
İşte iyi bir açıklama ile bir blog yazısı: Dijital Kamera: Toplam İç Yansıma
Daha fazla ayrıntı içeren başka bir yazı: Dijital Kamera: Snell'in Kırılma Yasası
Suya paralel bir yüzeyde bir yükseklik haritası kullanıyorsanız, olur . Güneş doğrudan su yüzeyinin üzerinde ise doğru faktör 1'e eşittir.
Bir nokta ışığıyla, ışık kaynağının göreceli konumuna bağlı olarak her köşe için hesaplamanız gerekir .
Sabit bir su seviyesi veya sabit bir ışık yönü ile denklemin parçaları sabittir ve performans nedenleriyle gölgelendiricide hesaplanmamalıdır.
Su yüzeyini ayrı bir derinlik haritasına getirirseniz (ışık kaynağından görüldüğü gibi), o derinlik dokusunu, ışığın yüzeye çarpmadan önce su içinde kat ettiği mesafeyi hesaplamak için kullanabilirsiniz.
Bunu yapmak için, her bir noktayı ışık kaynağının tepe noktası gölgelendiricisindeki görünüm projeksiyonuna yansıtır ve doku gölgesini piksel gölgelendiricisinde ararsınız.
Yüzey nispeten düz ise, daha iyi sonuçlar için kırılmış bir ışık orijini kullanmalısınız.
* Işığın POV'sundaki derinliği aşağıdaki gibi sayarak en yakın katı yüzeyin önündeki su miktarını belirleyebilirsiniz:
Sonuç dokusu şimdi ışık-görüş alanında ışığın önündeki su miktarını içerir, bu yüzden kullanmadan önce değerin geri dönüştürülmesi gerekir. Bu yöntem, yönlü ışığı (eksi kırılma) hesaplamak için çalışır, ancak yüzeyler çok düzensizse ve aynı parçaları etkileyen su kütleleri arasında çok miktarda hava varsa, hatalı ortam ışığına yol açar.
Artıları ve eksileri, normal gölge haritalama ile aynıdır, ancak derinlik hesaplanırken bir tampona daha ihtiyacınız vardır ve performans daha kötüdür çünkü daha fazla geometri çizmeniz gerekir.
Işın takibi, şeffaf hacimleri oluşturmak için bugüne kadar en doğru fakat aynı zamanda en pahalı çözümdür. Bunu yapmanın iki yolu vardır: 1. Okyanus tabanından yüzeye doğru ve 2. Işık kaynağından suya doğru. Parlaklığı hesaplamak için zemindeki her nokta için birden fazla ışın gerekir.
Su arıtırken dikkate alınması gereken birkaç şey var:
Gözlemciye seyahat ederken sudaki ışık tekrar dağılır, bu nedenle onu düz bir renge karıştırmalısınız.
Gözlemci suya batırılmışsa , derinlik tamponunun son sonucuna göre sis oluşturabilirsiniz. Sis rengi, ancak yoğunluğu değil, gözlemcinin yüzeyden olan uzaklığı ile değişmelidir! (Minecraft, efektin yalnızca bu bölümünü kullanır.)
Gözlemci suya yukarıdan bakarsa, suyla yüzey ve su altındaki geometri arasındaki derinlik farkını temel alarak hesaplamanız gerekir. Sis rengi daha büyük derinlik farklılıklarıyla biraz daha koyulaşmalı, ancak sisin tamamen opak olduğu noktaya geçmelidir.
Sis rengi ayrıca her piksel için görüş yönüne de bağlı olmalıdır, bu nedenle her iki durumda da bakarken biraz daha koyu olur.
Sahte kostikler için bir çıkartma yerine sorunsuz bir döşeme 3D-Texture kullanıyorsanız, dikey yüzeylerde gerilmekten kaçınabilirsiniz. Yüzeye yakın saçılan ışığın gücü üç boyutta değişir, bu nedenle 2D-Doku kullanmak genellikle sahnenin herhangi bir yerinde gerilmesini sağlar. Değişen ışık açılarını, zeminin tepe konumlarını farklı bir koordinat sistemine yansıtarak modelleyebilirsiniz.
Başka bir olasılık, ışığın koordinat sistemindeki yüzey pozisyonuna göre ışık yoğunluğunu hesaplamaktır, ancak bu muhtemelen bir performansa mal olacaktır.
Kostikler, artan derinliğe sahip dağınık ışıktan daha hızlı solmalıdır.
Renkler farklı şekilde dağılmıştır, bu nedenle ışık rengi artan derinlikle değişmelidir. Bu ayrıca, örneğin bir plajın su yüzeyiyle kesiştiği ani kenarları da önler.
Kırılma nedeniyle, ışık okyanus tabanına normalde olduğundan daha dik vurur. Snell kanunu hakkında Wikipedia makalesi açıları ve vektörler için formüller vardır.
Minecraft'taki gökyüzü ışıklandırma etkisinin dümdüz olduğuna inanıyorum - güneş nerede olursa olsun, üstlerindeki şeylerin gölgesi altında. Daha sonra, fenerler vb. Gibi yerel aydınlatma, düşürme etkisi ile uygulanır - ışık kaynağından uzaklaştıkça, küp ne kadar az ışık alırsa.
Bu şekilde yapılırsa, her su tabakası, altındaki tabakayı kümülatif olarak gölgeleyecek, böylece her biri giderek koyulaşacaktır. Ağaç yaprakları bu şekilde gölge sağlar, ancak kümülatif değildir. Bir ağacın altında aynı gölgeyi 1 veya 100 yeşillik küp olsun.
Bunun kullanılan metot olduğuna dair bir ipucu, izleyiciden uzaklaştıkça suyun kararmayacağı - sadece aşağı indiğiniz zaman. Evet, sis efekti belli aralıklarla devreye giriyor ancak suyun karanlık efekti yok.
Bu yüzden aydınlatmayı hesaplamanın temel formülü sözde kodda böyle bir şey olurdu ...
light_on_cube = 1.0
for each cube above target cube, from lowest to highest {
if cube being examined is tree foliage
light_on_cube = 0.5
else if cube being examined is water
light_on_cube = light_on_cube - 0.1
else if cube being examined is solid
light_on_cube = 0
}
Bu, bu yöntemi kullanarak bir çıkıntının altında zifiri karanlık olacağından, çıkıntıların altındaki veya mağaralardaki aydınlatmanın hesaplanması için mükemmel değildir. Ancak, hem yerel ışık kaynaklarına (fenerler, yangınlar vb.) Hem de güneşten yanmış blokları ışık kaynakları olarak muamele etmek eklenebilir. Böyle bir şey yapabilir ...
Buradaki fikir, eğer bir küp güneş veya bir fener tarafından aydınlatılıyorsa, yanındaki küpün de bir şekilde yanacağıdır. Ve o uzaktaki küpten uzaklaştıkça, o kadar az ışık olacak. Dağınık aydınlatmayı tahmin etmek için bir çeşit çamur yolu ama bence işe yarayacak mı?
Belki de soruyu yanlış anlıyorum ama neden derinliklerine bağlı olarak blokların rengini değiştiremiyorsunuz?
Derinlik d'ye sahipseniz (bloklar halinde, 0'dan başlayarak) o zaman parlaklık için makul bir denklem şöyle olacaktır:
L = (1- m ) e - kd + m
Kod: L = (1.0 - m) * exp(-k * d) + m;
k ne kadar hızlı kararır (yüksek = daha hızlı). Makul bir değer 0,5 olacaktır.
m istediğiniz minimum parlaklıktır.
L 0 ila 1 arasında değişir.
Kullanmakta olduğunuz grafik API'sindeki blokların rengini nasıl değiştireceğinizi bilmiyorsanız, lütfen ayrı bir soru olarak (hangi API'yi kullandığınızı ve gölgelendiricileri kullanıp kullanmadığınızı belirterek) sorunuzu sorun.
e^-kd
Biraz yavaş yavaş bazı değere (derinlik) üzerinden sıfıra doğru eğilimi şeyler için standart bir fonksiyondur sadece bir üstel bozunma vardır. Çarpma (1-m)
ve ilavesi m
, çürümeyi en aza m
indirecek ve hala başlangıçta olacak şekilde ölçeklendirmek ve dengelemek içindir 1
. en.wikipedia.org/wiki/Exponential_decay