Sampling a second texture using same TextureCoordv

I seem to misunderstand how TextureCoordv works. Given two bitmaps with exact same dimensions, when I try to sample second texture, it does not work as expected. See:

package;

import openfl.Assets;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.DisplayObjectRenderer;
import openfl.display.Shader;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.filters.BitmapFilter;
import openfl.filters.BitmapFilterShader;

class Main extends Sprite
{
	private static inline var RADIUS = 175;

	private var gradient:Sprite;
	private var gradientS:Sprite;
	private var gradient2:Sprite;
	private var gradient2S:Sprite;
	private var gradientDrawn:BitmapData;

	private var gradientGlowFilter:BitmapFilter;

	public function new()
	{
		super();

		drawGradient();
		drawGradient2();

		createGradientGlowFilter();

		addChild(gradient2);
		addChild(gradient);

		gradient.filters = [gradientGlowFilter];
	}

	function createGradientGlowFilter()
	{
		gradientGlowFilter = new GradientGlowFilter(gradientDrawn);
	}

	private function drawGradient()
	{
		gradientS = new Sprite();

		gradientS.graphics.beginFill(0xFFFFFF);
		gradientS.graphics.drawRect(0, 0, RADIUS * 2, RADIUS * 4);
		gradientS.graphics.beginFill(0x000000);
		gradientS.graphics.drawRect(RADIUS * 2, 0, RADIUS * 2, RADIUS * 4);
		gradientS.graphics.endFill();

		gradient = new Sprite();
		gradient.addChild(gradientS);
		gradientS.x = -gradientS.width / 2;
		gradientS.y = -gradientS.height / 2;

		gradient.x = stage.stageWidth / 2;
		gradient.y = stage.stageHeight / 2;
		gradient.cacheAsBitmap = true;
	}

	private function drawGradient2()
	{
		gradient2S = new Sprite();

		gradient2S.graphics.beginFill(0xFF0000);
		gradient2S.graphics.drawRect(0, 0, RADIUS * 2, RADIUS * 4);
		gradient2S.graphics.beginFill(0x0000FF);
		gradient2S.graphics.drawRect(RADIUS * 2, 0, RADIUS * 2, RADIUS * 4);
		gradient2S.graphics.endFill();

		gradient2 = new Sprite();
		gradient2.addChild(gradient2S);
		gradient2S.x = -gradient2S.width / 2;
		gradient2S.y = -gradient2S.height / 2;

		gradient2.x = stage.stageWidth / 2;
		gradient2.y = stage.stageHeight / 2;
		gradient2.cacheAsBitmap = true;

		gradientDrawn = new BitmapData(RADIUS * 2, RADIUS * 2, true, 0);
		gradientDrawn.draw(gradient2);
	}
}

class GradientGlowFilter extends BitmapFilter
{
	public var __shader:GradientGlowFilterShader;
	public var __content:BitmapData;

	public function new(content:BitmapData)
	{
		super();

		__numShaderPasses = 1;
		__shader = new GradientGlowFilterShader();
		__content = content;
	}

	private override function __initShader (renderer:DisplayObjectRenderer, pass:Int, sourceBitmapData:BitmapData):Shader {
    __shader.uContent.input = __content;

		return __shader;
	}
}

class GradientGlowFilterShader extends BitmapFilterShader
{
	@:glFragmentHeader('
		uniform sampler2D uContent;
	')

	@:glFragmentBody('
		vec4 contentColor = texture2D(uContent, openfl_TextureCoordv);

		if (openfl_TextureCoordv.x < 0.75) {
			gl_FragColor = vec4(contentColor.rgb, 1.0);
		}
	')

	public function new()
	{
		super();
	}
}

Expected result: 1/2 blue, 1/4 red, 1/4 black. Actual result: 3/4 blue, 1/4 black. What am I doing wrong here?

Hi! You are using very strange code to fill the BitmapData. As i can see, it will be filled only with blue.

Are the texture coordinates in the dimensions of the image?

https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Texture_coordinates

@Egis no, it is half blue, half red.

@singmajesty I don’t really know, those are just two bitmaps with exact same dimensions and shapes, and I guessed the coords would match as well. How can I otherwise sample the whole second texture?

No, BitmapData is only blue. Shader code works as expected. If you check your BitmapData (!) and you can see red color on it, i would be interested to discuss this strange behaviour. Is it html5 or another platform?

1 Like

Sorry for the confusion, I did not account for drawing being on negative coordinates of my bitmapdata. The solution was to use a translation matrix.

1 Like