Skip to content

Instantly share code, notes, and snippets.

@Beeblerox
Created October 7, 2017 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Beeblerox/6285c39ef17a1db887b1d4559668ab12 to your computer and use it in GitHub Desktop.
Save Beeblerox/6285c39ef17a1db887b1d4559668ab12 to your computer and use it in GitHub Desktop.
mixing two render targets together
package;
import flash.Lib;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.FlxStrip;
import flixel.effects.FlxRenderTarget;
import flixel.graphics.FlxMaterial;
import flixel.graphics.shaders.quads.FlxTexturedShader;
import flixel.group.FlxGroup;
import flixel.system.FlxAssets.FlxShader;
import flixel.ui.FlxBar;
import flixel.ui.FlxButton;
import flixel.util.FlxColor;
import openfl.Vector;
/**
* ...
* @author Zaphod
*/
class RenderTargetState extends FlxState
{
var rt1:FlxRenderTarget;
var rt2:FlxRenderTarget;
var rt3:FlxRenderTarget;
var rt4:FlxRenderTarget;
override public function create():Void
{
// unfortunately for mixing 2 render targets (each of them have its own shader)
// we'll need 4 render targets (not 3)
rt1 = new FlxRenderTarget(128, 128);
rt2 = new FlxRenderTarget(128, 128);
rt3 = new FlxRenderTarget(128, 128);
rt4 = new FlxRenderTarget(128, 128);
var s1:FlxSprite = new FlxSprite();
var s2:FlxSprite = new FlxSprite();
// first render target will use invert shader
// secont render target will use default shader (for sake of simplicity, but you could set any shader you want).
rt1.shader = new InvertShader();
// we'll render sprite s1 to first render target
// and sprite s2 to second render target
rt1.add(s1);
rt2.add(s2);
// first render target will be drawn on third render target.
rt3.add(rt1);
// second render target will be drawn on fourth render target.
rt4.add(rt2);
// for the fourth render target we will use shader which mixes two textures:
// - first texture is the texture of render target itself
// - second texture is the texture of the third render target
rt4.shader = new MixShader();
rt4.material.data.uMix.value = [0.5];
rt4.material.data.uImage1.input = rt3.renderTexture.bitmap;
// fourth render target will be actually rendered on the screen.
add(rt4);
}
override public function update(elapsed:Float):Void
{
// let's update mix value
rt4.material.data.uMix.value[0] = 0.5 * (1 + Math.sin(Lib.getTimer() / 1000));
rt4.x = 0.5 * FlxG.width * (1 + Math.sin(Lib.getTimer() / 1000));
// we need manually update third render texture, because we haven't added it to state.
rt3.update(elapsed);
super.update(elapsed);
}
override public function draw():Void
{
// we need to update texture of the third render target
// (but you could do it not in every frame)
rt3.renderGroup(true);
// and then render everything.
super.draw();
}
}
class InvertShader extends FlxTexturedShader
{
public function new()
{
var fragment:String = "
varying vec2 vTexCoord;
varying vec4 vColor;
varying vec4 vColorOffset;
uniform sampler2D uImage0;
void main(void)
{
vec4 color = texture2D(uImage0, vTexCoord);
gl_FragColor = vec4((1.0 - color.r) * color.a, (1.0 - color.g) * color.a, (1.0 - color.b) * color.a, color.a);
}";
super(null, fragment);
}
}
class MixShader extends FlxTexturedShader
{
public function new()
{
var fragment:String = "
varying vec2 vTexCoord;
varying vec4 vColor;
varying vec4 vColorOffset;
uniform sampler2D uImage0;
uniform sampler2D uImage1;
uniform float uMix;
void main(void)
{
vec4 color1 = texture2D(uImage0, vTexCoord);
vec4 color2 = texture2D(uImage1, vTexCoord);
gl_FragColor = mix(color1, color2, uMix);
}";
super(null, fragment);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment