रॉगुलाइक के लिए आशाजनक छाया की तलाश में



प्रिय खाबरोवचन, मैं आपके ध्यान में 2 डी बैगेल के लिए उपयुक्त छाया खोजने के विषय पर अनुसंधान की निरंतरता को प्रस्तुत करता हूं।

यह पोस्ट प्रकाशन की एक अगली कड़ी है, त्रुटियों पर एक तरह का काम और विचार का आगे विकास।

उनकी टिप्पणियों में, सम्मानित आलोचकों ने ठीक ही उल्लेख किया कि संलग्न स्थानों में छाया कोणीय और कुछ हद तक अप्राकृतिक रूप से बदल गए। कई समाधान प्रस्तावित किए गए थे, मुझे छाया की गणना के लिए रे कास्टिंग का उपयोग करने का प्रस्ताव पसंद आया।



मैं स्पष्ट करता हूं, मैं वीडियो कार्ड के साथ काम नहीं करता (मैं अभी तक काम नहीं करता हूं), सभी परिणाम सीपीयू पर मॉडल किए गए हैं।

रीकास्टिंग पर इस काम में, हम एक ऑब्जर्वर से किरणों को अंतरिक्ष में फेंकने तक एक छवि बनाने की विधि को समझते हैं जब तक कि यह एक बाधा (स्क्रीन सीमाओं) के साथ प्रतिच्छेद नहीं करता है और उनकी टक्कर के स्थान को उजागर करता है।

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



एल्गोरिथ्म समझ और अवतार दोनों के लिए पर्याप्त सरल है। मैं अपना खुद का कार्यान्वयन लाऊंगा:

पास्कल
// i,j -  ,  -  // X,Y -    // r -     //   if cos(a)<0 then begin di :=-1; ddi:= 0; end else begin di := 1; ddi:= 1; end; if sin(a)<0 then begin dj :=-1; ddj:= 0; end else begin dj := 1; ddj:= 1; end; //        Y x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); Dx := len(x,y,x1,y1); y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); Dy := len(x,y,x1,y1); sum_lenX := 0; sum_lenY := 0; //    X  Y   a rX := abs(tile_size / cos(a)); rY := abs(tile_size / sin(a)); //    repeat if sum_lenX+DX < sum_lenY+DY then begin x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); i := i+di; //         key := is_wall(i,j); sum_lenX := sum_lenX + DX; if DX<>rX then DX:=rX; //       if r<sum_lenX then Break; end else begin y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); j := j+dj; //         key := is_wall(i,j); sum_lenY := sum_lenY + DY; if DY<>rY then DY:=rY; //       if r<sum_lenY then Break; end; until (      ); // x1,y1   

चूंकि बीम एक ही दूरी पर प्रत्येक अक्ष पर कोशिकाओं को पार करता है, आप गणना पर बचत कर सकते हैं और केवल यह देख सकते हैं कि क्या टाइल के भीतर दीवारें हैं। हमें एक बाधा के साथ एक चौराहे की आवश्यकता है और इसके निर्देशांक को याद रखें।

मेरे कार्यान्वयन में, मैंने सभी त्रिकोणमिति और विभाजनों को प्रत्येक कोण के लिए एक अलग तालिका में रखा, जिसने एल्गोरिथ्म को बहुत तेज किया।

वांछित चरण के साथ सभी दिशाओं में किरणों को लॉन्च करने के बाद, हमें निम्नलिखित चित्र मिलते हैं:



किरणों की संख्या कई हजार तक बढ़ाना और दायरे का वांछित पॉलीहेड्रॉन प्राप्त करना। यह संभव है, 3 डी एक्सीलेटर के रूप में, छवि के प्रत्येक पिक्सेल के लिए किरणों को डालना, लेकिन आप यहाँ वीडियो कार्ड के बिना नहीं कर सकते।



परतों के साथ आगे का काम शुरू होता है।

स्कोप। इसके बाद, किरणें वस्तुओं की गहराई में थोड़ी-सी गुजरती हैं। इस तरह के गेम कन्वेंशन 2 डी गेम्स की एक अनूठी परिवेश विशेषता है।



प्रकाश नक्शा पीढ़ी। हम प्रदर्शन में सुधार करने के लिए अग्रिम और कैश में स्थैतिक प्रकाश स्रोत उत्पन्न करते हैं, हम स्क्रीन पर प्रदर्शित करने की प्रक्रिया में गतिशील लोगों को लागू करते हैं।



सब कुछ एक साथ लाना। जो सब याद आ रहा है वह भयानक राक्षस और खजाना है ... कई खजाने।



प्रकाश के प्रवेश की एक चर वक्रता वाली दीवारें मेरे पास नहीं गईं, लेकिन शायद यह एक शौकिया है।



प्रोटोटाइप बनाने की प्रक्रिया में, मैंने मॉडल के कई रूपों की कोशिश की, उनमें से कुछ हॉरर के लिए बेहतर अनुकूल हैं:



मुझे विशेष रूप से दीवारों से किरणों के कई प्रतिबिंबों का प्रभाव पसंद आया, लेकिन यहां तक ​​कि इसका भोली कार्यान्वयन इतना धीमा था कि मैंने इसे भविष्य के लिए छोड़ दिया जब मैं वीडियो कार्ड के साथ दोस्त बन गया।

आपका ध्यान के लिए धन्यवाद।

खेलने के लिए लिंक (विंडोज़ के लिए exe)

भाग १ , भाग ३

Source: https://habr.com/ru/post/hi431304/


All Articles