एक पूर्ण स्क्रीन क्वाड के साथ एक रेंडरर्ट के लिए पिक्सेल-सही रेंडरिंग


9

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

एक उदाहरण: मैं एक 4x4 बनावट के लिए प्रस्तुत करता हूं और इस मामले में शेडर बस बनावट निर्देशांक (यू, वी) को लाल और हरे रंग के चैनलों में आउटपुट करता है:

return float4(texCoord.rg, 0, 1);

जो मैं इससे बाहर निकलना चाहता हूं वह एक बनावट है जहां ऊपर बाईं ओर पिक्सेल RGB (0,0,0) है और इस प्रकार काला है, शीर्ष दाईं ओर पिक्सेल RGB (255,0,0) है और इस प्रकार एक चमकदार लाल और नीचे बाईं ओर पिक्सेल RGB (0,255,0) है - एक चमकदार हरा।

हालाँकि, इसके बजाय मुझे यह यहाँ दाईं ओर मिलता है:

(सीधे क्वाड प्रतिपादन, कोई सुधार नहीं)
ट्रैक्टर के सीधे प्रतिपादन, कोई सुधार लागू नहीं हुआ

शीर्ष बाएँ पिक्सेल काला है, लेकिन मुझे केवल दूसरे कोनों में अपेक्षाकृत गहरा लाल और गहरा हरा रंग मिलता है। उनके RGB मान हैं (191,0,0) और (0,191,0)। मुझे दृढ़ता से संदेह है कि यह क्वाड के नमूने स्थानों के साथ क्या करना है: शीर्ष बाएं पिक्सेल क्वाड के शीर्ष बाएं कोने को सही ढंग से नमूने देता है और यूवी निर्देशांक के रूप में (0,0) मिलता है, लेकिन दूसरे कोने के पिक्सल से नमूना नहीं होता है क्वाड के अन्य कोनों। मैंने इसे बाईं छवि में क्वाड के प्रतिनिधित्व वाले नीले बॉक्स के साथ चित्रित किया है और सफेद ऊपरी नमूना निर्देशांक को डॉट्स करता है।

अब मुझे पता है कि Direct3D9 में स्क्रीन-एलायंस क्वाड्स रेंडर करते समय आपको अपने निर्देशांक पर लागू होने वाले आधे पिक्सेल ऑफसेट के बारे में पता होना चाहिए। आइए देखें कि मुझे इससे किस प्रकार का परिणाम मिलता है:

(DX9 के आधे पिक्सेल ऑफसेट के साथ प्रस्तुत किया गया क्वाड)
आधा पिक्सेल ऑफसेट के साथ रेंडर किया गया क्वाड

लाल और हरे रंग की उज्ज्वल है, लेकिन अभी भी सही नहीं हैं: 223 लाल या हरे रंग के चैनल पर अधिकतम है। लेकिन अब, मेरे पास अब शुद्ध काला भी नहीं है, लेकिन आरजीबी (32,32,0) के साथ एक गहरे पीले रंग का धूसर रंग है!

मुझे वास्तव में इस तरह के प्रतिपादन की आवश्यकता होगी:

(लक्ष्य रेंडर, क्वाड साइज घटाया गया)
शुद्ध काले, साग और सही प्रक्षेप के साथ लाल

ऐसा लग रहा है कि मुझे अपने फिगर के मुकाबले अपने क्वाड के बायीं और नीचे की सीमा को बिल्कुल एक पिक्सेल ऊपर और बाईं ओर ले जाना है। फिर सही कॉलम और पिक्सल की निचली पंक्ति को सही ढंग से यूवी को निर्देश देना चाहिए कि यह क्वाड की सीमा से सही है:

VertexPositionTexture[] quad = new VertexPositionTexture[]
{
    new VertexPositionTexture(new Vector3(-1.0f,  1.0f, 1f), new Vector2(0,0)),
    new VertexPositionTexture(new Vector3(1.0f - pixelSize.X,  1.0f, 1f), new Vector2(1,0)),
    new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
    new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};

हालांकि यह काफी काम नहीं आया और नीचे और दाएं पिक्सल को बिल्कुल भी रेंडर नहीं करने का कारण बना। मुझे लगता है कि इन पिक्सेल केंद्रों को अब क्वाड द्वारा कवर नहीं किया जाता है और इस प्रकार यह shader द्वारा संसाधित नहीं होगा। अगर मैं कुछ छोटी राशि से पिक्सेल की गणना को बदल देता हूं तो क्वाड को एक छोटी राशि से बड़ा बनाने के लिए यह थोड़े काम करता है ... कम से कम 4x4 बनावट पर। यह छोटे बनावट पर काम नहीं करता है और मुझे डर है कि यह बड़ी बनावट पर uv मूल्यों के समान वितरण को भी सूक्ष्म रूप से विकृत करता है:

Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);

(मैंने छोटे आकार के टैक्स्टों के लिए पिक्सेल आकार को 0.001 एफ द्वारा संशोधित किया है, जैसे 1 डी लुकअप टेबल, यह काम नहीं करता है और मुझे इसे 0.01 एफ या कुछ बड़ा करना है)

