Comments (19)
Nice idea 👍 I will add the feature to my list. Would be useful for pixel art / retro games!
from pixijs.
I was experiencing this as well, not only blurring but strange artifacts on the sprites as well. I implemented the solution in the article and it seems to fix the issue for me.
This is a version of Pixi.js built with that fix in there, see if that works for you. https://github.com/Ateoto/pixi.js/blob/feature-pixelsnap/bin/pixi.dev.js
This is where I implemented the fix:
ateoto@3d0cb99
from pixijs.
Excellent, will give it a whirl!
from pixijs.
You can achieve this easily on the user-land side, I don't think it is something we want to force into the core.
from pixijs.
I'd appreciate support for this in Pixi itself (currently patching it in). How do you envision arranging it in user-land? It's doable if all display objects are in a single, pixel-aligned container, but it becomes highly impractical when nested objects are used, where the misalignment may occur at any level in the tree.
from pixijs.
The short answer is to just take care not to assign floating values to your positions, if something is a delta change round/floor/ceil it before assigning.
You're right, this isn't an easy problem to solve, but I don't think the solution is to make objects everywhere have a potentially expensive branching path and math operation to catch mistakes a situation that only exists when doing certain types of applications. Canvas renderer currently has a roundPixels option that increases rendering speed by flooring positions as images are drawn, but it doesn't work like that on WebGL. We would have to round/floor/ceil positions in js which would negatively effect the renderer's performance.
There is also the issue that some applications want to round positions as the move, some want to floor, and some want to ceil, some want to let the browser interpolate normally. It depends on the application. If the answer is "it depends on the application" it probably doesn't belong in the core.
I'm not convinced that this belongs in pixi core because it means adding a branch to every update transform call at best, or many branches at worst. I'm still of the opinion that you should just round/floor/ceil your values you assign to positions as you do it in your application, if it makes sense to do so in your application. I've done this in quite a few apps now, usually there is only a couple (or just one) physics integration point where positions are actually being set. Generally when syncing the body positions to the sprite I just floor it, and it works well (sometimes round, depending).
from pixijs.
Take for example a spaceship moving slowly around a space. You don't want to round its x
and y
, because then you can't achieve the slow motion. The spaceship has lots of elements, rotating turrets, etc. Also, there is zooming and rotation of the view going on.
You only want the leaves in the display tree, the actual sprites, to snap to the pixel grid. The only practical place to apply this would be somewhere between updateTransform
and the actual rendering.
I fully sympathize with not wanting to add code to fix a very specific problem in such a general location. I'm all for separation of concerns. (Why does BaseTexture
deal with loading/caching images from urls? :-] )
So would you consider adding an optional callback inside/after DisplayObject.transform
? It would receive the updated matrix, allowing it to modify it further, e.g. applying rounding/flooring/whatever to the translation values.
If you're worried about branching, you might implement it somewhat like this:
DisplayObject.prototype.setTransformCallback = function(cb) {
if (cb != null) {
this.updateTransform = function() {
DisplayObject.prototype.updateTransform.call(this);
cb(this.worldTransform);
};
} else {
delete this.updateTransform; // revert to using the prototype version
}
}
from pixijs.
(Why does BaseTexture deal with loading/caching images from urls? :-] )
Historical and usability reasons, it was written like that a long time ago before we had a loader and unfortunately people started using it and expect it to be that way :( I hate it.
So would you consider adding an optional callback inside/after DisplayObject.transform? It would receive the updated matrix, allowing it to modify it further, e.g. applying rounding/flooring/whatever to the translation values.
I have thought so long and hard about this one. The challenge is making it happen in a way that is performant, and I haven't found a method with low enough overhead to make it acceptable, yet.
If you're worried about branching, you might implement it somewhat like this:
Well we definitely can't do that since that will change the hidden class of the object. But I understand what you are going for. I'll try to think about this problem more and see if we can't get a good solution.
from pixijs.
It would change the hidden class, but only for users who explicitly want to have that callback and are ready to take the performance hit. One then wouldn't apply it to thousands of bunnies (in my case the number of objects using it is in the 100 order of magnitude).
Also, if the new updateTransform
were not to be a closure but a function defined once (with the callback stored as a property), it would add only one hidden class.
Anyway, I've looked around the source a bit and found things like displayObjectUpdateTransform
and _originalUpdateTransform
. I'm sure you're able to find a way to work this in :)
from pixijs.
@bartvanheukelom Yeah it is possible, those aren't adding/removing properties though just chaning them. And displayObjectUpdateTransform is just a shortcut to calling up the prototype chain to reduce the call stack in hot methods.
In other words, those examples add speed but yours reduces it :P let me think on this a bit.
from pixijs.
Also I noticed that PIXI.Text
gets blurry when not using roundPixels
. It's very difficult to not use floating numbers on the final position since the anchor
/pivot
usually are float values (0.5 for center), so this is not on the user control anymore - using integers on x
/y
will not ensure that the evaluated position is actually an integer.
Maybe just PIXI.Text
should round it's position in this case, and not the entire core.
from pixijs.
Hello! With v3 you can snap to using renderer.roundPixels = true
from pixijs.
@GoodBoyDigital This issue still exists when rotation/angle is used unfortunately. Can the same algorithm that is used by CSS3 rotateZ, etc, be used here?
from pixijs.
@skaraman im not sure i follow i'm afraid? If you provide an example of the issue and what needs solving that would be ace. Thanks!
from pixijs.
@GoodBoyDigital actually it was to do with retina resolution - http://www.html5gamedevs.com/topic/20776-pixel-percision-on-rotation-for-renderer/
from pixijs.
I'm trying to avoid this pixel snapping functionality. I want to have a lot of slow moving sprites and the motion doesn't look nice when they snap to each pixel. I've tried renderer.roundPixels = false
but it has no effect (Pixi.js 4.5.1 - Canvas / Chrome 58.0.3029.96 (64-bit) / OSX).
Is there any way to fix this? It's a deal breaker for me at the moment :(
I can easily repro it in the "tinting" demo with these line modifications:
//dude.scale.set(0.8 + Math.random() * 0.3); // Comment out this line
//dude.rotation = -dude.direction - Math.PI / 2; // Comment out this line
dude.speed = 0.1; // Make them move slowly
from pixijs.
Hi all, any ideas as to why renderer.roundPixels = false
seems to have no effect in my case above? Thanks for any suggestions.
from pixijs.
RoundPixels is off by default. How big coordinates are you working with? May be its precision problem.
from pixijs.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
from pixijs.
Related Issues (20)
- Bug: [v8] Compressed textures are not being rendered HOT 6
- Bug: PIXI.Graphics method lineTo at later call different
- Bug: Argument of type 'Sprite' is not assignable to parameter of type 'DisplayObject'. HOT 4
- Bug: http://gametest.mobi/pixi/morph is down HOT 2
- Bug: Stutter in basic animation on various browsers and OS HOT 1
- Save and load the current state of the application
- Bug: Graphics scaling and adding filters, display abnormal
- Bug:
- Bug: Unexpected behaviour of alpha on Graphics HOT 1
- Bug: [v8 regression] cannot do many `moveTo`/`lineTo` HOT 13
- Bug: API Documentation URLs Leading to 403 Errors HOT 3
- Bug: BitmapText color
- Bug: app.renderer.extract.base64 doesn't apply tint HOT 1
- Feature Request: Allow GraphicsContext.poly to accept PointData[] HOT 1
- Bug: Assigning filters after initial assignment is busted without invalidating
- Bug [v8 migration]: utils.clearTextureCache() no longer exist HOT 2
- Bug: [v8 regression] Graphics Mask doesn't always update when clearing and redrawing HOT 2
- Feature Request: Support for bundle tree on AssetsManifest
- Virus detected when I try to download PixiJS HOT 2
- Bug: [v8] Missing information on Migration guide for v8 or in the Blog post of v8 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pixijs.