4ian / GDevelop

:video_game: Open-source, cross-platform game engine designed to be used by everyone.
https://gdevelop.io
Other
6.56k stars 722 forks source link

[$200+ Bounty]Implement "Bitmap Text" object to avoid blurry or distorted text objects in pixel perfect games (and benefit from higher performance of the text rendering) #1449

Closed Silver-Streak closed 3 years ago

Silver-Streak commented 4 years ago

Describe the bug

When using a text object (or BBText object), if you resize the game, the text will become either blurry or distorted. This seems to have gotten worse since the release of the new resolution options and events related to them.

This occurs if you resize through any method, including by dragging and resizing the window, using fullscreen on a monitor that is a different resolution, or by using any of the resolution/fullscreen events.

Using the solution here does not solve this problem, although it does slightly reduce the effect: https://forum.gdevelop-app.com/t/solved-pixel-art-fonts-are-fuzzy-text-font-blury/14225

To Reproduce

  1. Create a text object.

  2. Set the font size to something large so it is more noticeable (Size 40+).

    • Note: this still occurs on small fonts, just harder to notice.
  3. Set your game resolution to any size smaller than your monitor (e.g. 1280x720 on a 1080p monitor)

  4. Place the text object in the scene.

  5. Launch the preview, or compile the game and run it.

  6. Stretch the window larger, or set the game to fullscreen.

  7. The text will either be blurry, or have distorted pixels. This occurs regardless of whether using linear or nearest scaling.

I've attached the default platformer example project with some text objects with both the default font and a custom font to show this effect. My project4.zip

In my actual game, here's some examples Using the example fix linked above (showing it does not resolve it):

Here's the text before the window has been changed in size (720p)- image image

Here's the text after the game has been fullscreened on a 1080p monitor- image image

It is important to note: If you create an image with the text you want in an image editor (such as gimp) and add it as a sprite object, it does not have the blurriness or distortion when resizing. So it is something specific with how GDevelop/Pixi is scaling the Text Objects.

Other details

Bouh took a crack on this over on the forums to apply some potential fixes we found such as enabling the roundPixels function. This had a noticeable improvement, but it is still being distorted. You can still see the distortion in these images, although they are much better: image

image

I've been doing some digging, and it seems like this is due to how the Text Object is being scaled in GD5's implementation of Pixi. Apparently it's not intended to be scaled like other objects are, due to how Pixi uses the OS' native scaler and that's not optimal for text.

Note: this is my very basic understanding from reading multiple threads on how scaling impacts Pixi.Text, I could be interpreting it wrong.

Here are some alternative methods offered that may resolve this:

Potential Solution 1: Do not scale Text objects, keep them at their native size but scale the font size based off the scaling size:

Potential Solution 2: Adjust the Pixi.Text ratio based off the canvas pixel density:

Potential Solution 3: Signed Distance Field (SDF) Text

Potential Solution 4: Bitmap Font object

Please let me know if there's any other info or testing needed.

4ian commented 4 years ago

Thanks for the very detailed explanations :) 👍 I don't have any bandwidth to take a look at this but this is a very interesting project for anyone wanting to contribute to GD.

Silver-Streak commented 4 years ago

If anyone can/wants to take a look at this:

I've started looking at the code snippet here: https://codepen.io/Tazy/pen/wJVExB?editors=0010

While I haven't used Javascript in years, I think the main gdjs function around "onGameResolutionResized" (I believe in GDJS.js?) would need to ensure it doesn't scale TextObject using it's normal method, and would instead use the listed function in the snippet around resizing the font. If not GDJS, it might need to be in RuntimeScene.js (specifically gdjs.RuntimeScene.prototype.onGameResolutionResized) and have it exclude TextObjects (or Treat objects differently).

I also believe you might need to disable all of the scaling functionality on the text object itself in the TextObject runtime (likely textruntimeobject.js, textruntimeobject-pixi-renderer.js), to ensure it's scale is always set to 1. This may not be necessary if the above is completed (and incase the user specifically uses scaling events on the object)

