package com.marshalchen.common.uimodule.imageprocessing.filter.blend;
import com.marshalchen.common.uimodule.imageprocessing.filter.MultiInputFilter;
import android.opengl.GLES20;
/**
* Selectively replaces a color in the first image with the second image
* colour: The colour to match with
* thresholdSensitivity: How close a color match needs to exist to the target color to be replaced
* smoothing: How smoothly to blend for the color match
* @author Chris Batt
*/
public class ChromaKeyBlendFilter extends MultiInputFilter {
private static final String UNIFORM_COLOUR = "u_Colour";
private static final String UNIFORM_THRESHOLD = "u_Threshold";
private static final String UNIFORM_SMOOTHING = "u_Smoothing";
private int colourHandle;
private int thresholdHandle;
private int smoothingHandle;
private float[] colour;
private float threshold;
private float smoothing;
public ChromaKeyBlendFilter(float[] colour, float threshold, float smoothing) {
super(2);
this.colour = colour;
this.threshold = threshold;
this.smoothing = smoothing;
}
@Override
protected String getFragmentShader() {
return
"precision mediump float;\n"
+"uniform sampler2D "+UNIFORM_TEXTURE0+";\n"
+"uniform sampler2D "+UNIFORM_TEXTUREBASE+1+";\n"
+"varying vec2 "+VARYING_TEXCOORD+";\n"
+"uniform vec3 "+UNIFORM_COLOUR+";\n"
+"uniform float "+UNIFORM_THRESHOLD+";\n"
+"uniform float "+UNIFORM_SMOOTHING+";\n"
+"void main(){\n"
+" vec4 color = texture2D("+UNIFORM_TEXTURE0+","+VARYING_TEXCOORD+");\n"
+" float maskY = 0.2989 * "+UNIFORM_COLOUR+".r + 0.5866 * "+UNIFORM_COLOUR+".g + 0.1145 * "+UNIFORM_COLOUR+".b;"
+" float maskCr = 0.7132 * ("+UNIFORM_COLOUR+".r - maskY);"
+" float maskCb = 0.5647 * ("+UNIFORM_COLOUR+".b - maskY);"
+" float Y = 0.2989 * color.r + 0.5866 * color.g + 0.1145 * color.b;"
+" float Cr = 0.7132 * (color.r - Y);"
+" float Cb = 0.5647 * (color.b - Y);"
+" float blendValue = smoothstep("+UNIFORM_THRESHOLD+", "+UNIFORM_THRESHOLD+" + "+UNIFORM_SMOOTHING+", distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));"
+" gl_FragColor = mix(color, texture2D("+UNIFORM_TEXTUREBASE+1+","+VARYING_TEXCOORD+"), blendValue);\n"
+"}\n";
}
@Override
protected void initShaderHandles() {
super.initShaderHandles();
colourHandle = GLES20.glGetUniformLocation(programHandle, UNIFORM_COLOUR);
thresholdHandle = GLES20.glGetUniformLocation(programHandle, UNIFORM_THRESHOLD);
smoothingHandle = GLES20.glGetUniformLocation(programHandle, UNIFORM_SMOOTHING);
}
@Override
protected void passShaderValues() {
super.passShaderValues();
GLES20.glUniform3f(colourHandle, colour[0], colour[1], colour[2]);
GLES20.glUniform1f(thresholdHandle, threshold);
GLES20.glUniform1f(smoothingHandle, smoothing);
}
}