hexus Posted June 25, 2016 Share Posted June 25, 2016 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! Link to comment Share on other sites More sharing options...
Recommended Posts