बेशक यह एक तुच्छ उदाहरण है और मैं इस गणना को सीपीयू पर पिक्सेल केंद्रों में यूवी की मैपिंग की चिंता किए बिना बहुत आसानी से कर सकता था ... फिर भी, वास्तव में एक पूर्ण, पूर्ण प्रस्तुत करने का एक तरीका होना चाहिए [0, 1] रेंडरर्ट पर पिक्सेल की रेंज !?


ऐसा नहीं है कि यह किसी भी मदद की है, लेकिन मैं एक ही समस्या है।
IUsedToBeAPygmy

1
रैखिक नमूने को भी अक्षम करना न भूलें।
r2d2rigo

यह उस समन्वय प्रणाली की तरह नहीं दिखता है जिसका आप स्क्रीन के पिक्सेल से मिलान कर रहे हैं- यदि यह था, तो ऐसा लगता है कि आप यहाँ केवल 2 × 2 पिक्सेल ही खींच रहे हैं। पहला मुद्दा जो मैं हल कर रहा हूं वह है प्रोजेक्ट और मॉडलव्यू मैट्रिसेज़ को स्केल किया गया जैसे कि कोऑर्डिनेट स्पेस में स्क्रीन पर 1 पिक्सेल की शिफ्ट।
स्लिप डी। थॉम्पसन

जवाबों:


4

आपकी समस्या यह है कि यूवी को बनावट निर्देशांक के लिए डिज़ाइन किया गया है। 0,0 का एक समन्वय बनावट में शीर्ष बाएं पिक्सेल का ऊपरी बाएं कोने है, जो कि आप सामान्य रूप से बनावट को पढ़ना चाहते हैं, वह नहीं है। 2D के लिए आप उस पिक्सेल के बीच की बनावट को पढ़ना चाहते हैं।

यदि मेरा गणित सही है, तो आपको उस दौर में काम करने की आवश्यकता है:

return float4((texCoord.rg - (0.5f/textureSize)) * (textureSize/(textureSize-1)), 0, 1);

यही है कि आप 0,0 पर शीर्ष बाएँ पिक्सेल को प्राप्त करने के लिए उपयुक्त ऑफ़सेट को घटाते हैं और फिर नीचे दाएं दाईं ओर प्राप्त करने के लिए एक स्केल लागू करते हैं।

0-1 की सीमा के बाहर ज्यामिति के लिए यूवी निर्देशांक का विस्तार करके भी यही बात हासिल की जा सकती है।


अंतिम वाक्य पर विस्तार से बताने के लिए: आप क्वाड के चार कोनों के लिए वर्वेज़ बफर में UVs के लिए इस परिवर्तन को लागू कर सकते हैं, फिर पिक्सेल शेडर में बस करें return float4(texCoord.rg, 0, 1);
नाथन रीड

मैंने ऊपर सुझाए गए सूत्र की कोशिश की और यह काफी काम नहीं आया: ऊपर से मेरे 4x4 नमूना रेंडरर्ट में, मुझे आर और जी चैनलों में 0, 42, 127 और 212 मिलते हैं, बाएं से दाएं या ऊपर से नीचे तक। हालाँकि, मैं 0 से 255 तक के मूल्यों को समान रूप से स्थानिक चरणों (4x4 बनावट के लिए 0, 85, 170 और 255 के लिए) चाहूंगा। मैंने यूवी निर्देशांक को बदलने की भी कोशिश की, लेकिन अभी तक सही ऑफसेट नहीं मिला।
मारियो

0

ऐसा लग रहा है कि मुझे अपने फिगर के मुकाबले अपने क्वाड के बायीं और नीचे की सीमा को बिल्कुल एक पिक्सेल ऊपर और बाईं ओर ले जाना है।

लगभग, लेकिन पिक्सेल का केवल आधा। बस अपने क्वाड वर्जन से 0.5 घटाएं। जैसे आप एक ही बनावट के साथ 256x256 क्वाड चाहते हैं, यहां आपके बिंदु हैं:

p1 = (-0.5, -0.5)
p2 = (-0.5, 255-0.5)
p3 = (255-0.5, 255-0.5)
p4 = (255-0.5, -0.5)

या, आप इसके बजाय पिक्सेल shader में टेक्सेल का आधा जोड़ सकते हैं (texCoord.rg + 0.5 * (1.0 / texSize))

डीएक्स 9 में आधा पिक्सेल ऑफसेट एक ज्ञात तथ्य है। यह और यह लेख आपकी मदद कर सकते हैं।


0

यह निश्चित रूप से रैखिक नमूने के कारण हो रहा है। यदि आप टेक्सल्स को पूर्ण-ब्लैक टॉप-लेफ्ट पिक्सेल के दाईं ओर और नीचे देखते हैं, तो आप देखेंगे कि उनके पास R और / या G चैनल में 63 हैं, और उनमें से 2 के पास B. में 2 हैं। अब देखिए मैला-गहरा-पीला आपको मिलता है; यह आर और जी में 31 और बी में 1 है। निश्चित रूप से एक 2x2 समूह पर औसत टेक्सल्स का परिणाम है, इसलिए समाधान आपके बनावट फ़िल्टर को इंगित करने के लिए सेट करना है।


-2

यह केवल बीक्युस है जो आप शीर्ष आउटपुट से टेक्सचर्ड्स का उपयोग कर रहे हैं जो कि वर्टेक्स शेडर के प्रसंस्करण के बाद हार्ड ड्राइव द्वारा प्रक्षेपित होता है।

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