Jump to content

Adding a filter causes smoothing/blurring and shaking (position) while rotating


brokedRobot
 Share

Recommended Posts

I've stumbled across an undesirable effect.  When I add a filter to a sprite, and rotate it, the sprite is smoothed (blurred a small amount, looks like linear maybe) and also, it shakes slightly (you have to look closely to see it, but it becomes very apparent on small sprites.  I don't know if this is phaser or pixi, but I was wondering if anyone knew of a way to alleviate the effect.  The position thing looks to be loss of precision on the position or at least the effect makes it look like that, jumping from one pixel location to the next or something like that.  The other I don't know about.  There's no interpolation in the filter, the only thing I'm really doing is gl_fragcolor = texture2D(uSampler, vTextureCoord);

both effects are removed if you just comment out the line: sprite.filters = [filter]; (removing the filter)

here's a link to the simple example:

https://brokedrobot.com/resources/dev/public/index2.html

and here's the code for that example:

<html id="html" style="overflow: hidden;" ng-app="html">
<head>

	<title>Example</title>
	
	<meta name="author" content="glitchedRaven">
	<meta name="keywords" content="">
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1.0,
		user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
	
	<script src="phaser.min.js"></script>

</head>
<body style="background: green; margin: 0vh; padding: 0vh;">
	<script>
		var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }, true);

		function preload() {

			game.load.image('texture', 'test.png');

		}

		var filter;
		var sprite;

		function create() {

			//  Shader by Kali (https://www.shadertoy.com/view/4dfGDM)
			//  Image patched by Richard Davey

			var fragmentSrc = [

				"precision mediump float;",

				"uniform float     time;",
				"uniform vec2      resolution;",
				"varying vec2      vTextureCoord;",
				"uniform sampler2D iChannel0;",
				"uniform sampler2D uSampler;",

				"void main( void ) {",

					"vec2 uv = gl_FragCoord.xy / resolution.xy;",
					"uv.y *= -1.0;",
					"uv.y += (sin((uv.x + (time * 0.5)) * 10.0) * 0.1) + (sin((uv.x + (time * 0.2)) * 32.0) * 0.01);",
					//"vec4 texColor = texture2D(uSampler, uv);",
					"vec4 texColor = texture2D(uSampler, vTextureCoord);",
					"gl_FragColor = texColor;",

				"}"
			];

			//  Texture must be power-of-two sized or the filter will break
			
			sprite2 = game.add.sprite(310, 230, 'texture');
			sprite = game.add.sprite(0, 0, 'texture');
			sprite.width = 400;
			sprite.height = 300;
			sprite.x = 400; sprite.y = 300;
			sprite.anchor.set(0.5, 0.5);
			sprite.scale.set(1.5, 1.5);
			sprite.smoothed = false;
			

			var customUniforms = {
				iChannel0: { type: 'sampler2D', value: sprite.texture, textureData: { repeat: true } }
			};

			filter = new Phaser.Filter(game, customUniforms, fragmentSrc);
			filter.setResolution(1024, 1024);

			sprite.filters = [ filter ];

		}

		function update() {
			sprite.rotation += 0.01;
			filter.update();

		}
	</script>
</body>
</html>

As I understand it, filters use a canvas element behind the scenes to render, but is there any way I can set the imageSmoothingEnabled property of that element?  Or make the filtered sprite match the unfiltered sprite some other way?  To be honest, the position shaking thing is more troublesome to me than the smoothing thing, is there a way to keep the location steady?

Link to comment
Share on other sites

Have you removed the blur to see if this works as intended? I can't say for certain why this is happening, but I'm going to go out on a limb and assume this is a mathematical issue.. to be more precise, a rounding issue. Because the sprite's rotating.. it needs to be in one pixel or the other, however when you add a blur to this and thus the smooth edges, when rotating, the renderer is given positions that when rounded will sometimes be one pixel out.. hence your jumping. 

I should think there is a very easy fix for this though, if you draw your sprite, add your blur, then create a new bitmapTexture from this, then you can use that blurred sprite as a fresh sprite, which then wouldn't technically use the blurred effect. If you want to keep changing the filter then this fix probably doesn't really work for you.

 

Link to comment
Share on other sites

There is no blur in my code.  I'm trying to remove the blur as well.  It is one of the undesired effects of adding the filter.

There's really only two lines that matter in the filter, the rest of it is from an example and isn't doing anything.  The filter is as simple as:

"vec4 texColor = texture2D(uSampler, vTextureCoord);",

"gl_FragColor = texColor;"

I want to remove the blur and the rounding error.  They may in fact be connected as you say, but I am not intentionally adding either.

 

EDIT: I've since removed the blurring by setting the renderer's antialiasing property false, but that just makes the jumping even more pronounced...I altered the example page to reflect..

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...