2009-05-15 9 views
5

जब बनावट बहुभुज के एक दृश्य प्रतिपादन, मैं मूल रंग और एक "ग्रेस्केल" मोड में प्रतिपादन के बीच स्विच करने में सक्षम होना चाहते हैं। मैं मिश्रण और रंग मैट्रिक्स संचालन का उपयोग करके इसे प्राप्त करने की कोशिश कर रहा हूं; इसमें से कोई भी काम नहीं करता है (मिश्रण के साथ मुझे एक glblendFunc() नहीं मिला जो कुछ जो मैं चाहता था उससे दूरस्थ रूप से कुछ हासिल कर लिया, और रंग मैट्रिक्स ऑपरेशंस ...are discussed here)।ओपनजीएल में ग्रेस्केल प्रतिपादन को कैसे कार्यान्वित करें?

एक समाधान जो दिमाग में आता है (लेकिन यह भी महंगा है) प्रत्येक फ्रेम को स्क्रीन पर कब्जा करना और परिणामी बनावट को ग्रेस्केल में परिवर्तित करना और इसके बजाय प्रदर्शित करना है ... (जहां मैंने ग्रेस्केल कहा था, वास्तव में मुझे कुछ भी मतलब था कम संतृप्ति, लेकिन मैं संभवतः अधिकांश संभावित समाधानों के लिए अनुमान लगा रहा हूं, यह ग्रेस्केल से जितना अधिक अलग नहीं होगा)।

मैं दूसरे क्या विकल्प हैं?

उत्तर

9

डिफ़ॉल्ट ओपन फ्रेमबफर आरजीबी रंग अंतरिक्ष, जो एक स्पष्ट संतृप्ति की दुकान नहीं है का उपयोग करता है। संतृप्ति निकालने, इसे संशोधित करने और इसे फिर से बदलने के लिए आपको एक दृष्टिकोण की आवश्यकता है।

मेरे पिछले सुझाव जो केवल आरजीबी वेक्टर लंबाई इस्तेमाल किया luminance में 0 प्रतिनिधित्व करने के लिए गलत थी, तो यह ध्यान में स्केलिंग नहीं लिया है, मैं माफी माँगता हूँ।

नए शॉर्ट स्निपेट के लिए क्रेडिट नियमित उपयोगकर्ता "RTFM_FTW" पर ## opengl और ## opengl3 से फ्रीनोड/आईआरसी पर जाता है, और यह आपको महंगी आरजीबी-> एचएसवी-> आरजीबी की गणना किए बिना सीधे संतृप्ति को संशोधित करने देता है रूपांतरण, जो वास्तव में आप चाहते हैं। हालांकि एचएसवी कोड आपके प्रश्न के संबंध में कम है, लेकिन मैंने इसे रहने दिया।

void main(void) 
{ 
    vec3 R0 = texture2DRect(S, gl_TexCoord[0].st).rgb; 
    gl_FragColor = vec4(mix(vec3(dot(R0, vec3(0.2125, 0.7154, 0.0721))), 
     R0, T), gl_Color.a); 
} 

तुम सिर्फ संतृप्ति से अधिक नियंत्रण चाहते हैं, तो आप एचएसएल या एचएसवी रंग-अंतरिक्ष में बदलने की जरूरत है। जैसा कि एक जीएलएसएल टुकड़ा शेडर का उपयोग करके नीचे दिखाया गया है।

जीएलएसएल v1.30 कार्यक्षमता का उपयोग करने के तरीके को जानने के लिए http://www.opengl.org/registry पर उपलब्ध ओपनजीएल 3.0 और जीएलएसएल 1.30 विनिर्देश पढ़ें।

#version 130 
#define RED 0 
#define GREEN 1 
#define BLUE 2 

in vec4 vertexIn; 
in vec4 colorIn; 
in vec2 tcoordIn; 
out vec4 pixel; 
Sampler2D tex; 
vec4 texel; 
const float epsilon = 1e-6; 

