मैं Minecraft की तरह पानी को गहराई से कैसे प्रकट कर सकता हूं?


24

Minecraft में जब आप पानी को गहराई से देखते हैं तो आपको गहरा रंग दिखाई देता है। क्या किसी को पता है कि इस तरह से कुछ कोड करने के लिए कैसे?

प्रभाव से Minecraft प्रभाव के साथ Minecraft

बिना प्रभाव के समान खेल बिना प्रभाव के समान खेल


18
क्या यह स्वचालित रूप से नहीं किया गया है क्योंकि पानी घन की सामग्री अर्ध-पारदर्शी है?
pek

मुझे ऐसा नहीं लगता। मैंने तुलना के लिए प्रभाव के बिना एक चित्र जोड़ा।
जेवियर

2
हो सकता है कि यह केवल पानी के टुकड़ों पर लागू होने वाला मिश्रण है? फिर से, यह आसान होना चाहिए क्योंकि सामग्री अर्ध-पारदर्शी है।
pek

1
आप गहराई के अनुसार बक्से का रंग भी बदल सकते हैं।
अली

जवाबों:


51

गहराई पर आधारित प्रकाश जल के लिए अनिवार्य रूप से दो अलग-अलग दृष्टिकोण हैं:

वॉक्सेल-प्रकाश

Minecraft voxel- आधारित प्रकाश का उपयोग करता है, जो प्रकाश को आसन्न क्यूब्स में प्रचारित करके काम करता है, ब्लॉक प्रकार के आधार पर चमक को कम करता है। अंधेरा महासागर इस प्रणाली का एक दुष्प्रभाव है।

पानी सूर्य के प्रकाश को अवरुद्ध करता है और प्रकाश को 3 स्तरों प्रति ब्लॉक (डिफ़ॉल्ट 1 स्तर के बजाय) से कम करता है, जिसका अर्थ है कि सतह से प्रत्येक दूरी के लिए एक महासागर में चमक है:

0 (surface): 15 (direct sunlight)
1:           12
2:            9
3:            6
4:            3
5 and below:  0 (darkness)

स्रोत: माइनक्राफ्ट विकी - लाइट

दूरी आधारित छायांकन

एक पारंपरिक प्रकाश मॉडल वाले खेलों में, यह प्रभाव पानी की मात्रा को मापने के द्वारा बनाया जा सकता है जो प्रकाश स्रोत और समुद्र तल के बीच होता है। इस दूरी के आधार पर प्रकाश को फीका किया जाता है। ऐसा करने के लिए कुछ तरीके हैं:

प्रत्यक्ष गणना

यदि आपके पास एक सपाट सतह है, तो आप आसानी से पानी में प्रकाश की यात्रा की दूरी की गणना कर सकते हैं यदि आप सतह को पानी के शरीर से दूर करते हैं \ Vec {n}और इस सामान्य और डॉट सतह के डॉट उत्पाद रोंको ज्यामिति की छाया में बदलते हैं।

प्रभावी जल दूरी है

\ max (\ left (s - \ vec {n} \ cdot \ vec {p} \ right), 0) \ cdot \ left (1 + \ tan (\ Alpha) \ right)

जहां \ Vec {p}शीर्ष की स्थिति है और अल्फासतह के नीचे प्रकाश दिशा के बीच का कोण है और पानी की सतह पानी के शरीर की ओर सामान्य है।

सूर्यास्त के समय, अल्फाकेवल 50 ° से थोड़ा कम तक पहुंचता है क्योंकि पानी में प्रवेश करने पर प्रकाश अपवर्तित हो जाता है।
यहाँ एक अच्छी व्याख्या के साथ एक ब्लॉग पोस्ट है: डिजिटल कैमरा: कुल आंतरिक प्रतिबिंब
अधिक विवरण के साथ एक और पोस्ट: डिजिटल कैमरा: अपवर्तन का नियम

यदि आप पानी के समानांतर किसी सतह पर एक ऊंचाई का उपयोग कर रहे हैं, \ बाएँ (s - \ vec {n} \ cdot \ vec {p} \ right)बन जाता है \ बाएँ (s - h \ दाएँ)। सही कारक 1 बराबर होता है अगर सूरज सीधे पानी की सतह से ऊपर हो।
एक बिंदु प्रकाश के साथ, आपको अल्फाप्रकाश स्रोत के सापेक्ष स्थिति के आधार पर प्रत्येक शीर्ष के लिए गणना करना होगा।

एक निश्चित जल स्तर या एक निश्चित प्रकाश दिशा के साथ, समीकरण के भाग स्थिर होते हैं और प्रदर्शन कारणों से छाया में गणना नहीं की जानी चाहिए।

पेशेवरों:

  • तेज और सटीक

