2011-09-29 14 views
5

के लिए क्लिप मैट्रिक्स मैं एक साधारण 3 डी ग्राफिक्स इंजन बनाने की कोशिश कर रहा हूं और मैंने यहां समीकरणों को पाया और उपयोग किया है: http://en.wikipedia.org/wiki/3D_projection#cite_note-0। (मेरे पास डीएक्स, डीई, डीजे और बीएक्स के लिए गणना है)3 डी परिप्रेक्ष्य प्रोजेक्शन

मैं काम करता हूं, लेकिन जब मैं कैमरे को घुमाता हूं तो पर्याप्त जगहें पूरी जगह उड़ती हैं और आखिर में आप देखते हैं कि स्क्रीन से निकले बहुभुज वापस आना शुरू हो जाते हैं स्क्रीन के विपरीत दिशा में (आप यहां जा सकते हैं: http://mobile.sheridanc.on.ca/~claassen/3d.html और कैमरे को घुमाने के लिए मैं क्या बात कर रहा हूँ देखने के लिए डब्ल्यू, ए, एस और डी कुंजी का उपयोग करें)

मैं इस चर्चा पढ़ें: How to convert a 3D point into 2D perspective projection? जहां वह एक क्लिप मैट्रिक्स का उपयोग करने के बारे में बात की लेकिन मैं अभी भी थोड़ा उलझन में हूं कि वास्तव में एक का उपयोग कैसे किया जाए। इसके अलावा मुझे यकीन नहीं है कि क्या मैं चर्चा में वर्णित अनुसार 'समरूप समन्वय' का उपयोग कर रहा हूं।

उत्तर

18

परिप्रेक्ष्य प्रोजेक्शन मैट्रिक्स (उर्फ क्लिप मैट्रिक्स) द्वारा गुणा करने के बाद आप एक समरूप 4-वेक्टर [x, y, z, w] के साथ समाप्त होते हैं। इसे एनपीसी (सामान्यीकृत प्रक्षेपण निर्देशांक) कहा जाता है, और क्लिप निर्देशांक भी कहा जाता है। 2 डी स्क्रीन पर निर्देशांक प्राप्त करने के लिए आप आम तौर पर इस आप देता है कि आप क्या चाहते

xscreen = (x/w) * screen_width 
yscreen = (y/w) * screen_width 

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

कोशिश करने की एक त्वरित बात यह है कि किसी भी रेखा को न खींचें यदि वर्टेक्स डब्ल्यू < 0 है। यह आपके दृश्य में दिखाई देने वाले अजीब बहुभुज को ठीक करना चाहिए। लेकिन यह कुछ लाइनों को भी हटा देगा जो दिखाना चाहिए।

कैमरे के सामने एक कशेरुका और कैमरे के पीछे एक कशेरुक वाली सभी पंक्तियों को क्लिप करने के लिए आपको जिस समस्या की आवश्यकता है उसे पूरी तरह ठीक करने के लिए। क्लिपिंग का मतलब है कि रेखा को आधे में काटकर कैमरे के पीछे आधा भाग फेंकना। रेखा कैमरे के माध्यम से एक विमान द्वारा "clipped" है और प्रदर्शन स्क्रीन के समानांतर है। समस्या यह है कि इस विमान से संबंधित रेखा पर बिंदु ढूंढना है (यानी जहां रेखा विमान को छेड़छाड़ करती है)। यह लाइन पर बिंदु पर होगा जहां w == 0।आप इस बिंदु पा सकते हैं, लेकिन तब जब आप स्क्रीन खोजने की कोशिश निर्देशांक

xscreen = (x/w) * screen_width 
yscreen = (y/w) * screen_width 

आप से 0 (== 0 डब्ल्यू) विभाजित अंत। "क्लिपिंग प्लेन के पास" का यही कारण है। पास क्लिपिंग विमान डिस्प्ले स्क्रीन के समानांतर है लेकिन कैमरे के सामने (कैमरा और दृश्य के बीच) है।

[ near/width ][  0  ][   0    ][  0  ] 
[  0  ][ near/height ][   0    ][  0  ] 
[  0  ][  0  ][(far+near)/(far-near) ][  1  ] 
[  0  ][  0  ][-(2*near*far)/(far-near)][  0  ] 

के पास विमान आप लाइन है कि निकट कतरन विमान काटती है पर बिंदु मिल करने के लिए क्लिप करने के लिए: कैमरा और पास कतरन विमान के बीच की दूरी प्रक्षेपण मैट्रिक्स के "पास" पैरामीटर है। यह वह बिंदु है जहां w == पास है। तो तुम कोने v1 के साथ एक पंक्ति है, वी 2 आप यदि प्रत्येक शिखर के सामने या पास क्लिप विमान के पीछे है जांच करने की जरूरत है, जहां

v1 = [x1, y1, z1, w1] 
v2 = [x2, y2, z2, w2] 

है। यदि w1 < पास है तो w1> = निकट और पीछे अगर V1 सामने है। यदि v1 और v2 दोनों सामने हैं तो रेखा खींचें। यदि v1 और v2 दोनों पीछे हैं तो रेखा खींचें नहीं। यदि v1 सामने है और v2 तो पीछे है, जहां आप लाइन के पास क्लिप विमान काटती है vc खोजने की जरूरत है:

n = (w1 - near)/(w1 - w2) 
xc = (n * x1) + ((1-n) * x2) 
yc = (n * y1) + ((1-n) * y2) 
zc = (n * z1) + ((1-n) * z2) 
vc = [xc, yc, zc, wc] 

अब v1 और कुलपति के बीच रेखा खींचते।

+0

मैं अच्छी तरह लिखित उत्तर के लिए आपको धन्यवाद नहीं दे सकता। इससे मुझे बहुत मदद मिली है ... या तो पर्याप्त वोट नहीं दे सकता है। – shbi

+0

यह एक अच्छा जवाब है, लेकिन कुछ ऐसी चीजें हैं जिन पर मैं अस्पष्ट हूं। सबसे पहले, क्या आप लाइन 'wc = (n * w1) + ((1 - n) * w2) गायब हैं? इसके अलावा, क्या आपके प्रक्षेपण मैट्रिक्स पी दाहिने i.e. v_e * पी पर गुणा किया गया है? अधिक महत्वपूर्ण बात यह है कि मैंने उपयोग किए गए कोई रेंडरर के लिए मुझे ड्रॉ टाइम पर निकटतम विमान निर्दिष्ट करने की आवश्यकता नहीं है - जब आप निकट मूल्य ज्ञात नहीं हैं तो आप इस क्लिपिंग को कैसे कर सकते हैं? – Qualia

+0

मुझे तात्कालिक रूप से एक उत्तर मिल गया है। स्पष्ट रूप से, ज़िप क्लिपिंग, आप डब्ल्यू को बाधित करते हैं, क्योंकि वे रैखिक रूप से निर्भर हैं। मेरी समस्या यह थी कि, यदि आप डब्ल्यू को इंटरपोल कर रहे हैं, तो आप क्लिप वैल्यू को इंटरपोल कर रहे हैं जिसके खिलाफ आप जेड का परीक्षण करते हैं। वास्तव में, समीकरण उतना कठिन नहीं है जितना मैंने सोचा था। V_1 और v_2 से दी गई वर्टेक्स v_3 के लिए, जिसकी रेखा क्लिप प्लेन को छेड़छाड़ करती है, 'w_3 = w_1 + r * (w_2-w_1) 'और' a_3 = a_1 + r * (a_2-a_3)', जहां 'a_n = dot (विमान, v_n) '। लेकिन ए_3 क्लिप वैल्यू के बराबर है, w_3, तो 'a_1 + r * (a_2-a_1) = w_1 + r * (w_2-w_1)'। आर के लिए हल करें, और आप कर रहे हैं। (मुझे उम्मीद है)। – Qualia

4

इस शब्दावली का एक गलतफहमी हो सकती है। क्लिप मैट्रिक्स अधिक उचित रूप से प्रक्षेपण मैट्रिक्स के रूप में जाना जाता है। ओपनजीएल में कम से कम, प्रोजेक्शन मैट्रिक्स में 4 डी समरूप समन्वय को बदलता है समन्वय स्थान (वीसीएस)क्लिपिंग समन्वय स्थान (सीसीएस) देखें। सामान्यीकृत डिवाइस coodinate अंतरिक्ष (NDCS) को सीसीएस से प्रोजेक्शन डब्ल्यू घटक द्वारा प्रत्येक घटक विभाजित परिप्रेक्ष्य विभाजन है, यानी की आवश्यकता है। इस कदम से पहले क्लिपिंग सही ढंग से की जाती है। तो, एक 'क्लिपिंग मैट्रिक्स' प्रक्षेपण से पहले ज्यामिति को क्लिप करने की आवश्यकता को हटा नहीं देता है। मुझे उम्मीद है कि मैंने आपको समझा है, और यह संवेदना नहीं करता है।

उसने कहा, मुझे लगता है कि आपको स्पष्ट रूप से प्रोजेक्शन मैट्रिक्स सही मिला है - यह काम करता है। मुझे संदेह है कि आंख के पीछे गुजरने वाले चरम नकारात्मक डब्ल्यू हैं, जिसका अर्थ है कि उन्हें क्लिप किया जाना चाहिए; लेकिन मुझे यह भी संदेह है कि उनके पास नकारात्मक ज़ेड है, इसलिए विभाजन सकारात्मक जेड वैल्यू दे रहा है। यदि आप वास्तव में संपूर्ण त्रिकोणों को छोड़ने के बजाय ज्यामिति को क्लिप करना चाहते हैं, तो 'सजातीय क्लिपिंग' की खोज करें। यदि आप वास्तव में 4 डी सजातीय जगह में काम नहीं कर रहे हैं, तो आप 'सुथरलैंड-होडगमैन' 3 डी क्लिपिंग को देखकर शुरू कर सकते हैं।