vec3 RGBtoHSV(vec3 color) 
{ 
    /* hue, saturation and value are all in the range [0,1> here, as opposed to their 
     normal ranges of: hue: [0,360>, sat: [0, 100] and value: [0, 256> */ 
    int sortindex[3] = {RED,GREEN,BLUE}; 
    float rgbArr[3] = float[3](color.r, color.g, color.b); 

    float hue, saturation, value, diff; 
    float minCol, maxCol; 
    int minIndex, maxIndex; 

    if(color.g < color.r) 
     swap(sortindex[0], sortindex[1]); 
    if(color.b < color.g) 
     swap(sortindex[1], sortindex[2]); 
    if(color.r < color.b) 
     swap(sortindex[2], sortindex[0]); 

    minIndex = sortindex[0]; 
    maxIndex = sortindex[2]; 
    minCol = rgbArr[minIndex]; 
    maxCol = rgbArr[maxIndex]; 

    diff = maxCol - minCol; 

    /* Hue */ 
    if(diff < epsilon){ 
     hue = 0.0; 
    } 
    else if(maxIndex == RED){ 
     hue = ((1.0/6.0) * ((color.g - color.b)/diff)) + 1.0; 
     hue = fract(hue); 
    } 
    else if(maxIndex == GREEN){ 
     hue = ((1.0/6.0) * ((color.b - color.r)/diff)) + (1.0/3.0); 
    } 
    else if(maxIndex == BLUE){ 
     hue = ((1.0/6.0) * ((color.r - color.g)/diff)) + (2.0/3.0);   
    } 

    /* Saturation */ 
    if(maxCol < epsilon) 
     saturation = 0; 
    else 
     saturation = (maxCol - minCol)/maxCol; 

    /* Value */ 
    value = maxCol; 

    return vec3(hue, saturation, value); 
} 
vec3 HSVtoRGB(vec3 color) 
{ 
    float f,p,q,t, hueRound; 
    int hueIndex; 
    float hue, saturation, value; 
    vec3 result; 

    /* just for clarity */ 
    hue = color.r; 
    saturation = color.g; 
    value = color.b; 

    hueRound = floor(hue * 6.0); 
    hueIndex = int(hueRound) % 6; 
    f = (hue * 6.0) - hueRound; 
    p = value * (1.0 - saturation); 
    q = value * (1.0 - f*saturation); 
    t = value * (1.0 - (1.0 - f)*saturation); 

    switch(hueIndex) 
    { 
     case 0: 
      result = vec3(value,t,p); 
     break; 
     case 1: 
      result = vec3(q,value,p); 
     break; 
     case 2: 
      result = vec3(p,value,t); 
     break; 
     case 3: 
      result = vec3(p,q,value); 
     break; 
     case 4: 
      result = vec3(t,p,value); 
     break; 
     default: 
      result = vec3(value,p,q); 
     break; 
    } 
    return result; 
} 
void main(void) 
{ 
    vec4 srcColor; 
    vec3 hsvColor; 
    vec3 rgbColor; 
    texel = Texture2D(tex, tcoordIn); 
    srcColor = texel*colorIn; 
    hsvColor = RGBtoHSV(srcColor.rgb); 
    /* You can do further changes here, if you want. */ 
    hsvColor.g = 0; /* Set saturation to zero */ 
    rgbColor = HSVtoRGB(hsvColor); 
    pixel = vec4(rgbColor.r, rgbColor.g, rgbColor.b, srcColor.a); 
} 
+0

"v" परिभाषित नहीं किया गया है। Hsv2rgb के लिए अन्य एल्गोरिदम को देखते हुए, ऐसा लगता है कि यह वास्तव में "मान" होना चाहिए, इसके अलावा, अंतिम केस स्टेटमेंट (केस 5) भी डिफ़ॉल्ट मामला होना चाहिए। –

2

आप एक आधुनिक पर्याप्त ओपन के खिलाफ काम कर रहे हैं, तो मैं कहूंगा कि pixel shaders एक बहुत ही उपयुक्त समाधान यहाँ है। या तो प्रत्येक बहुभुज की छायांकन में उन्हें प्रस्तुत करते हुए, या एक दूसरे पास में एक पूर्ण स्क्रीन-स्क्रीन क्वाड करके जो प्रत्येक पिक्सेल को पढ़ता है, ग्रेस्केल में परिवर्तित होता है, और इसे वापस लिखता है। जब तक आपका रिज़ॉल्यूशन, ग्राफिक्स हार्डवेयर और लक्ष्य फ़्रेमेट किसी भी तरह "चरम" न हो, तो इन दिनों अधिकांश मामलों में ऐसा करने योग्य होना चाहिए।

2

अधिकांश डेस्कटॉप के लिए रेंडर-टू-बनावट अब महंगा नहीं है, सभी कंपिज़, एयरो इत्यादि और हालिया खिताब में देखे गए क्षेत्र की उदासी या गहराई जैसे प्रभाव इस पर निर्भर करते हैं।

असल में आप स्क्रीन बनावट प्रति से ग्रेस्केल में कनवर्ट नहीं करते हैं, तो आप बनावट के साथ एक स्क्री-साइज्ड क्वाड और वैल्यूज़ को ग्रेस्केल में बदलने वाले एक टुकड़े टुकड़े को आकर्षित करना चाहते हैं।

एक अन्य विकल्प अपने त्रिकोण, एक बस के रूप में तय समारोह pieline होगा gl_FrontColor विशेषता को कॉपी, और एक अन्य है कि स्क्रीन बफर करने के लिए ग्रेस्केल मान लिखते हैं के लिए टुकड़ा shaders के दो सेट है।

एक तीसरा विकल्प रंग मोड अनुक्रमित किया जा सकता है, यदि आप एक ग्रेस्केल पैलेट UUP निर्धारित करते हैं, लेकिन यह है कि मोड पदावनत किया जा सकता है और खराब अब तक का समर्थन किया; प्लस अगर आप सही ढंग से याद करते हैं, तो आप मिश्रण की तरह बहुत सारी कार्यक्षमता खो देते हैं।

+0

yup, colorindex मोड के साथ कोई मिश्रण नहीं। आपका क्या मतलब है "सभी कंपिज़, एयरो, इत्यादि"? – zyndor

+0

उसका मतलब है कि डेस्कटॉप विंडो रेंडरर आजकल बनावट में प्रतिपादन का उपयोग करते हैं (वह संभवतः एक विंडो प्रबंधक प्रोग्रामर है)। – Triang3l

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