ओपनजीएल - किनारों का पता लगाना


12

मैं मनमाने ढंग से मेश लोड करना चाहता हूँ और किनारों पर मोटी काली रेखाएँ खींचना चाहता हूँ ताकि लुक-अप जैसा लुक पा सकें। मैं स्टैंसिल बफर का उपयोग करके वस्तुओं के चारों ओर एक काले सिल्हूट को खींचने में कामयाब रहा। आप यहाँ परिणाम देख सकते हैं:

यहाँ छवि विवरण दर्ज करें

लेकिन जो चीज गायब है वह वस्तु में काली रेखाएँ हैं। मैंने सामान्य असंतोषों की जाँच करने के बारे में सोचा: यह जाँचना कि क्या एक पड़ोसी पिक्सेल में वर्तमान की तुलना में एक अलग सामान्य वेक्टर है। यदि हाँ, एक किनारे पाया गया है। दुर्भाग्य से, मुझे पता नहीं है कि मैं इस दृष्टिकोण को कैसे लागू कर सकता हूं, न तो ओपनजीएल में और न ही जीएसएसएल वर्टेक्स / टुकड़ा shader में।

मैं इस दृष्टिकोण या किनारे का पता लगाने के बारे में किसी भी मदद के लिए बहुत खुश हूँ।

संपादित करें: मैं अपने जाल के लिए किसी भी बनावट का उपयोग नहीं करता हूं।

बहुत अधिक सटीक हो, मैं एक सीएडी / सीएएम समाधान बनाना चाहता हूं जो इस तरह दिखता है (शीर्ष ठोस https://www.youtube.com/watch?v=-qTJZtYUDB4 से लिया गया ):

यहाँ छवि विवरण दर्ज करें


मेरा मानना ​​है कि आपको "किनारे" को अधिक विस्तार से परिभाषित करने की आवश्यकता है। यह एक साधारण वायरफ्रेम से कैसे भिन्न होता है? Cifz उत्तर में स्क्रीन स्पेस पोस्ट-प्रोसेस का एक अच्छा विवरण है, लेकिन आपके प्रश्न से यह निर्धारित करना मुश्किल है कि क्या यह लागू है।
एंड्रियास

खैर, किनारे से मेरा मतलब है "घटता" और "लकीरें" जो ठोस बनाती हैं। एक वायरफ्रेम सभी त्रिभुज चेहरों को प्रदर्शित करेगा, जो कि मैं नहीं चाहता।
enne87

ठीक है, वास्तव में मैंने जो पूछा था :-) मैं उन क्रीज और लकीरों से एक वायरफ्रेम उत्पन्न करूंगा। मुश्किल हिस्सा अभी भी यह निर्धारित करने के लिए है कि क्रीज / रिज क्या है। क्या आपको पता है कि कैसे करना है?
एंड्रियास

1
कैड प्रोग्राम ज्यादातर शेडर के साथ ऐसा नहीं करते हैं। इसके बजाय वे मॉडल से हार्ड किनारों को जानते हैं और उस जानकारी के जाल के शीर्ष पर एक रेखा खींचते हैं।
पूजा

joojaa क्या आपको इस तकनीक के बारे में कोई और जानकारी है? दोहरे घुमावदार मुक्त रूप सतहों के मामले में क्या किया जाता है? मुझे यह भी पता नहीं है कि जब आपके पास शंकु या एक सिलेंडर होता है जो कुछ मुक्त रूप से कट / छंटनी हो रही है। stackoverflow.com/questions/43795262/…
Dusan Bosnjak 'pailhead'

जवाबों:


18

आम तौर पर एज डिटेक्शन उच्च ढाल मूल्य वाले छवि के क्षेत्रों का पता लगाने के लिए उबलता है।

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

आप कैसे इस ढाल को वास्तव में आप क्या पूछ रहे हैं और मुझे जवाब देना बाकी है :)

बहुत सारे तरीके! यहाँ एक जोड़ी :)

शेड कार्यों में निर्मित

दोनों hlsl और glsl व्युत्पन्न कार्य प्रदान करते हैं। GLSL में आपके पास dFdx और dFdy हैं जो आपको क्रमशः x और y दिशा में क्रमिक जानकारी देते हैं। आमतौर पर इन कार्यों का मूल्यांकन 2x2 टुकड़ों के एक ब्लॉक में किया जाता है।
जब तक आप एक ही दिशा में रुचि रखते हैं, एक अच्छा तरीका है एक कॉम्पैक्ट नतीजा यह है कि इंगित करता है कैसे मजबूत क्षेत्र में ढाल कर रहा है के लिए fwidth है कि आप और कुछ नहीं लेकिन dFdy और dFdy का निरपेक्ष मान का योग देता है।
आपको किसी विशिष्ट चैनल के बजाय समग्र छवि पर एक किनारे में रुचि होने की संभावना है, इसलिए आप अपनी छवि फ़ंक्शन को लूमा में बदलना चाह सकते हैं। इसे ध्यान में रखते हुए, जब यह पता चलता है कि आपके शेड में कुछ इस तरह शामिल हो सकता है:

  float luminance = dot(yourFinalColour,vec3(0.2126, 0.7152, 0.0722));
  float gradient = fwidth(luminance );
  float isEdge = gradient > threshold;

