मेरे पास एक वस्तु है जिसे मैं धुंधला करने की कोशिश कर रहा हूं।

  1. इसे एक पारदर्शी (1, 1, 1, 0) FBO के साथ स्पष्ट करें।
  2. इसे वर्टिकल ब्लर शेडर के साथ दूसरे पारदर्शी FBO में रेंडर करें।
  3. इसे एक क्षैतिज ब्लर शेडर के साथ स्क्रीन पर प्रस्तुत करें।

यहाँ एक उदाहरण है जो धुंधला नहीं दिखता है, और फिर इस तकनीक से धुंधला हो जाता है:

enter image description here

जाहिर है मुद्दा यह है कि धुंधली वस्तु के चारों ओर सफेद चमक है।

मुझे लगता है कि मैं मूल अवधारणा को समझता हूं कि ऐसा क्यों हो रहा है। जबकि एफबीओ में ऑब्जेक्ट के चारों ओर पिक्सेल पारदर्शी होते हैं, फिर भी वे रंग (1,1,1) रखते हैं और नतीजतन, वह रंग धुंध में मिश्रित होता है।

मुझे नहीं पता कि इसका समाधान करने के लिए मैं क्या करूँ?

यहां मेरा क्षैतिज धुंधला शेडर है, लंबवत समान है:

hBlur.vert

uniform mat4 u_projTrans;
uniform float u_blurPixels;
uniform float u_texelWidth;

attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;

varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];

void main()
{
    v_texCoord = a_texCoord0;
    gl_Position = u_projTrans * a_position;

    float blurDistance6 = u_blurPixels * u_texelWidth;
    float blurDistance5 = blurDistance6 * 0.84;
    float blurDistance4 = blurDistance6 * 0.70;
    float blurDistance3 = blurDistance6 * 0.56;
    float blurDistance2 = blurDistance6 * 0.42;
    float blurDistance1 = blurDistance6 * 0.28;
    float blurDistance0 = blurDistance6 * 0.14;

    v_blurTexCoords[ 0] = v_texCoord + vec2(-blurDistance6, 0.0);
    v_blurTexCoords[ 1] = v_texCoord + vec2(-blurDistance5, 0.0);
    v_blurTexCoords[ 2] = v_texCoord + vec2(-blurDistance4, 0.0);
    v_blurTexCoords[ 3] = v_texCoord + vec2(-blurDistance3, 0.0);
    v_blurTexCoords[ 4] = v_texCoord + vec2(-blurDistance2, 0.0);
    v_blurTexCoords[ 5] = v_texCoord + vec2(-blurDistance1, 0.0);
    v_blurTexCoords[ 6] = v_texCoord + vec2(-blurDistance0, 0.0);
    v_blurTexCoords[ 7] = v_texCoord + vec2( blurDistance0, 0.0);
    v_blurTexCoords[ 8] = v_texCoord + vec2( blurDistance1, 0.0);
    v_blurTexCoords[ 9] = v_texCoord + vec2( blurDistance2, 0.0);
    v_blurTexCoords[10] = v_texCoord + vec2( blurDistance3, 0.0);
    v_blurTexCoords[11] = v_texCoord + vec2( blurDistance4, 0.0);
    v_blurTexCoords[12] = v_texCoord + vec2( blurDistance5, 0.0);
    v_blurTexCoords[13] = v_texCoord + vec2( blurDistance6, 0.0);
}

धुंधला.फ्रैग

uniform sampler2D u_texture;

varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];

void main()
{
    gl_FragColor = vec4(0.0);
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 0]) * 0.0044299121055113265;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 1]) * 0.00895781211794;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 2]) * 0.0215963866053;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 3]) * 0.0443683338718;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 4]) * 0.0776744219933;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 5]) * 0.115876621105;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 6]) * 0.147308056121;
    gl_FragColor += texture2D(u_texture, v_texCoord         ) * 0.159576912161;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 7]) * 0.147308056121;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 8]) * 0.115876621105;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 9]) * 0.0776744219933;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[10]) * 0.0443683338718;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[11]) * 0.0215963866053;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[12]) * 0.00895781211794;
    gl_FragColor += texture2D(u_texture, v_blurTexCoords[13]) * 0.0044299121055113265;
}

मैं झूठ बोलूंगा अगर मैंने कहा कि मैं पूरी तरह से निश्चित था कि यह कोड क्या कर रहा है। लेकिन संक्षेप में यह केवल u_blurPixels के दायरे से पिक्सेल का नमूना ले रहा है और पूर्व-निर्धारित गाऊसी भार के साथ gl_FragColor के परिणामी रंग को जोड़ रहा है।

पारदर्शी पृष्ठभूमि के कारण सफेद चमक को रोकने के लिए मैं इसे कैसे संशोधित करूं?

1
FTLRalph 13 सितंबर 2017, 00:35

1 उत्तर

समस्या यह है कि ओपनजीएल ईएस पोस्ट-गुणा अल्फा (यह हार्डवेयर में सस्ता है) का उपयोग करता है, जबकि इसे "ठीक से" करने के लिए प्रीमल्टीप्लाइड अल्फा की आवश्यकता होती है।

आप अपने द्वारा धुंधला किए गए प्रत्येक नमूने के लिए शेडर में पूर्व-गुणा गणित कर सकते हैं:

premult.rgb = source.rgb * source.a;

... लेकिन फिर आप मिश्रण कर रहे प्रत्येक बनावट नमूने के लिए रन-टाइम लागत लेते हैं। बनावट निर्माण/संपीड़न के दौरान अपनी इनपुट कला संपत्तियों को ऑफ़लाइन पूर्व-गुणा करना आम तौर पर बेहतर होता है।

यदि आपको प्रकाश गणना आदि के लिए पोस्ट-गुणा डेटा की आवश्यकता है, तो आप ऑब्जेक्ट रंग को पड़ोसी "पारदर्शी" पिक्सेल में निकालकर त्रुटि को कम दिखाई दे सकते हैं। उदा.:

extruded color

ध्यान दें कि यदि आप शेडर्स पहले से कई गुना अल्फा फ्रैग्मेटन रंग उत्सर्जित कर रहे हैं तो आपको अपने ओपनजीएल मिश्रण समीकरण को ठीक करना होगा (srcAlpha के लिए GL_ONE का उपयोग करें, अल्फा मान नहीं)।

1
solidpixel 13 सितंबर 2017, 16:51