I think it would be pretty safe to say font 4px would be the smallest, and then the "BaseFontSize" would always be whatever the player selects as the font size in the editor. I wanted to test this method without any concern of editor functionality to see how it works...but I'm no where near good enough to know how to manipulate any of the functions listed above, or even know if I'm on to something, sadly.

Hopefully if someone does look into this, the above can help. If I'm understanding properly, solution 1 could potentially be applied to regular text objects AND bb text objects, and would (in theory) solve all font scaling...as they're no longer being scaled at all. Any other "blurriness" would be an issue with the font, and not GD5 or Pixi, since they're just rendering the font at the same size Windows would be.

deadpool1999 commented 4 years ago

Hello , I am an open source aspirer, trying to learn open source style of programming. Is this the right place I am looking at : https://github.com/4ian/GDevelop/blob/master/GDJS/Runtime/runtimescene.js in this file the "onGameResolutionResized" fuunction. If yes, please help me in understanding what is _layers here.

Silver-Streak commented 4 years ago

I think _layers is the call for returning the layer name. I'm not a dev though and could be 100% incorrect, so I'd wait for 4ian, Bouh, or another Contributor to confirm.

4ian commented 4 years ago

I'm not sure we have a precise solution here @deadpool1999. As the label "🙇‍♀️Careful thinking/design or refactoring needed" indicates, there is probably some more complex underderstanding of how text work. I'm not actually sure there are even changes to do in onGameResolutionResized. For _layers, the name is pretty much saying it all, it's a variable containing layers. What's layers? You can find this in the documentation or searching a bit in the code :)

Silver-Streak commented 4 years ago

@4ian So I don't think this is one of the items being covered by GSOC, correct? If not, is this something that you would feel eligible for me to throw another bounty on? If we'd rather wait until GSOC is over to see if any pulls it, I'm happy to wait on that too. 😄

I can delete this comment to avoid influencing people's decisions, as well.

4ian commented 4 years ago

This is not in the original project idea list, but could be a project if someone want to make a solid proposal for this. I think though it would be worth a bounty as it's more an in depth investigation that is needed :)

Silver-Streak commented 4 years ago

Thanks 4ian.

I have posted a bounty on this issue here: https://www.bountysource.com/issues/89023609-changing-resolution-makes-text-objects-blurry-or-distorted

