Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Chroma Key Filter for the Haxe version of Starling 2
// =================================================================================================
//
// Starling Framework
// Copyright Gamua GmbH. All Rights Reserved.
//
// This program is free software. You can redistribute and/or modify it
// in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================
package starling.filters;
import openfl.display3D.Context3D;
import openfl.display3D.Context3DBlendFactor;
import openfl.display3D.Context3DProgramType;
import openfl.Vector;
import starling.utils.Color;
import starling.core.Starling;
import starling.rendering.FilterEffect;
import starling.rendering.Painter;
import starling.rendering.Program;
import starling.textures.Texture;
import starling.utils.MathUtil;
class ChromaKeyFilter extends FragmentFilter
{
private var __color:UInt;
private var __threshold:Float;
#if commonjs
private static function __init__ () {
untyped Object.defineProperties (ChromaKeyFilter.prototype, {
"color": { get: untyped __js__ ("function () { return this.get_color (); }"), set: untyped __js__ ("function (v) { return this.set_color (v); }") },
"threshold": { get: untyped __js__ ("function () { return this.get_threshold (); }"), set: untyped __js__ ("function (v) { return this.set_threshold (v); }") },
});
}
#end
public function new(color:UInt = 0x00ff00, threshold:Float = 0)
{
super();
__color = color;
__threshold = threshold;
// this.maintainResolutionAcrossPasses = true;
}
/** @private */
override public function process(painter:Painter, helper:IFilterHelper,
input0:Texture = null, input1:Texture = null,
input2:Texture = null, input3:Texture = null):Texture
{
var effect:ChromaKeyEffect = cast this.effect;
effect.color = __color;
effect.threshold = __threshold;
return super.process(painter, helper, input0, input1, input2, input3);
}
/** @private */
override private function createEffect():FilterEffect
{
return new ChromaKeyEffect();
}
public var color(get, set):UInt;
public function get_color():UInt { return __color; }
public function set_color(value:UInt):UInt
{
__color = value;
return value;
}
public var threshold(get, set):Float;
public function get_threshold():Float { return __threshold; }
public function set_threshold(value:Float):Float
{
__threshold = value;
return value;
}
}
class ChromaKeyEffect extends FilterEffect
{
private var _threshold:Float;
private var _color:UInt;
private static var sVars:Vector<Float> = Vector.ofArray([0, 0, 0, 0.]);
private static var sVars2:Vector<Float> = Vector.ofArray([0, 0, 0, 0.]);
#if commonjs
private static function __init__ () {
untyped Object.defineProperties (ChromaKeyEffect.prototype, {
"color": { get: untyped __js__ ("function () { return this.get_color (); }"), set: untyped __js__ ("function (v) { return this.set_color (v); }") },
"threshold": { get: untyped __js__ ("function () { return this.get_threshold (); }"), set: untyped __js__ ("function (v) { return this.set_threshold (v); }") },
});
}
#end
/** Creates a new ChromaKeyEffect. */
public function new():Void
{
super();
_color = 0x00FF00;
_threshold = 0;
}
override private function createProgram():Program
{
var vertexShader:String = FilterEffect.STD_VERTEX_SHADER;
var fragmentShader:String = [
//"tex ft0, v0, fs0<2d, repeat, linear, nomip>"
FilterEffect.tex("ft0", "v0", 0, texture),
// Find difference in Red dimension (to power of 2)
"sub ft2.x, ft0.x, fc0.x",
"mul ft2.x, ft2.x, ft2.x",
// Find difference in Green dimension (to power of 2)
"sub ft2.y, ft0.y, fc0.y",
"mul ft2.y, ft2.y, ft2.y",
// Find difference in Blue dimension (to power of 2)
"sub ft2.z, ft0.z, fc0.z",
"mul ft2.z, ft2.z, ft2.z",
// Find distance in RGB color space from Chroma color
"add ft2.w, ft2.x, ft2.y",
"add ft2.w, ft2.w, ft2.z",
"sqt ft1.x, ft2.w",
// Multiply Alpha by zero if distance is less than or equal to threshold
"sge ft1.w, ft1.x, fc0.w",
"mul ft0.w, ft1.w, ft0.w",
"mov oc, ft0",
].join("\n");
return Program.fromSource(vertexShader, fragmentShader);
}
override private function beforeDraw(context:Context3D):Void
{
super.beforeDraw(context);
sVars[0] = Color.getRed(_color) / 0xff;
sVars[1] = Color.getGreen(_color) / 0xff;
sVars[2] = Color.getBlue(_color) / 0xff;
sVars[3] = _threshold;
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, sVars);
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, sVars2);
context.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
}
public var threshold(get, set):Float;
private function get_threshold():Float { return _threshold; }
private function set_threshold(value:Float):Float { return _threshold = value; }
public var color(get, set):UInt;
private function get_color():UInt { return _color; }
private function set_color(value:UInt):UInt { return _color = value; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.