Last active
April 27, 2018 01:40
-
-
Save TomByrne/a1e8f183169c68e3ec0995bc5a74ef00 to your computer and use it in GitHub Desktop.
Chroma Key Filter for the Haxe version of Starling 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================================================================= | |
// | |
// 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