My overall preference/requirements on this (although obviously I'm not the final say): Preferred:

Medium preference:

Less preference:

@4ian , not sure if you want to throw the Bounty tag on this issue, or if that tag is used on this repository or not. Thanks for your and @Bouh 's time on this over the past few weeks.

Bouh commented 4 years ago

$70 USD on bounty source for this issue, @4ian bounty source tag can be added. https://www.bountysource.com/issues/89023609-changing-resolution-makes-text-objects-blurry-or-distorted

Silver-Streak commented 4 years ago

I got a e-mail about a mention that isn't here, so I'm assuming it was deleted, however it appears someone was asking about where the text runtime objects I mentioned are located.

They can be found here: https://github.com/4ian/GDevelop/tree/master/Extensions/TextObject

Hope this helps anyone looking into this.

HarsimranVirk commented 4 years ago

Okay, @Silver-Streak I didn't look into Extensions (and checked only GDJS/Runtime), so I thought TextObjects are treated as normal RuntimeObjects, sorry about that, my bad :) Anyway, I want to ask why do we scale TextObjects? I mean we could've changed their font size instead of scaling? Is there any special purpose for scaling the fonts?

https://github.com/4ian/GDevelop/blob/4edbd9d37743eda30335c67339cbec4948ad124a/Extensions/TextObject/textruntimeobject-pixi-renderer.js#L147-L166

Maybe we could have a function like these which sets the font size instead of setting scale? We are already passing the runtimeScene, which means we could get the resolution, and set the font size accordingly.

Silver-Streak commented 4 years ago

@HarsimranVirk I'm not a contributor, and I think 4ian and Bouh/all of the contributors goal is for a careful solution to be put in place for this.

However, if you look at "Potential Solution 1" in the second or third post above, it provides a method to do exactly what you're mentioning. It looks at the "default" resolution for the game, your selected font size, then scales the font size up and down rather than the font itself. It's my personal preferred solution for this since it should avoid all scaling issues altogether for text.

Quoted for posterity:

Potential Solution 1: Do not scale Text objects, keep them at their native size but scale the font size based off the scaling size:

Thread that discusses it - https://www.html5gamedevs.com/topic/36463-pixijs-v4-does-not-remain-sprite-pixelated-as-it-original-is Code example - https://codepen.io/Tazy/pen/wJVExB Note: This seems like it might be the "prettiest" option, in that it should accommodate almost every font/text combination, I do not understand how difficult it would be to implement, however.

HarsimranVirk commented 4 years ago

@Silver-Streak I've been checking on some functions related to resizing, and I strongly believe that the TextObject, or really any other object is not directly scaled at all. I have 2 reasons for that,

  1. I'm not really familiar with the codebase, but if I had to implement the resizing, I wouldn't access each and every object present in the scene (or layer) and scale them up/down individually. This wouldn't be the most efficient way since there could be dozens of objects in a scene. Instead, I'd scale the entire scene or layer, which would result in indirect scaling of all the objects.

  2. I couldn't find any code related to scaling individual objects, (it's possible that there is some code which I really couldn't find) but I found a lot of stuff scaling scenes and layers. I'd need to confirm this with @4ian and @Bouh, however.

I've tried to simplify what I'm trying to say, here, https://codepen.io/harsimran-singh-virk/pen/oNXydEb?editors=0010

I'm not sure if this is the real cause of the problem, but if it is, then a potential solution can be:

  1. TextObject is bound to scale if it's parent container is scaling, so if we could reverse it somehow, ie, if the parent container is scaling up, we could scale down the TextObject. This would effectively nullify the scaling.
  2. After the reverse-scaling, we can set the font-size accordingly. I'm also not sure about how this could be implemented, would definitely require help from @4ian and @Bouh.
Silver-Streak commented 4 years ago

@HarsimranVirk I believe you are correct. TextObject inherits the behavior from (I think) GDJS.js around a "onGameResolutionResized" function.

To implement this method I think there would likely need to be a change so it no longer inherits that scaling 1:1 and instead when onGameResolutionResized is called, TextObjects (and BBtextobjects) use this other font size scaling method, instead of just scaling the object itself.

I'll wait for 4ian and Bouh (or another contributor) to chime in, as I only know very basic JS and found the above from poking around, and it may be completely incorrect.

4ian commented 4 years ago

There is no special scaling applied to objects. All game objects are rendered to a canvas, using the game resolution. The canvas is then stretched to fill the window/page, but not object individually.

This does not seem related to GDevelop. It would be interesting to reproduce the issue of a Pixi sample. Basically, render a text with a font, and put a sprite with some text using the same font and same size next to it. Then, enlarge the canvas. Check if the text is blurred and differs from the sprite. If not, then there must be something that we've wrongly done in GDevelop, or we've not properly applied the styles for resizing using nearest neighbours. If there is a difference, then this should be probably a question for Pixi.js

Silver-Streak commented 4 years ago

@4ian

Looking at https://codepen.io/Tazy/pen/wJVExB, it seems like they're applying this alternative scaling logic (or lackthereof) to Text objects using Pixi. If I understand correctly, they're basically creating a separate function that handles text scaling for the canvas, basically creating a separate instance of the GDJS "onGameResolutionResize" (or equivalent) that instead of scaling it just changes font size.

So I think you're correct: This is an issue stemming from applying scaling to the whole Pixi canvas (via pixi). However, it makes me think that maybe a general scaling for all items isn't the best way to do scaling? (or at least, breaking text out of that general scaling would solve this issue)

Again, I"m very much a layman, though 😄 So I'm just trying to understand using what little JS I know.

Silver-Streak commented 4 years ago

I've bumped up the bounty on this and asked Bountysource to tweet about it in hopes of spurring more interest. https://www.bountysource.com/issues/89023609-changing-resolution-makes-text-objects-blurry-or-distorted 😄

Bouh commented 4 years ago

@Quarkstar This issue is still present in your pixi v5 branch ? Be sure to make good comparaisons between the versions v4/v5.

Quarkstar commented 4 years ago

This issue is still present in your pixi v5 branch ? Be sure to make good comparaisons between the versions v4/v5.

Yes, it's still there. I think it looks the same in v4 and v5 branch.

ShukantPal commented 4 years ago

@Silver-Streak @4ian Nice discussion here; The first solution posted here is quite simple and should do the job. Are there any obstacles in implementing that solution?

If you want to scale text via font size (not by Pixi's internal scaling), you can create a PIXI.Container wrapper around a PIXI.Text. This wrapper would have a custom _render method:

Silver-Streak commented 4 years ago

@SukantPal

Thank you greatly for chiming in.

While I'm definitely not one that would be able to implement it, could you clarify on the last step? I though the goal would be to avoid any scaling on the text at all. Wouldn't text.scale remain the original size but text font size be changed instead? What does downscaling the text's transform gain?

(This is more curiosity than anything else)

ShukantPal commented 4 years ago

@Silver-Streak Option 1 wants to replace the “scaling factor” with a larger font size. To nullify the “scale”, you need to apply the inverse of it. If you don’t, both the transform scaling and larger font size would be at work..

Silver-Streak commented 4 years ago

Hmm, now I'm more confused. If we're removing any scaling from occurring on that object (Leaving text object scale at 100%), wouldn't the larger font size appear 'normal'/same size as before since it's only being displayed when the window resolution has increased/scaled up accordingly?

ShukantPal commented 4 years ago

@Silver-Streak

Look at this: https://jsfiddle.net/ShukantPal/nwvmh1L2/. It shows the demo.

To see the text without my "font-size adjustment", change the name of the TextWrapper#render method to something else (just add a letter to the front drender). This will make the text blurry again.

Silver-Streak commented 4 years ago

As it is another payperiod, I've bumped up the bounty on this again. https://www.bountysource.com/issues/89023609-changing-resolution-makes-text-objects-blurry-or-distorted

Thanks to SukantPal for all of their input. I'm hoping said input makes it easier for someone to implement.

ShukantPal commented 4 years ago

@Silver-Streak I'm actually ready to do this - I don't know how I'll test if it works locally. @4ian Any guidance to how you develop locally?

4ian commented 4 years ago

Start there: https://github.com/4ian/GDevelop/blob/master/newIDE/README.md :) Then I recommend to try the project uploaded by Silver-Streak to reproduce the issue and see what you can do.

Bouh commented 4 years ago

The balise canvas is stretch in the html directly, so even if you rescale the container and increase the fontSize the result is still blurry.

image

Note you need change the style.padding too if you don't do this the text is crop on top.

Text is still blurry, i've rescale by x4 the fontSize and downscale to 0.25 the text container. The font file used: Silver.zip

image

ShukantPal commented 4 years ago

@Bouh Hmm, I see. I believe your proposed solution is something like this: https://stackoverflow.com/a/15666143/6805653.

Get the device's pixel ratio, and then

new PIXI.Renderer({
      width: yourWidth * ratio,
      height: yourHeight * ratio,
      autoDensity: true
});
Bouh commented 4 years ago

Pixel ratio is still 1 for me. then it change nothing on my preview. autoDensity is only on pixi v5 so i use the current branch of @Quarkstar for test. If i understand correctly autoDensity allow to to pixi to resize the canvas size in CSS ? But the canvas is already resize at the dimension of the window.

For me the issue in at the root when the pixiRenderer is define, instead use the size from the setting of the game we should use the value of the window. Values of the game should the used only for set the size of the window. Tell me if i've lost you in my explaination ^^.

So here my new result.

image

ShukantPal commented 4 years ago

@Bouh You did kind of lose me there. Here is what I think you said :) - you used somebody's branch that had upgraded GDevelop's Pixi dependency to v5. The window size was set to the game's resolution & the canvas size was set to the window's dimensions. You used resolution: 1?

Bouh commented 4 years ago

My pixel ratio is always 1, resolution too 1.

The game can have options for set width and height for configure the window of the game. 800x600 by default. This value is used for configure the window (it's ok) and used at the rescale event of the window and used for redefine the pixiRenderer, but the value stay 800x600.

So the pixiRenderer comptue for a canvas of 800x600, and after the HTML canvas is rescale with CSS rules. If the quality of the renderer is smaller than the HTML canvas, it's logic for me know to have a poor quality result when we rescale the window is apply on the canvas.

(I try draw a cat on a paper A4, i wish my cat on a poster, if my quality is bad on my paper and rescale my image to poster dimension my beautiful draw loose in quality, it's better if a redraw my cat on the poster. I hope the analogy help ^^)

I try to understand how work this part of GD. But it's give me a good result with my technic. I've open a PR here. See the last commit. And you can try my new build of GD

This work on current master branch under pixi v4.8.6, and it can work also for next branch under pixi v5.

It's only on Text object not yet on BBtext.

Silver-Streak commented 4 years ago

I posted it in the PR, but to make sure it's not lost:

Bad news: This seems to still have scaling issues rather than changing font size, unless I'm misunderstanding:

Here's text at native resolution 1920x1080, font size: 72 image

Here's the window resolution changed to 1280x720, font size still 72 according to debugger: image

You can see it still becomes very distorted once I change the resolution.

(Also, this doesn't appear to fix blurriness on BBText, but I don't think we're trying for that currently)

Silver-Streak commented 4 years ago

Some more tests with this build: Game set to 1920x1080 resolution. Font: Gravity Pixel Font https://jotson.itch.io/gravity-pixel-font Font Size: 30

At 1080p (Native game resolution, click for full size): image

Window resized to 720p (click for full size): image

You can see in the word "PRESS" there is a lot of distortion on the S characters.

However, if I change the game resolution to native 720p (2/3 of 1080p) and change the font size to 20 (2/3 of size 30) No distortion on any character (click for full size): image

Here's the project files: FontResizeDistortion.zip

Silver-Streak commented 4 years ago

@Bouh and I have been talking through this on the discord, so I wanted to post these examples incase anyone else needs to see them, as the difference is noticeable but faint.

Here's 1080p native, zoomed in, with a 1x1 pixel grid. image

Notice that the center of each S is the exact same size, ~4 pixels

Here's that same window resized to 720p: image Notice that the top S and bottom S are not equal, among other differences.

So it seems like the font size scaling down isn't working properly, at minimum.

@SukantPal Also, Bouh's knee deep in bug hunting for the recent releases, so if you do want to take a crack at this, any help is appreciated. (Edit: To be clear, I mean if you want to take a crack at your own implementation, not necessarily what we're seeing with the build Bouh made. Or both. Honestly I'm just happy if we can get this solved. :D )

Bouh commented 4 years ago

Something is different between your screen and mine. Maybe the resolution or the pixel ratio like @SukantPal suggest. i guess it's why i can't see the difference with your screen. Because mine are different. I can't reproduce what you see, then i don't know how debug this, i'am very lost.

The electron menu made the mess, but because it's not present in exported game we should not take it in account. This menu reduce the canvas and affect the CSS size, so i've remove this menu in my preview. For remove this damn electron menu you can just export your game or use my new build below.

I use your project with more information for debug. htmlCanvasSize, cssCanvasSize, pixiRendererSize, pixiRendererResolution, devicePixelRatio, pixelRatioSize, gameSettingsSize, isFullscreen

advanced_debug_res_font.zip

On my screen 1920x1080, 144hz, with my build with fix and b92, without electron menu in preview:

n1

n2

n3

n4

For the n°4, if i resize to 1279x719, (1px below), the font is prefect! image

n5

n6

We can see when the CSS canvas size have decimals, the font is distorted. It's because electron menu is present and the window cannot be resized bigger than the screen resolution. What you think, how it is for you ?

Silver-Streak commented 4 years ago

Thanks Bouh. I'll check later today.

Silver-Streak commented 4 years ago

Hmm... I still get the electron menu in preview.

Also, after exporting the provided project using your build, this is what is shown after building it with electron-builder using yarn: image

Is something going weird with how it's handling game resolution now?

Even hitting T again to set it to 1080p does this: image

Bouh commented 4 years ago

Is something going weird with how it's handling game resolution now?

The weird resolution with decimals? You are not in fullscreen so the canvas is reduce by your title bar. Press F for set in fullscreen, and G for windowed.

It's a good news to see resolution to 1 everywhere.

Bouh commented 4 years ago

The build number is broken, but it's a custom build between b90 and b92 (it's a version similar to b92, but without the lastest commits about the profiler. I've just added the commit to fix electron. This change nothing for us here.)

You are still not in fullscreen and you have the electron menu. Press F, not F11, F will remove the electron menu, F11 don't.

Silver-Streak commented 4 years ago

Yep, I totally missed that. My apologies.

I'm now seeing significant improvement, although still some oddities.

Upscaling tests: Game resolution 1280x720, font size 24, 720p: image

Zoomed in: image

Game resolution 1280x720, font size 24, full screen (1080p): image

Zoomed in: image

Note, on the zoomed in view, I only marked the pure white pixels. It seems like there's some very bizarre sub pixel rendering/color blending happening still, but it is CONSIDERABLY better than the production build.

Downscaling tests:

Game resolution 1920x1080 (1.5x 1280x720), font size 32 (1.5x 1280x720), full screen: image

Zoomed in: image

Game resolution 1920x1080, font size 32, window rescaled to 720p: image

Zoomed in: image

Not sure what would impact the color blending like that. I think the most interesting thing is that the 1080p 32 font size scaled to 720p does NOT have the same color blending/subpixel rendering that the 720p 24 font size does.

Silver-Streak commented 4 years ago

Yeah, still something weird. I did some digging, and this font is designed for font sizes that are multiples of 5, not 8.

Downscale test: Game resolution 1080p, font size 30 full screen: image

zoomed in: image

Game resolution 1080p, font size 30, resized to 720p: image

Zoomed in: image

Notice that before resize, each S has a width of the line of 6 pixels. Since 720p is 2/3rds of 1080p, that should mean after resize to 720p, each S should be 4 pixels wide (2/3rds of 6). It is instead 3 pixels wide, with 2 pixels on each side of color blending/subpixel rendering.

Upscale test:

Game resolution 720p, font size 20 (2/3rd 30): image

Zoomed in: image

(Note, 4 pixels wide on the sides, so already different than the scaled down one above)

Game resolution 720p, font size 20, full screened (scaled up to 1080p): image

Zoomed in: image

Notice that the upscaled one goes from 4 pixels wide to 6 pixels wide. It seems like upscaling is working how I would think it should, but downscaling is being weird?

Silver-Streak commented 4 years ago

Just wanted to throw some updates on this as I've been testing with various fonts and seeing some really weird behaviors. We already know Silver.ttf (https://poppyworks.itch.io/silver) runs into issues once scaled, even with these updates.

Even though this font is heavily used in game development, I wanted to test with some other monospaced pixel fonts, so I've tried Monogram here: https://datagoblin.itch.io/monogram and m6x11 (https://managore.itch.io/m6x11).

They also don't do well with downscaling, and the distortion is heavily noticeable. Unfortunately, going to 1279x719 doesn't fix it for any of the above fonts.

Upscaling, again, is fine.

Bouh commented 4 years ago

The more I look for solutions, the problem gets worse. Under PixiV5

image

The black rectangle should be the text, it's black because WebGL: INVALID_VALUE: texImage2D: width or height out of range And it's normal because i change the fontSize x4, and the fontSize is 300. (300*4=1200) and i rescale the font to 0.25. But this is just the size for one letter, so if you make a sentence, the renderer for the texture will be huge! (~letters is your sentence x 1200 ), my renderer is 50k of width. And the WebGL dont want a huge renderer to calculate like that, so upscaling the font isn't a good solution ?

My best result for now, 1920x1080 resize to 1280x720, font:30 image Zoomed image

Silver-Streak commented 4 years ago

To be fair, font size 300 is already ridiculous. 😄

If you can, help me understand why are we rescaling the font size up then down? Wouldn't we just rescale the font size once per resolution?

(Game resolution 1080p, font size 30, game window resized to 720p (2/3rds 1080p), font size would then be scaled to 20 (2/3rds 720p)

Silver-Streak commented 4 years ago

Do we want to loop 4ian or SukantPal back in to see if we need to address this differently, or is this something where maybe it'd be beneficial to just have it as a toggle on game settings (Underneath the resolution settings) with a disclaimer "Very large font sizes such as 200+ may not render correctly"?

Silver-Streak commented 4 years ago

@SukantPal So @Bouh and I have been hammering away at this on the discord.

Unfortunately we can't seem to crack what the issue may be, the text distortion still happens one way or another. Do you still have time to take a crack at this?

ShukantPal commented 4 years ago

@Silver-Streak

"Since 720p is 2/3rds of 1080p, that should mean after resize to 720p, each S should be 4 pixels wide (2/3rds of 6). It is instead 3 pixels wide, with 2 pixels on each side of color blending/subpixel rendering."

This only applies when the the leftmost pixel is at a multiple of 6px. I think the problem here is that the "S" is not at a multiple of 6px position, so when you scale down, the position of the first pixel is not a whole number. For example, if the position of the first pixel mod 6 is 1px (so 1, 7, 13 is the position of "S"), then the new position after scaling down has a .33 or .66 in it. Since the position of the "S" is not a integer (after scaling down), it the first & last pixels don't entirely overlap with the "S" (hence are blended).

Did you try to moving the position of PRESS by 1, 2, 3, 4, 5 px (so there must be a multiple of 6px position)? I think that might give some insight.


P.S. Are you using a screenshot and zooming in for those pixel-level images?

Silver-Streak commented 4 years ago

For your last question: Yes. screenshot, zoomed in, pixel count.

As for your other question around positioning,, we've tried applying a "draggable" behavior to the text object, and you can watch it distort/become normal again as you move it around the canvas, yes.

Although the above screenshots are mostly focused around the subpixel rendering, that is only part of the concern, and less of a concern than the actual distortion we see on fonts.

Here's an example that shows the distortion more clearly: image

And it doesn't appear to be subpixel related as full pixels are being removed/added. This occurs more with more defined pixel fonts such as Monogram (https://datagoblin.itch.io/monogram) or Silver (https://poppyworks.itch.io/silver). Silver has been used in a ton of published games from other engines, and scale to different resolutions without issue.

The distortion we're seeing above does not happen in the codepen example from "Solution 1" at the top of this post either, so we're thinking it has to do with something being applied to the scaling methods.

Edit: Also, shouldn't Pixel Rounding stop the partial pixels (.33/.66) from occurring? because it doesn't seem to be applied (or at least not after a downscale)

Bouh commented 4 years ago

Edit: Also, shouldn't Pixel Rounding stop the partial pixels (.33/.66) from occurring? because it doesn't seem to be applied (or at least not after a downscale)

I wish add, even if these settings exist.