2011-11-07 16 views
5

Image of shader resultGLSL Gif तड़पना प्रभाव: अधिक उपयोग

मैं एक टुकड़ा शेडर कि अनिवार्य रूप से रंग अल्फा पढ़ता है और पिक्सल भर में एक कटौती के प्रभाव में इसकी अनुवाद मिल गया है।

हालांकि, यह सभी मोड और यदि कथन के साथ काफी प्रोसेसर गहन है। क्या किसी के पास नीचे दिए गए कोड को अनुकूलित करने पर कोई सिफारिश है?

varying vec2 the_uv; 
varying vec4 color; 

void main() 
{ 
    // The pixel color will correspond 
    // to the uv coords of the texture 
    // for the given vertice, retrieved 
    // by the Vertex shader through varying vec2 the_uv 

    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); 
    vec4 tex = texture2D(_MainTex, the_uv); 
    tex = tex * color ; 
    float r = tex.a; 

    if (r > 0.1) { 
     if ((mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0)) > 6.00) { 
      gl_FragColor = color; 
     } 
    } 

    if (r > 0.5) { 
     if ((mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y, 4.0)) > 6.00) { 
      gl_FragColor = color; 
     } 
    } 

    if (r > 0.7) { 
     if ((mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0)) > 6.00) { 
      gl_FragColor = color; 
     } 
    } 

    if (r > 0.9) { 
     if ((mod(gl_FragCoord.x + 1.0, 4.001) + mod(gl_FragCoord.y + 1.0, 4.0)) > 6.00) { 
      gl_FragColor = color; 
     } 
    } 

    if (r > 0.3) { 
     if ((mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0)) > 6.00) { 
      gl_FragColor = color; 
     } 
    } 
} 

यहाँ समाधान प्रतिक्रिया के आधार पर है:

 varying vec2 the_uv; 
     varying vec4 color; 

     void main() 
     { 
      color = gl_Color; 
      gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
      the_uv = gl_MultiTexCoord0.st; 
     } 
     #endif 

     #ifdef FRAGMENT 
     uniform sampler2D _MainTex; 
     uniform sampler2D _GridTex; 
     varying vec2 the_uv; 
     varying vec4 color; 

     void main() 
     { 
      if (texture2D(_MainTex, the_uv).a * color.a > texture2D(_GridTex, vec2(gl_FragCoord.x, gl_FragCoord.y)*.25).a) gl_FragColor = color; 
      else gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); 

     } 
+0

आप अपने चर के लिए बहुत सामान्य नाम है का उपयोग करके/4 से बच सकते हैं। यदि आप अधिक अभिव्यक्तिपूर्ण नामों का उपयोग करते हैं तो यह पता लगाने के लिए कि आपका एल्गोरिदम क्या है, यह एक _lot_ आसान होगा। –

उत्तर

6

आप जो करने का प्रयास कर रहे हैं यह चुनने के लिए है कि प्रत्येक पिक्सेल को स्रोत अल्फा के आधार पर 4x4 ग्रिड पर जलाया जाना चाहिए या नहीं। ऐसा करने के लिए सबसे आसान है बस ऐसा करना है।

पहले इसी alphas कि पिक्सेल पास के लिए आवश्यक हैं के साथ एक 4x4 बनावट को प्रारंभ

1.0 0.5 1.0 0.1 
1.0 1.0 0.9 1.0 
1.0 0.3 1.0 0.7 
1.0 1.0 1.0 1.0 

सेटअप दोहराने के साथ इस बनावट आधुनिक पूरी तरह से बचने के लिए (मैं कभी नहीं यहाँ दिखाने के लिए अल्फा के रूप में 1.0 उठाया) , और रैखिक फ़िल्टरिंग से बचने के लिए एक नजदीक फ़िल्टर।

फिर, उस बनावट का नमूनाकरण यह तय करने के लिए करें कि पिक्सेल को प्रकाश देना है या नहीं।

vec4 dither = texture2D(_my4x4, gl_FragCoord/4.); // 4 is the size of the texture 
if (r > dither) { gl_FragColor = color; } 

