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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.