2011-01-02 9 views
16

मेरे पास जीएलएसएल में रेडियल ब्लर शेडर है, जो एक बनावट लेता है, इसमें एक रेडियल ब्लर लागू होता है और परिणाम को स्क्रीन पर प्रस्तुत करता है। यह अब तक बहुत अच्छी तरह से काम करता है।मैं पूरे दृश्य में रेडियल ब्लर लगाने के लिए जीएलएसएल शेडर का उपयोग कैसे करूं?

समस्या है, कि इस दृश्य में पहले बनावट के लिए रेडियल कलंक लागू होता है। लेकिन मैं वास्तव में क्या करना चाहता हूं, इस धुंध को पूरे दृश्य पर लागू करना है।

इस कार्यक्षमता को प्राप्त करने का सबसे अच्छा तरीका क्या है? क्या मैं इसे केवल शेडर्स के साथ कर सकता हूं, या क्या मुझे दृश्य को पहले एक बनावट (ओपनजीएल में) प्रस्तुत करना है और फिर आगे की प्रक्रिया के लिए इस बनावट को शेडर में पास करना है?

// Vertex shader 

varying vec2 uv; 

void main(void) 
{ 
    gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0); 
    gl_Position = sign(gl_Position); 
    uv = (vec2(gl_Position.x, - gl_Position.y) + vec2(1.0))/vec2(2.0); 
} 


// Fragment shader 

uniform sampler2D tex; 
varying vec2 uv; 
const float sampleDist = 1.0; 
const float sampleStrength = 2.2; 

void main(void) 
{ 
    float samples[10]; 
    samples[0] = -0.08; 
    samples[1] = -0.05; 
    samples[2] = -0.03; 
    samples[3] = -0.02; 
    samples[4] = -0.01; 
    samples[5] = 0.01; 
    samples[6] = 0.02; 
    samples[7] = 0.03; 
    samples[8] = 0.05; 
    samples[9] = 0.08; 

    vec2 dir = 0.5 - uv; 
    float dist = sqrt(dir.x*dir.x + dir.y*dir.y); 
    dir = dir/dist; 

    vec4 color = texture2D(tex,uv); 
    vec4 sum = color; 

    for (int i = 0; i < 10; i++) 
     sum += texture2D(tex, uv + dir * samples[i] * sampleDist); 

    sum *= 1.0/11.0; 
    float t = dist * sampleStrength; 
    t = clamp(t ,0.0,1.0); 

    gl_FragColor = mix(color, sum, t); 
} 

alt text

उत्तर

16

यह मूलतः कहा जाता है "पोस्ट-प्रोसेसिंग" क्योंकि आप एक प्रभाव (यहाँ: रेडियल कलंक) लागू कर रहे हैं पूरे दृश्य करने के लिए के बाद यह है प्रदान की गई।

तो हाँ, तुम सही हो:

  • , एक स्क्रीन आकार NPOT बनावट (GL_TEXTURE_RECTANGLE) बनाने
  • एक FBO बनाने के लिए, करने के लिए बनावट देते हैं: पोस्ट-प्रोसेसिंग के लिए अच्छा तरीका है यह
  • इस एफबीओ को सक्रिय करने के लिए सेट करें, दृश्य
  • एफबीओ को अक्षम करें, एफबीओ के बनावट के साथ एक पूर्ण-स्क्रीन क्वाड बनाएं।

का सवाल है "क्यों", वजह साफ है: दृश्य (टुकड़ा शेडर कई पिक्सल के लिए स्वतंत्र रूप से क्रियान्वित किया जाता है) समानांतर में प्रदान की गई है। पिक्सेल (एक्स, वाई) के लिए रेडियल ब्लर करने के लिए, आपको सबसे पहले आसपास के पिक्सल के प्री-ब्लर पिक्सेल मानों को जानने की आवश्यकता है। और वे पहले पास में उपलब्ध नहीं हैं, क्योंकि इन्हें केवल इसी दौरान प्रस्तुत किया जा रहा है।

इसलिए, आप टुकड़ा (एक्स, वाई) के लिए रेडियल कलंक के बाद ही पूरे दृश्य प्रदान की गई है और टुकड़ा शेडर लागू करना चाहिए दृश्य से किसी भी पिक्सेल पढ़ने में सक्षम है। यही कारण है कि आपको इसके लिए 2 प्रतिपादन चरणों की आवश्यकता है।

+0

आपको बहुत बहुत धन्यवाद, जो वास्तव में बहुत मदद की! –

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