Sign in to follow this  
hexus

Filter Textures - RenderTexture Y coordinate inversion

Recommended Posts

I've been working recently on a lighting system for my game, and I've noticed something awkward when passing render textures to fragment shaders.

TL;DR: Why does uSampler act normally when any other RenderTexture passed into a shader needs vTextureCoord.y *= -1.0 to prevent it from being inverted on the Y axis?

I'll try to explain with the code as concisely as I can, but I don't have a demo I can show for this issue.

I'm drawing a game world to a render texture a little like this:

// When booting the renderer:
var diffuse = new Phaser.Sprite(game, 0, 0, new Phaser.RenderTexture(
	game,
	game.width,
	game.height,
	null,
	Phaser.scaleModes.NEAREST
));

var cameraMatrix = new Phaser.Matrix(1, 0, 0, 1,
	-game.camera.x,
	-game.camera.y
);

// Outside the renderer, after booting it:
var filter = new Phaser.Filter(game, {
	diffuse: { type: 'sampler2D', value: diffuse.texture }
}, game.cache.getShader('diffuse'));

game.world.filters = [filter];


// Later on in the rendering pass:

// Retain existing filters
filters = game.world.filters;

// Render the world to the texture without filters
game.world.filters = null;
diffuse.texture.render(game.world, cameraMatrix, true);

// Set back the filters
game.world.filters = filters;

It's part of a sprite because that makes it easy to output on the stage for debugging (to view it, really). If I do this, it renders fine.

Now, my lighting system acts on this diffuse texture to apply some shaders. I've finally got my system working, but unfortunately with a lot of uv.y *= -1.0; hacks to get around this Y inversion issue I've been finding when running a render texture through a shader sampler. I would rather remove these hacks and have the shaders read more cleanly.

When I use a Filter to draw the resulting lit texture over the game world, it is inverted on the Y axis. This can be demonstrated with the following fragment shader and Phaser Filter:

precision highp float;

varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D diffuse;

void main() {
	gl_FragColor = texture2D(diffuse, vTextureCoord);
}
filter = new Phaser.Filter(game, {
	diffuse: { type: 'sampler2D', value: diffuse.texture }
}, game.cache.getShader('diffuse'));

world.filters = [filter];

Why is it flipped here and uSampler isn't? For example, if I change the fragment shader to use uSampler:

void main() {
	gl_FragColor = texture2D(uSampler, vTextureCoord);
}

It doesn't render upside down.

I've tried looking for the reasoning behind this but can't find much. A pixi bug perhaps? Or should I just pass all textures to my shaders with flipY set to true?

new Phaser.Filter(game, {
	diffuse: { type: 'sampler2D', value: diffuse.texture, textureData: { flipY: true } }
}, game.cache.getShader('diffuse'));

Is uSampler flipped automatically? That might explain. Cheers!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.