यह है कि आर 1. कभी नहीं है मान लिया गया है कि, उदाहरण के लिए आस-पास काम करने के लिए सरल तरीके हैं 1.0 के अलावा 4x4 बनावट में मानों को विभाजित करें, और फिर परीक्षण के पहले 2 से गुणा करें, लेकिन प्राप्त करने के बाद।

कुछ संभावित अनुकूलन:

  • आप तुलना (छाया बनावट) के साथ एक बनावट के प्रयोग से पूरी तरह अगर परीक्षण से बच सकते हैं।
  • आप textureFetch निर्देश
+0

धन्यवाद! मेरे अंतिम शेडर्स इस तरह दिखते हैं: – miketucker

-1

सबसे पहले, अपने टुकड़ा रंग के परिणामों की परवाह किए बिना एक ही हो सकता है अगर बयान रंग पर सेट है के बाद से इसकी शुरुआत हुई।

दूसरा, केवल तभी उपयोग करते हुए यदि कोई और विवरण नहीं है तो आपका कोड प्रत्येक गणना के माध्यम से चलाता है चाहे कोई फर्क नहीं पड़ता।

एक बहुत बेहतर यह करने के लिए जिस तरह से करने के लिए होगा:

if (r > 0.9) { 
    if ((mod(gl_FragCoord.x + 1.0, 4.001) + mod(gl_FragCoord.y + 1.0, 4.0)) > 6.00) { 
     gl_FragColor = color; 
    } 
} 
else if (r > 0.7) { 
    if ((mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0)) > 6.00) { 
     gl_FragColor = color; 
    } 
} 
else if (r > 0.5) { 
    if ((mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y, 4.0)) > 6.00) { 
     gl_FragColor = color; 
    } 
} 
else if (r > 0.3) { 
    if ((mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0)) > 6.00) { 
     gl_FragColor = color; 
    } 
} 
else if (r > 0.1) { 
    if ((mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0)) > 6.00) { 
     gl_FragColor = color; 
    } 
} 
else{ 
    gl_FragColor = color; 
} 

बेशक यह मदद नहीं करेगा आप उत्पादन बदलने के बाद से रंग बदल जाता है कभी नहीं है (जैसा कि मैंने पहले उल्लेख)। लेकिन यह चीजों को थोड़ा तेज चलाना चाहिए।

एक अन्य बात ध्यान में रखना है कि कौन से मामलों को अक्सर निष्पादित किया जाता है। मैंने माना कि बड़े आर के मामले अधिक आम हैं, इसलिए अगर बयानों का आदेश। यदि छोटे आर अधिक आम हैं, तो ऑर्डर को उलटकर और < 0.1, आर < 0.3, आर < 0.5, आर < 0.7, आर < 0.9 अधिक समझ में आएगा।

यहां पूरा बिंदु कोड जितना संभव हो सके बाहर निकलने के लिए है (यानी यदि कोई वापसी सही है)। एक बार यदि कोई रिटर्न सही हो जाता है, तो शेष को अनदेखा कर दिया जाता है, जिससे आप बाकी सभी मॉड ऑपरेशंस की गणना करने से बचाते हैं।

+3

"सबसे पहले, रंगों को शुरुआत में सेट होने के बाद, यदि आपके बयान के ब्योरे के बावजूद आपका टुकड़ा रंग समान होगा।" यह सच नहीं है। आप कई बार शेडर चरण आउटपुट सेट कर सकते हैं; केवल अंतिम लिया जाता है। आप उन्हें जगह में संशोधन भी कर सकते हैं। –

+0

क्षमा करें अगर मैं स्पष्ट नहीं था। मेरा मतलब यह था कि चूंकि रंग को लूप के बाहर असाइन किया गया है, इसलिए प्रत्येक व्यक्ति का नतीजा यदि लूप एक जैसा सत्य होगा (आर> 0.9 आर> 0.1 के समान टुकड़ा रंग देता है)। (जब तक कि शेडर्स कैसे काम करते हैं, मेरी समझ के साथ कुछ पूरी तरह से गलत नहीं है)। – NickLH

+0

लेकिन वे केवल उस रंग को सेट करते हैं यदि उनके पास अतिरिक्त 'mod' स्थिति है। अन्यथा, वे सिर्फ 0 के डिफ़ॉल्ट रंग का उपयोग करते हैं। यह सिर्फ 'आर> एक्स' नहीं है। –

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