2012-10-05 16 views
5

नीचे के अंदर बिंदु, एक GLSL टुकड़ा शेडर कि एक Texel आउटपुट यदि दिए गए बनावट coord एक बॉक्स के अंदर है अन्यथा एक रंग उत्पादन होता है। यह सिर्फ मूर्खतापूर्ण लगता है और वहां ब्रांचिंग के बिना ऐसा करने का एक तरीका होना चाहिए?GLSL बॉक्स परीक्षण

uniform sampler2D texUnit; 

varying vec4 color; 
varying vec2 texCoord; 

void main() { 
    vec4 texel = texture2D(texUnit, texCoord); 
    if (any(lessThan(texCoord, vec2(0.0, 0.0))) || 
     any(greaterThan(texCoord, vec2(1.0, 1.0)))) 
    gl_FragColor = color; 
    else 
    gl_FragColor = texel; 
} 

नीचे शाखा के बिना एक संस्करण है, लेकिन यह अभी भी बेकार लगता है। "बनावट समन्वय क्लैंपिंग" के लिए सबसे अच्छा अभ्यास क्या है?

uniform sampler2D texUnit; 

varying vec4 color; 
varying vec4 labelColor; 
varying vec2 texCoord; 

void main() { 
    vec4 texel = texture2D(texUnit, texCoord); 
    bool outside = any(lessThan(texCoord, vec2(0.0, 0.0))) || 
       any(greaterThan(texCoord, vec2(1.0, 1.0))); 
    gl_FragColor = mix(texel*labelColor, color, 
        vec4(outside,outside,outside,outside)); 
} 

Here is the rendering result

मैं लेबल के साथ क्षेत्र के लिए texels क्लैम्पिंग रहा है - बनावट रों & टी निर्देशांक इस मामले में 0 और 1 के बीच किया जाएगा। अन्यथा, मैं भूरा रंग का उपयोग करता हूं जहां लेबल नहीं है।

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

+0

के माध्यम से मैं हमेशा इस तरह सामान के लिए बेंचमार्किंग परिणाम देखने के लिए इच्छुक हूँ। मुझे लगता है कि इस मामले में आपको एक परिदृश्य बनाना पड़ सकता है जहां कई बिंदु-इन-बॉक्स परीक्षण एक बाधा बन जाते हैं। – jozxyqk

उत्तर

10

उपयोग step समारोह:

// return 1 if v inside the box, return 0 otherwise 
float insideBox(vec2 v, vec2 bottomLeft, vec2 topRight) { 
    vec2 s = step(bottomLeft, v) - step(topRight, v); 
    return s.x * s.y; 
} 

void main() { 
    vec4 texel = texture2D(texUnit, texCoord); 

    float t = insideBox(v_position, vec2(0, 0), vec2(1, 1)); 
    gl_FragColor = t * texel + (1 - t) * color; 
} 
+0

धन्यवाद आपके सुधार के लिए एंडी शियू – damphat

+0

"अंदरबॉक्स()" एक बहुत चालाक समारोह है! – Tara

+0

क्या कोई 3 डी संस्करण है? – jjxtra

3

damphat के जवाब के आधार पर, मैं अंदर और बाहर के बीच सुचारु के लिए एक समारोह को क्रियान्वित किया है आयत:

float inside_rectangle_smooth(vec2 p, vec2 bottom_left, vec2 top_right, float transition_area) 
{ 
    vec2 s = smoothstep(bottom_left, bottom_left + vec2(transition_area), p) - 
      smoothstep(top_right - vec2(transition_area), top_right, p); 
    return(s.x * s.y); 
} 

अंदर के बीच और आयत के बाहर संक्रमण क्षेत्र के आकार धुन पर "transition_area" पैरामीटर का उपयोग करें। संक्रमण आयताकार के अंदर फीका हुआ है, इसके बाहर नहीं। यह भी सुनिश्चित करें कि "transition_area" पैरामीटर "bottom_left" और "top_right" (प्रत्येक आयाम में) के बीच की दूरी से छोटा है।
मैं अपने इंजन में छाया छाया को फीका करने के लिए सफलतापूर्वक इस फ़ंक्शन का उपयोग कर रहा हूं (छाया मानचित्र निर्देशांक का उपयोग करके)।

प्रदर्शन:
inside_rectangle_smooth(v_texture_coordinate, vec2(0.0), vec2(1.0), 0.1)
ऊपर छवि बुला द्वारा निर्मित है:
inside_rectangle_smooth(v_texture_coordinate, vec2(0.0), vec2(1.0), 0.1)

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