2016-09-07 5 views
6

मैं अगले कोड का उपयोग कर Unity3D का स्वत: द्विरेखीय छानने एल्गोरिथ्म को दोहराने के लिए कोशिश कर रहा हूँ:बिलीनेर फ़िल्टरिंग नहीं होने पर यह तकनीक क्या है?

fixed4 GetBilinearFilteredColor(float2 texcoord) 
{ 
    fixed4 s1 = SampleSpriteTexture(texcoord + float2(0.0, _MainTex_TexelSize.y)); 
    fixed4 s2 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, 0.0)); 
    fixed4 s3 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, _MainTex_TexelSize.y)); 
    fixed4 s4 = SampleSpriteTexture(texcoord); 

    float2 TexturePosition = float2(texcoord)* _MainTex_TexelSize.z; 

    float fu = frac(TexturePosition.x); 
    float fv = frac(TexturePosition.y); 

    float4 tmp1 = lerp(s4, s2, fu); 
    float4 tmp2 = lerp(s1, s3, fu); 

    return lerp(tmp1, tmp2, fv); 
} 

fixed4 frag(v2f IN) : SV_Target 
{ 
    fixed4 c = GetBilinearFilteredColor(IN.texcoord) * IN.color; 
    c.rgb *= c.a; 
    return c; 
} 

मैंने सोचा कि मैं सही एल्गोरिथ्म उपयोग कर रहा था क्योंकि केवल एक ही मैं द्विरेखीय के लिए वहाँ बाहर देखा है।

  • 1º बनावट: है प्वाइंट छानने में और कस्टम द्विरेखीय शेडर (डिफ़ॉल्ट स्प्राइट शेडर से maded) का उपयोग लेकिन मैं इसे एक ही बनावट दोहराया के साथ एकता उपयोग करने की कोशिश।
  • 2º बनावट: डिफ़ॉल्ट स्प्राइट शेडर

साथ द्विरेखीय फिल्टर में है और यह परिणाम है:

enter image description here

आपको लगता है कि वे अलग हैं देख सकते हैं और यह भी वहाँ कुछ है मेरे कस्टम शेडर में विस्थापन जो ज़ेड अक्ष में घूमते समय स्प्राइट ऑफ-सेंटर बनता है।

क्या मैं गलत कर रहा हूं इसका कोई विचार? यूनिटी 3 डी क्या कर रहा है इसके बारे में कोई विचार? क्या कोई और एल्गोरिदम है जो यूनिटी 3 डी डिफ़ॉल्ट फ़िल्टरिंग में फिट बैठता है?

समाधान

अन्य लोगों को जो यहाँ इसके लिए खोज के लिए निको के कोड के साथ पूरा कोड समाधान के साथ अपडेट किया गया:

fixed4 GetBilinearFilteredColor(float2 texcoord) 
{ 
    fixed4 s1 = SampleSpriteTexture(texcoord + float2(0.0, _MainTex_TexelSize.y)); 
    fixed4 s2 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, 0.0)); 
    fixed4 s3 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, _MainTex_TexelSize.y)); 
    fixed4 s4 = SampleSpriteTexture(texcoord); 

    float2 TexturePosition = float2(texcoord)* _MainTex_TexelSize.z; 

    float fu = frac(TexturePosition.x); 
    float fv = frac(TexturePosition.y); 

    float4 tmp1 = lerp(s4, s2, fu); 
    float4 tmp2 = lerp(s1, s3, fu); 

    return lerp(tmp1, tmp2, fv); 
} 

fixed4 frag(v2f IN) : SV_Target 
{ 
    fixed4 c = GetBilinearFilteredColor(IN.texcoord - 0.498 * _MainTex_TexelSize.xy) * IN.color; 
    c.rgb *= c.a; 
    return c; 
} 

और परिणाम के साथ छवि परीक्षण:

enter image description here

0.5 बिल्कुल ठीक क्यों नहीं करते?

यदि आप इसका परीक्षण करते हैं तो आप कुछ किनारे के मामलों को देखेंगे जहां यह (पिक्सेल -1) तक कूदता है।

उत्तर

6

चलो देखते हैं कि आप वास्तव में क्या कर रहे हैं। मैं 1 डी मामले में रहूंगा क्योंकि इसे देखना आसान है।

आपके पास पिक्सेल और एक बनावट की स्थिति है। मुझे लगता है, _MainTex_TexelSize.z एक तरह से स्थापित है, जैसे कि यह पिक्सेल निर्देशांक देता है। अपने नमूने (निकटतम बिंदु नमूना कल्पना करते हुए) के साथ

Pixels

, आप पिक्सल 2 मिल जाएगा: यह आपको क्या मिलेगा (बक्से पिक्सेल अंतरिक्ष निर्देशांक नीचे पिक्सेल संख्या और संख्या बक्से में पिक्सल, संख्या का प्रतिनिधित्व करते हैं) है और 3. हालांकि, आप देखते हैं कि lerp के लिए इंटरपोलेशन समन्वय वास्तव में गलत है। आप बनावट की स्थिति का अंश भाग (यानी 0.8) पारित करेंगे, लेकिन यह 0.3 (= 0.8 - 0.5) होना चाहिए। इसके पीछे तर्क काफी सरल है: यदि आप पिक्सेल के केंद्र में उतरते हैं, तो आप पिक्सेल मान का उपयोग करना चाहते हैं। यदि आप दो पिक्सेल के बीच बीच में सही जमीन पर उतरते हैं, तो आप दोनों पिक्सेल मानों का औसत उपयोग करना चाहते हैं (यानी 0.5 का इंटरपोलेशन मान)। अभी, आपके पास मूल रूप से बाएं से आधा पिक्सेल ऑफसेट है।

जब आप पहली बार इस समस्या का समाधान है, वहाँ एक दूसरे से एक है:

Pixels

इस मामले में, आप वास्तव में पिक्सेल 1 और 2 के बीच मिश्रण करने के लिए चाहते हैं लेकिन क्योंकि तुम हमेशा में सही करने के लिए जाना आपका नमूनाकरण, आप 2 और 3 के बीच मिश्रण करेंगे। फिर, गलत इंटरपोलेशन मान के साथ।

समाधान बहुत आसान होना चाहिए:

fixed4 c = GetBilinearFilteredColor(IN.texcoord - 0.5 * _MainTex_TexelSize.xy) * IN.color; 
: बनावट से पिक्सेल चौड़ाई का घटाना आधा इसके साथ कुछ भी है, जो शायद सिर्फ है निम्नलिखित (यह मानते हुए कि आपके चर बातें मुझे लगता है कि पकड़) करने से पहले समन्वय

परिणाम अलग-अलग कारण हैं कि एकता वास्तव में एक अलग फ़िल्टर का उपयोग करती है, उदाहरण के लिए बाइबिक (लेकिन मुझे नहीं पता)। इसके अलावा, मिपमैप्स का उपयोग परिणाम को प्रभावित कर सकता है।

संबंधित मुद्दे