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();