एक उच्च सीमा के साथ आप मोटे किनारों को पाएंगे और आप कुछ को याद कर सकते हैं, इसके विपरीत, कम सीमा के साथ आप गलत किनारों का पता लगा सकते हैं। आपको उस सीमा को खोजने के लिए प्रयोग करना होगा जो आपकी आवश्यकताओं के अनुसार बेहतर हो।

इन कार्यों के कारण का उल्लेख करने लायक है, लेकिन मेरे पास इसके लिए अभी समय नहीं है, मुझे इस उत्तर को बाद में अपडेट करने की संभावना है :)

स्क्रीन स्पेस पोस्ट-प्रोसेस

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

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

                                   यहाँ छवि विवरण दर्ज करें

जो क्रमशः आपको x और y दिशाओं में ग्रेडिएंट देते हैं:

                                  एक पुराने पीडीएफ से मैंने बहुत पहले लिखा था।

जीआरमैंnटीजीnमैंटीयू=(जीआरमैंnटीएक्स)2+(जीआरमैंnटीy)2

फिर आप उसी तरह से बता सकते हैं जिस तरह से मैंने ऊपर बताया है।

यह कर्नेल जैसा कि आप केंद्रीय पिक्सेल को अधिक वजन दे सकते हैं, इसलिए प्रभावी रूप से ग्रेडिएंट + को थोड़ा चौरसाई कर रहा है जो पारंपरिक रूप से मदद करता है (अक्सर छवि छोटे किनारों को खत्म करने के लिए धुंधली होती है)।

उपरोक्त काफी अच्छी तरह से काम करता है, लेकिन अगर आपको चौरसाई पसंद नहीं है तो आप प्रीविट कर्नेल का उपयोग कर सकते हैं:

                                                   यहाँ छवि विवरण दर्ज करें

(नोट मैं जल्दबाज़ी में हूँ, जल्द ही चित्रों के बजाय उचित स्वरूपित पाठ लिखूंगा!)

वास्तव में वास्तविक समय ग्राफिक्स के बजाय छवि प्रक्रिया-वाई तरीके से बढ़त का पता लगाने के लिए बहुत अधिक गुठली और तकनीकें हैं, इसलिए मैंने अधिक जटिल (दंडित इरादा नहीं) विधियों को बाहर रखा है क्योंकि शायद आप dFdx / y फ़ंक्शन के साथ ठीक हो जाएंगे ।


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

यदि आप आस्थगित रेंडरर का उपयोग करते हैं तो आप वही कर सकते हैं लेकिन सामान्य बफर या फिर से, यदि आपके पास कोई पूर्वाग्रह है तो आप एल्गोरिथ्म को गहराई तक लागू कर सकते हैं। फिर भी आप सही हैं, एक स्क्रीन स्पेस एप्रोच सभी मामलों में आदर्श नहीं हो सकता है :) क्या समाधान व्यवहार्य है इस बात पर बहुत निर्भर करता है कि इस प्रभाव के लिए आपका बजट क्या है, आपका दृश्य कितना जटिल है।
cifz

संभावित रूप से अगर यह आपके खेल के लिए वास्तव में केंद्रीय है, तो एक बहुत ही आसान, लेकिन संभावित रूप से कर लगाना, प्रत्येक पड़ोस के लिए अपने मानक मानदंडों पर एक ढाल की गणना करना होगा (लोड समय पर ऑफ़लाइन) और अतिरिक्त कारक विशेषता के रूप में इस कारक को पास करें।
cifz

आपकी मदद के लिए फिर से थांग्स। ठीक है, मैं जो हासिल करना चाहता हूं वह एक सीएडी / सीएएम समाधान विकसित करना है जो इस तरह दिखता है: youtube.com/watch?v=-qTJZtYUDB4 और मैं वास्तव में जानना चाहता हूं कि कैसे उन्होंने इसे सभी काले किनारों को प्रस्तुत करने में कामयाब किया, और लकीरें खींचता है। cifz, क्या आपको लगता है कि ग्राफिक्स प्रोग्रामिंग के विशेषज्ञ के रूप में उन्होंने अपने स्क्रीन स्पेस दृष्टिकोणों में से किसी एक का उपयोग करके इस लुक को हासिल किया है? या शायद पड़ोसी मानदंडों पर एक ढाल की गणना करके? मैं वास्तव में जानना चाहता हूं कि यह कैसे किया जा सकता है। एक बार फिर धन्यवाद!
enne87

1
किसी को भुगतान करने की आवश्यकता नहीं है, बस कुछ ट्यूटोरियल पढ़ना शुरू करें, कुछ किताबें खरीदें और कठिन अध्ययन करें :) यह अंत में बहुत फायदेमंद होगा!
cifz

3

बस किसी को भी ऐसो को किनारों का पता लगाने की आवश्यकता होती है: यहां एक अच्छा लेख है कि वायरफ्रेम कैसे प्रदर्शित किया जाए और यह लेख बताता है कि केवल किनारों को कैसे दिखाया जाए।

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