2012-07-17 11 views
5

में एचटीएमएल पृष्ठभूमि के साथ मिश्रण मैं वेबजीएल कैनवास में फ्लैट रंग और बनावट खींच रहा हूं। मेरे रंगों और बनावट में अल्फा मान अलग-अलग होते हैं और मैं उन्हें सही ढंग से मिश्रित करना चाहता हूं। मैं पारदर्शी पृष्ठभूमि रखना चाहता हूं (उन्हें HTML सामग्री के साथ मिश्रित किया जाना चाहिए, जो कैनवास के अंतर्गत है)।वेबजीएल

WebGL में, मैं

gl.clearColor(0, 0, 0, 0); 
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 
gl.enable(gl.BLEND); 

का उपयोग यह सही ढंग से काम करता है जब एचटीएमएल पृष्ठभूमि काला है। लेकिन जब मैं पृष्ठभूमि के रूप में एक जेपीजी पैटर्न सेट करता हूं, तो मैं काला त्रिकोण (अल्फा = 1) और सफेद त्रिकोण (अल्फा = 0.5) खींचता हूं, मैं पृष्ठभूमि पैटर्न को उस स्थान पर देख सकता हूं जहां त्रिभुज एक-दूसरे को छेड़छाड़ करते हैं। क्या यह सही व्यवहार है?

उत्तर

11

मेरा पिछला उत्तर वास्तव में गलत था। आपके द्वारा वर्णित किए गए अनुमानित परिणाम का परिणाम है।

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) मतलब यह है कि जिसके परिणामस्वरूप अल्फा

A_final = A_s * A_s + (1 - A_s) * A_d 

अपने उदाहरण में है, काले त्रिकोण के बाद तैयार की है (अल्फा = 1 के साथ), फ्रेमबफर में तैयार पिक्सेल

1 * 1 + (1 - 1) * 0 == 1 + 0 == 1 
की एक अल्फा होगा

तो यह पूरी तरह से अपारदर्शी होगा। इसके बाद, सफेद त्रिकोण (के साथ अल्फा = .5) के बाद तैयार की है, दो त्रिकोण के चौराहे में एक पिक्सेल

.5 * .5 + (1 - .5) * 1 == .25 + .5 == .75 

की एक अल्फा इसका मतलब है कि अंतिम रंग आंशिक रूप से पारदर्शी रूप में माना जाएगा होगा, और , जब यह पृष्ठ के साथ मिश्रित होता है, पृष्ठ पृष्ठभूमि के माध्यम से दिखाया जाएगा।

नियमित ओपनजीएल में यह कुछ असामान्य समस्या है, क्योंकि सामग्री आमतौर पर खाली पृष्ठभूमि के खिलाफ मिश्रित होती है। यह तब आता है जब आप एक एफबीओ को आकर्षित करते हैं और परिणामों को अपने संदर्भ में अन्य सामग्री के साथ जोड़ना पड़ता है। इससे निपटने के कुछ तरीके हैं।

एक तरह से gl.ONE_MINUS_SRC_ALPHA ताकि आप राशि है जो आप आमतौर पर अल्फा सम्मिश्रण के साथ चाहते हैं

A_final = A_s + (1 - A_s) * A_d 

मिलता है, gl.ONE के साथ अपने अल्फा मिश्रण है। हालांकि, आप चाहते हैं कि आपके रंग अभी भी gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA के साथ मिश्रित हों। आप gl.blendFunc के बजाय gl.blendFuncSeparate का उपयोग अपने रंग मिश्रण और अल्फा मिश्रण कार्यों को अलग-अलग सेट करने के लिए कर सकते हैं। इस मामले में, आप कहेंगे

gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 

एक अन्य विकल्प premultiplied अल्फा के साथ रंग का लाभ लेने के लिए है (जो WebGL actually already assumes you are using, उदाहरण के लिए, जब एक बनावट से एक रंग नमूना)। आप दूसरे त्रिकोण अल्फा के साथ आकर्षित यदि पहले से ही रंग (ताकि एक आधा पारदर्शी सफेद त्रिकोण vec4(.5, .5, .5, .5) को gl_FragColor सेट होता है), तो आप मिश्रण मोड

gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) 

उपयोग कर सकते हैं और यह आप चाहते हैं के रूप में कार्य के माध्यम से गुणा रंग और अल्फा दोनों के लिए।

दूसरा विकल्प क्या आप WebGL उदाहरण में आमतौर पर दिखाई देगा, क्योंकि (के रूप में उल्लेख), WebGL पहले से ही मान लिया गया है अपने रंग premultiplied कर रहे हैं (ताकि vec4(1., 1., 1., .5) सरगम ​​से बाहर है, प्रतिपादन उत्पादन अपरिभाषित है, और ड्राइवर/GPU किसी भी पागल रंग को आउटपुट कर सकते हैं)। नियमित ओपनजीएल उदाहरणों में gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) देखने के लिए यह कहीं अधिक आम है, जो कुछ भ्रम की ओर जाता है।

+0

बहुत बहुत धन्यवाद, आप कमाल हैं! :) मैंने gl.blendFuncSeparate() का उपयोग करने का फैसला किया। मैंने प्री-गुणा अल्फा का उपयोग करने की कोशिश की, लेकिन यह अजीब लग रहा है, क्योंकि मेरे बनावट प्रील्टिप्लाइड नहीं हैं। मैं gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bd.image) का उपयोग करता हूं; ? मैं इसे प्रीमिलीप्लाइड में कैसे बदल सकता हूं? –

+0

डिफ़ॉल्ट रूप से, लोड होने पर बनावट आपके लिए पूर्ववर्ती नहीं होती है। ब्राउज़र को स्वचालित रूप से अल्फा द्वारा रंगों को गुणा करने के लिए, क्योंकि यह बनावट आयात करता है, आपको texImage2D को कॉल करने से पहले बनावट पैरामीटर सेट करना होगा। तो आप 'gl.pixelStorei (gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true) को कॉल करेंगे; 'texImage2D कॉल से पहले आप ऊपर सूचीबद्ध करें। वेबजीएल स्पेक में पिक्सेल स्टोरेज पैरामीटर नोट देखें: http://www.khronos.org/registry/webgl/specs/latest/#PIXEL_STORAGE_PARAMETERS –

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