विपक्ष:

  • केवल सपाट पानी की सतहों के लिए या केवल सीधे ऊपर से प्रकाश के लिए काम करता है, क्योंकि केवल एक सतह को सामान्य रूप से ध्यान में रखा जाता है। (किसी न किसी सतह और झुकी हुई रोशनी का संयोजन लंबन मानचित्रण के साथ कुछ विस्तार कर सकता है।)
  • कोई कास्टिक नहीं

छाया मानचित्रण

यदि आप पानी की सतह को एक अलग गहराई के नक्शे में प्रस्तुत करते हैं (जैसा कि प्रकाश स्रोत से देखा जाता है), तो आप सतह को मारने से पहले पानी में प्रकाश की यात्रा की दूरी की गणना करने के लिए उस गहराई की बनावट का उपयोग कर सकते हैं।
ऐसा करने के लिए, आप प्रत्येक स्रोत को वर्टेक्स शेडर में प्रकाश स्रोत के दृश्य प्रक्षेपण में प्रोजेक्ट करते हैं और पिक्सेल शेडर में टेक्सचर लुकअप करते हैं।

यदि सतह अपेक्षाकृत सपाट है, तो आपको बेहतर परिणामों के लिए अपवर्तित प्रकाश मूल का उपयोग करना चाहिए।

पेशेवरों:

  • अपेक्षाकृत जटिल जल ज्यामिति के साथ काम करता है, जब तक यह खुद को रोक नहीं देता है। *
  • आंशिक रूप से पारदर्शी मात्रा के लगभग किसी भी प्रकार के लिए पुन: उपयोग किया जा सकता है।

विपक्ष:

  • सीधी गणना से धीमी।
  • गहराई के नक्शे के लिए अतिरिक्त वीआरएएम की आवश्यकता है।
  • 100% सही नहीं है।

* आप प्रकाश की पीओवी से गहराई की गणना करके निकटतम ठोस सतह के सामने पानी की मात्रा निर्धारित कर सकते हैं:

  1. अपने दृश्य में ठोस ज्यामिति को सामान्य की तरह प्रस्तुत करें। प्रत्येक टुकड़े के लिए, आप परिणाम बनावट में गहराई मूल्य जोड़ते हैं।
  2. गहराई बफर को अपडेट किए बिना पानी के सामने के चेहरे को रेंडर करें और परिणाम से टुकड़ों की गहराई को घटाएं।
  3. उसी तरह से पीछे के चेहरे को रेंडर करें, लेकिन परिणाम के लिए खंड की गहराई जोड़ें।

परिणाम बनावट में अब प्रकाश-दृश्य-अंतरिक्ष में प्रकाश के सामने पानी की मात्रा होती है, इसलिए इसका उपयोग करने से पहले मूल्य को वापस रूपांतरित किया जाना चाहिए। यह विधि दिशात्मक प्रकाश (माइनस अपवर्तन) की गणना करने के लिए काम करती है, लेकिन गलत परिवेश प्रकाश का नेतृत्व करेगा यदि सतहों बहुत अनियमित हैं और समान टुकड़ों को प्रभावित करने वाले पानी के निकायों के बीच हवा की एक बड़ी मात्रा है।
पेशेवरों और विपक्ष सामान्य छाया मानचित्रण के लिए समान हैं, सिवाय इसके कि आपको गहराई की गणना करते समय एक और बफर की आवश्यकता होती है और प्रदर्शन बदतर होता है क्योंकि आपको अधिक ज्यामिति खींचनी होती है।

किरण पर करीबी नजर रखना

पारदर्शी दूरी प्रदान करने के लिए रे ट्रेसिंग अब तक सबसे सटीक लेकिन सबसे महंगा समाधान है। ऐसा करने के दो तरीके हैं: 1. समुद्र तल से सतह की ओर और 2. प्रकाश स्रोत से पानी की ओर ट्रेसिंग। चमक की गणना करने के लिए फर्श पर प्रत्येक बिंदु के लिए कई किरणों की आवश्यकता होती है।

पेशेवरों:

  • हर ज्यामिति के साथ सही ढंग से काम करता है।
  • सही कास्टिक!

विपक्ष:

  • धीरे!

अतिरिक्त प्रभाव

पानी देते समय कुछ और बातों का ध्यान रखना चाहिए:

कोहरा

पर्यवेक्षक की यात्रा के दौरान पानी में प्रकाश फिर से बिखरा हुआ है, इसलिए आपको इसे एक ठोस रंग की ओर मिश्रण करना चाहिए।

यदि पर्यवेक्षक डूब जाता है , तो आप बस गहराई बफर के अंतिम परिणाम के आधार पर कोहरे को प्रस्तुत कर सकते हैं। कोहरे का रंग, लेकिन इसका घनत्व सतह से पर्यवेक्षक की दूरी के साथ नहीं बदलना चाहिए! (Minecraft केवल प्रभाव के इस हिस्से का उपयोग करता है।)

यदि पर्यवेक्षक ऊपर से पानी को देखता है, तो आपको पानी के साथ सतह और ज्यामिति के बीच गहरे अंतर के आधार पर कोहरे की गणना करने की आवश्यकता है। कोहरे का रंग बड़े गहराई के अंतर के साथ थोड़ा गहरा होना चाहिए, लेकिन केवल उस बिंदु पर बदलना चाहिए जहां कोहरा पूरी तरह से अपारदर्शी है।

कोहरे का रंग प्रत्येक पिक्सेल के लिए दृश्य दिशा पर भी निर्भर होना चाहिए, इसलिए दोनों मामलों में नीचे देखने पर यह थोड़ा गहरा होता है।

फकिंग कास्टिक

यदि आप नकली कास्टिक के लिए एक decal के बजाय एक सहज टाइलिंग 3D-बनावट का उपयोग करते हैं, तो आप ऊर्ध्वाधर सतहों पर खिंचाव से बच सकते हैं। सतह के पास बिखरी हुई रोशनी की ताकत तीन आयामों में भिन्न होती है, इसलिए 2 डी-बनावट का उपयोग आमतौर पर दृश्य में कहीं भी खिंचाव पैदा करता है। आप फर्श के शीर्ष पदों को एक अलग समन्वय प्रणाली में पेश करके बदलते प्रकाश कोणों को मॉडल कर सकते हैं।

एक अन्य संभावना यह है कि प्रकाश की समन्वय प्रणाली में सतह की स्थिति के आधार पर प्रकाश घनत्व की गणना की जाए, हालांकि यह संभवतः कुछ प्रदर्शन की लागत होगी।

कास्टिक को बढ़ती गहराई के साथ फैलने वाले प्रकाश की तुलना में तेजी से फीका करना चाहिए।

रंग ढालना

रंग अलग-अलग बिखरे हुए हैं, इसलिए हल्के रंग को बढ़ती गहराई के साथ बदलना चाहिए। यह अचानक किनारों को भी रोकता है, उदाहरण के लिए, एक समुद्र तट पानी की सतह को काटता है।

घटना का कोण

अपवर्तन के कारण, प्रकाश महासागर के फर्श को सामान्य से अधिक गर्म होने से रोकता है। स्नेल के नियम के बारे में विकिपीडिया लेख कोण और वैक्टर के लिए फार्मूले हैं।


6

मेरा मानना ​​है कि Minecraft में आकाश प्रकाश प्रभाव सीधे नीचे है - चीजों को छायांकित किया जाता है जो उनके ऊपर है कोई फर्क नहीं पड़ता कि सूर्य कहां है। फिर टार्च इत्यादि से स्थानीय प्रकाश व्यवस्था को एक ड्रॉपऑफ़ प्रभाव के साथ लागू किया जाता है - प्रकाश स्रोत से दूर, एक प्रकाश घन जितना कम हो जाता है।

यदि इस तरह से किया जाता है, तो पानी की प्रत्येक परत संचयी रूप से उसके नीचे की परत को छाया देगी, इसलिए प्रत्येक उत्तरोत्तर गहरा हो जाएगा। पेड़ के पत्ते इस तरह से छाया प्रदान करते हैं, हालांकि यह संचयी नहीं है। आप एक पेड़ के नीचे एक ही छाया प्राप्त करते हैं चाहे वह 1 या 100 पर्ण कुटीर हो।

एक सुराग यह है कि यह जिस विधि का उपयोग किया जा रहा है वह यह है कि जब दर्शक नीचे जाते हैं तो पानी अधिक गहरा नहीं होता है - केवल नीचे जाते ही। हां, कोहरे का असर थोड़ी दूरी पर होता है, लेकिन पानी के गहरे प्रभाव से नहीं।

तो प्रकाश की गणना के लिए मूल सूत्र छद्म कोड में कुछ इस तरह होगा ...

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
}

यह ओवरहैंग या गुफाओं के नीचे प्रकाश की गणना के लिए बिल्कुल सही नहीं है, क्योंकि इस पद्धति का उपयोग करके ओवरहांग के नीचे अंधेरा हो जाएगा। लेकिन कोई भी स्थानीय प्रकाश स्रोतों (मशालों, आग, आदि) के साथ-साथ सूर्य के प्रकाश ब्लॉकों को प्रकाश स्रोतों के रूप में मान सकता है। ऐसा कुछ हो सकता है ...

  1. प्रत्येक क्यूब के लिए सीधे ऊपर से (छद्म कोड के माध्यम से) सूर्य से प्रकाश की गणना करें।
  2. यदि किसी घन के पास एक प्रकाश स्रोत है, तो इसे पूरी तरह से जलाए जाने पर विचार करें (1.0)
  3. यदि एक क्यूब सीधे ऊपर से कोई सूरज नहीं प्राप्त कर रहा है, तो इसे पूरी तरह से जलाए गए क्यूब से कितनी दूर है, इसके आधार पर कुछ प्रकाश दें। निकटता का अर्थ है अधिक प्रकाश, दूर का मतलब कम (शून्य तक)।

यहाँ पर विचार यह है कि अगर किसी घन को सूरज या मशाल द्वारा जलाया जाता है, तो उसके आगे का घन भी किसी तरह से जलाया जा सकता है। और जितनी दूर तुम उस रोशनी वाले घन से हो, उतनी ही कम रोशनी होगी। यह फैलाने वाली रोशनी का अनुमान लगाने के लिए एक कीचड़ के रास्ते की तरह है लेकिन मुझे लगता है कि (?) यह काम करेगा।


1
हाँ, मुझे पूरा यकीन है कि यह टिकट है। मैंने अपने खेल में कुछ ऐसा ही किया है।
MichaelHouse

वैसे मैंने अभी-अभी अपने ब्लॉग को अपनी Google रीडर सूची Byte56 में जोड़ा है - डेवलपर ब्लॉग FTW!
टिम होल्ट

ओह, क्यों धन्यवाद अभी भी इस सवाल का विषय है, लेकिन मैं सिर्फ प्रोफेसर बेली की कक्षा के बारे में आपके ब्लॉग को पढ़ता हूं। मैं पिछले साल उस क्लास में था! मुझे पूरा यकीन है कि आपने पिछले साल भी वह प्रस्तुति दी थी। मुझे लगा कि आपका नाम परिचित है। छोटी सी दुनिया :)
MichaelHouse

3

शायद मैं इस सवाल को गलत समझ रहा हूं, लेकिन आप सिर्फ उनकी गहराई के आधार पर ब्लॉक का रंग क्यों नहीं बदल सकते?

यदि आपके पास गहराई d (ब्लॉकों में, 0 से शुरू हो रही है) तो चमक के लिए एक उचित समीकरण होगा:

एल = (1- एम ) - केडी + एम

कोड: L = (1.0 - m) * exp(-k * d) + m;

k नियंत्रित करता है कि यह कितनी तेजी से गहरा (उच्च = तेज) हो जाता है। एक उचित मूल्य 0.5 होगा।
मीटर न्यूनतम चमक है जो आप चाहते हैं।
L 0 से 1 तक भिन्न होता है।

यदि आप नहीं जानते कि आप जो भी ग्राफिक्स एपीआई का उपयोग कर रहे हैं, उसमें ब्लॉक का रंग कैसे बदला जाए, तो कृपया एक अलग प्रश्न के रूप में पूछें (यह बताते हुए कि आप किस एपीआई का उपयोग करते हैं, और क्या आप shaders का उपयोग कर रहे हैं या नहीं)।


मैंने बस ऐसा करने के बारे में नहीं सोचा था। जिज्ञासा से बाहर आपको वह समीकरण कहां से मिला?
जेवियर

1
@Xavier: मैंने अभी इसे बनाया है। e^-kdबिट सिर्फ एक घातीय क्षय, चीजें हैं जो धीरे-धीरे कुछ मूल्य (गहराई) से अधिक शून्य की ओर जाते हैं के लिए एक मानक समारोह है जो है। गुणा (1-m)और जोड़ mकेवल क्षय को मापना और ऑफसेट करना है ताकि यह कम से कम समाप्त हो जाए mलेकिन फिर भी शुरू होता है 1en.wikipedia.org/wiki/Exponential_decay
पीटर एलेक्जेंडर

बात यह है कि, गहरे रंग के ब्लॉक केवल तभी देखे जाएंगे जब ब्लॉक में अल्फा रंग हों; जिस स्थिति में ब्लॉक रंग को बदलने की कोई आवश्यकता नहीं है, अल्फा स्वचालित रूप से प्रभाव पैदा करेगा।
जोनाथन कॉनेल

@ जोनाथन: आप पानी के ब्लॉक को प्रस्तुत नहीं करते हैं, आप समुद्र के बिस्तर पर रंगों को गहरा करने के साथ ब्लॉक प्रदान करते हैं और फिर पानी की सतह पर बस एक अल्फा परत रखते हैं।
पीटर अलेक्जेंडर

@ पेटर अलेक्जेंडर ओके, मैंने माना कि इन ब्लॉक प्रकार के खेलों में, यहां तक ​​कि पानी भी ब्लॉकों से बना था।
जोनाथन कोनेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.