jbattersby Posted June 1, 2015 Share Posted June 1, 2015 Hi, I'm somewhat confused about how the UV coordinates are allocated for sprites - my understanding is they should be ranging from 0.0 to 1.0 in both x and y directions. However, with the code below: this.wavetest = this.game.add.sprite(this.game.width * 0.5,this.game.height * 0.5,'wave_test'); var fragmentSrc = [ "precision mediump float;", "uniform sampler2D uSampler;", "varying vec2 vTextureCoord;", "void main(void) {", "vec4 texColor = texture2D(uSampler, vTextureCoord);", "if(vTextureCoord.x < 0.1){", "texColor = vec4(1.0, 0.0, 1.0, 1.0);", "}", "gl_FragColor = texColor;", "}" ]; this.filter = new Phaser.Filter(this.game, null, fragmentSrc); this.wavetest.filters = [this.filter];I get the following result: What I expect it to do is show the pink for the first 1/10th width of the sprite, not some arbitrary amount exceeding half! Can anybody explain this to me? I'm ultimately trying to shear and animate an array of sprites to create a wave effect that will encompass other objects. Fiddling with the fragment shader seems the only option to mimic modifying the vertices of a quad without resorting to something like three.js... which I may have to if this doesn't work out.... Link to comment Share on other sites More sharing options...
rich Posted June 2, 2015 Share Posted June 2, 2015 UV coordinates are normalised, so yes 0 to 1. There is nothing wrong with your shader code, it works fine for me here - but I'm using my own 512x512 texture (assets/textures/metal.png in the Phaser Examples repo if you want to try with it too) Here's my complete code:var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });function preload() { game.load.image('metal', 'assets/textures/metal.png');}var filter;var sprite;function create() { var fragmentSrc = [ "precision mediump float;", "varying vec2 vTextureCoord;", "uniform sampler2D uSampler;", "void main(void) {", "vec4 texColor = texture2D(uSampler, vTextureCoord);", "if (vTextureCoord.x < 0.1) {", "texColor = vec4(1.0, 0.0, 1.0, 1.0);", "}", "gl_FragColor = texColor;", "}" ]; // Texture must be power-of-two sized or the filter will break sprite = game.add.sprite(0, 0, 'metal'); filter = new Phaser.Filter(game, null, fragmentSrc); sprite.filters = [ filter ];}And it looks like this: Link to comment Share on other sites More sharing options...
jbattersby Posted June 2, 2015 Author Share Posted June 2, 2015 Very peculiar then, I get a similar effect with your texture (mine was also PoT (256x256)). Interestingly enough, the same amount of pink is covered in both textures: It seems reminiscent of a problem I had before when I was moving the sprite (with texture repeat on) and the sprite acted as a mask over a repeated texture in the background. This is running on 2.2.2 via a yeoman generator btw (as provided by codevinsky) Link to comment Share on other sites More sharing options...
rich Posted June 2, 2015 Share Posted June 2, 2015 You should try it against 2.3 (my screen shot above was against 2.4-dev) as 2.3 contains a vastly updated version of Pixi compared to 2.2. Unless the result we're seeing is hardware related, although I wouldn't have thought so for this specifically. But you never know. Link to comment Share on other sites More sharing options...
jbattersby Posted June 2, 2015 Author Share Posted June 2, 2015 Same result with 2.3 and 2.4 unfortunately :/ Like you I'm not convinced its a hardware issue - I first reported this on a Macbook Pro Retina, 13", Early 2013 but I've just viewed this though my LAN on a Windows 7 tower and it does exactly the same. Its reporting Pixi.js 2.2.8... is this correct? Could be the yeoman generator but I'm not convinced of that either unless its left out a crucial setup step.... Link to comment Share on other sites More sharing options...
rich Posted June 2, 2015 Share Posted June 2, 2015 What happens if you run my code exactly as I pasted above? (without any of the generator stuff you've currently got). Link to comment Share on other sites More sharing options...
jbattersby Posted June 2, 2015 Author Share Posted June 2, 2015 Welp, that narrows it down... no issue. *sigh* That's really quite annoying, its quite a useful bit of kit. Any ideas what *might* be causing this so I can dig a bit more effectively? Link to comment Share on other sites More sharing options...
rich Posted June 2, 2015 Share Posted June 2, 2015 I don't really know what it does, so not really. If I had to hazard a guess it would be something like the scale mode, or a world / stage scaling. Link to comment Share on other sites More sharing options...
jbattersby Posted June 3, 2015 Author Share Posted June 3, 2015 Hang on.... does the same happen for you when you set the canvas size to 1920x1080? Issue should be: texture remains the same size but the pink area will increase.... Because with my original generator stuff, setting it to 800x600 "fixes" it..... Link to comment Share on other sites More sharing options...
rich Posted June 3, 2015 Share Posted June 3, 2015 Ahh yes, that would make sense! When reading the texel is relative to the texture size, but writing it out again you're now dealing in screen space, not texture space. If you want to clamp the write to the specific texture area you'll need to do some texture width / screen width normalisation. Link to comment Share on other sites More sharing options...
jbattersby Posted June 3, 2015 Author Share Posted June 3, 2015 Ok, so if I change the code to this it works as expected:<!doctype html><html> <head> <meta charset="UTF-8" /> <title>hello phaser!</title> <script src="phaser.min.js"></script> </head> <body> <script type="text/javascript"> window.onload = function() { var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { game.load.image('metal', 'metal.png'); } var filter; var sprite; function create() { var fragmentSrc = [ "precision mediump float;", "varying vec2 vTextureCoord;", "uniform sampler2D uSampler;", "uniform vec2 resolution;", "void main(void) {", "vec2 uv = vTextureCoord / vec2(resolution.x/800.0, resolution.y/600.0);", "vec4 texColor = texture2D(uSampler, vTextureCoord);", "if (uv.x < 0.1) {", "texColor = vec4(1.0, 0.0, 1.0, 1.0);", "}", "gl_FragColor = texColor;", "}" ]; // Texture must be power-of-two sized or the filter will break sprite = game.add.sprite(0, 0, 'metal'); var customUniforms = { viewportX:{ type: "float", value: this.game.width}, viewportY:{ type: "float", value: this.game.height}, }; filter = new Phaser.Filter(game, null, fragmentSrc); filter.setResolution(512, 512); sprite.filters = [ filter ]; } function update() { sprite.x += 1; } }; </script> </body></html>I'd prefer not to hard code viewport values into the fragment but I'm confused by how custom uniforms should be passed (would prefer a vec2, say, viewport.xy) into the filter.... In any case, why is it not implied that the filter should apply to the texture/object space as oppose to the screen space? If I wanted a whole screen filter, shouldn't I apply it to the renderer or a sprite matching the size of it? Link to comment Share on other sites More sharing options...
rich Posted June 6, 2015 Share Posted June 6, 2015 Fragment shaders output in window space. Passing uniforms is easy: var customUniforms = { iChannel0: { type: 'sampler2D', value: sprite.texture, textureData: { repeat: true } } }; filter = new Phaser.Filter(game, customUniforms, fragmentSrc);A vec2 type would be '2f'. Link to comment Share on other sites More sharing options...
Recommended Posts