2011-01-23 20 views
5

Muszę zaimplementować kluczowanie kolorem (usunięcie jednolitego tła koloru) w aplikacji openFrameworks.Kluczowanie kolorem z openframeworks/opengl

Będę odtwarzać wiele (10 lub więcej) filmów jednocześnie (w tej samej ramce) i rysować je na ekranie wraz z alternatywnymi tłami. Mogę uzyskać efekt podobny do klucza chrominancji, wykonując iteracje między pikselami każdej klatki i ustawiając wartości alfa dla każdego z nich na podstawie zielonego progu, ale przy tak wielu filmach naraz, to uderzenie w piksel staje się wygórowane.

Czy istnieje łatwy tryb mieszania OpenGL lub operacja maskowania, która może zapobiec rysowaniu wszystkich pikseli o określonej wartości koloru? Czy istnieje inna biblioteka C++ zgodna z OpenFrameworks lub openFrameworks, która może to zrobić wydajnie?

Czy istnieje dobry (efektywny przestrzennie) sposób przechowywania kanału alfa w plikach wideo zgodnych z Quicktime? Będziemy przechowywać terabajty wideo (tygodnie ciągłego nagrywania), więc ważne jest, abyśmy używali wydajnych formatów.

Jedna uwaga: kolor kluczowania w plikach źródłowych będzie "idealny" - zostanie dodany cyfrowo. Więc jeśli istnieje jakiś rodzaj progu lub sztuczka bitowo-logiczna, aby to zrobić, to też może działać.


EDIT: Oto, co zadziałało, po sugestii VJo za pomocą pixel shader. Użyliśmy glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) oraz następujące Pixel Shader (za magenta jako zastąpionego kolor):

"Dane/shadery/chromakey.frag":

#extension GL_ARB_texture_rectangle : enable 

uniform sampler2DRect src_tex_unit0; 
vec4 color; 

void main(void) 
{ 
     vec2 st = gl_TexCoord[0].st; 
     vec4 sample = texture2DRect(src_tex_unit0, st); 
     gl_FragColor = sample; 
     if((sample.r > 0.5) && (sample.g < 0.5) && (sample.b > 0.5)) { 
       gl_FragColor.a = 0.0; 
     } 
} 

"Dane/shaderów/chromakey.vert":

void main() 
{ 
    gl_Position = ftransform(); 
    gl_TexCoord[0] = gl_MultiTexCoord[0]; 
} 

C++ klasy proxy dla shaderów - shaderChromakey.h:

#include "ofMain.h" 
#include "ofxShader.h" 
#include "ofxFBOTexture.h" 

class shaderChromakey{ 

    public: 
     void setup(int fboW, int fboH); 

     void beginRender(); 
     void endRender(); 

     void draw(int x, int y, int width, int height); 

     ofxShader shader; 

     ofxFBOTexture fbo; 

}; 

s haderChromakey.cpp:

#include "shaderChromakey.h" 

//-------------------------------------------------------------- 
void shaderChromakey::setup(int fboW, int fboH){ 

    ofBackground(255,255,255); 
    ofSetVerticalSync(true); 

    fbo.allocate(fboW, fboH, true); 

    shader.loadShader("shaders/chromakey"); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::beginRender(){ 
    fbo.swapIn(); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::endRender(){ 
    fbo.swapOut(); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::draw(int x, int y, int width, int height){ 

    shader.setShaderActive(true); 
    fbo.draw(x, y, width, height); 
    shader.setShaderActive(false); 
} 

Aby instancję shader, w projekcie:

shaderChromakey chromakey; 
chromakey.setup(HORIZONTAL, VERTICAL) 

W pętli remis, aby umożliwić shadera:

chromakey.beginRender(); 
    // draw chomakeyed frame here 
chromakey.endRender(); 

Odpowiedz

2

Można użyć glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA) a następnie gdy włączasz mieszanie, możesz użyć pixel shadera, aby zrobić to, co chcesz, jeśli piksel ma określony kolor (ustaw alfa na 0).