jdotrjs / phaser3-nineslice

A Nineslice plugin for Phaser 3
Other
108 stars 28 forks source link

Resizing causes text to render weirdly #16

Open Secretmapper opened 5 years ago

Secretmapper commented 5 years ago

Edit from @jdotrjs From a comment it looks like this is a phaser bug but there seems to be a work around included in the link.

Hello!

I joined Ludum Dare 43 this weekend and used this excellent library.

I kept encountering a REALLY weird bug in my game where text was rendering 'mushy':

screen shot 2018-12-04 at 5 32 32 pm screen shot 2018-12-04 at 5 32 09 pm

At first I actually thought this was a bug in phaser. It was really hard to diagnose, but I isolated it enough to realize that the bug is caused by resizing.

Here is an example:

Resizing sample: http://disturbed-crush.surge.sh

Not Resizing: http://zealous-game.surge.sh

As you can see, in the one where the window is resizing, the text gets 'mushy'.

Sample:

import 'phaser';
import { Plugin as NineSlicePlugin } from 'phaser3-nineslice'
import WebFont from 'webfontloader'

var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
  plugins: {
    global: [ NineSlicePlugin.DefaultCfg ],
  },
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

let text
function preload ()
{
    this.load.image('tile', 'assets/tile.png');
    WebFont.load({
      custom: {
        families: [ 'Kremlin' ]
      },
      active: () => {
          console.log('krem')
        text = this.add.text(
            32,
            32,
            'Hello', 
          { font: '20px Kremlin', fill: 'white' }
        )
      }
    });
}

function create ()
{
    this.dlg = this.add.nineslice(
      110, 110,   // this is the starting x/y location
      340, 240,   // the width and height of your object
      'tile', // a key to an already loaded image
      12,         // the width and height to offset for a corner slice
    )
    let i = 50
    setInterval(() => {
        i+= 1
        // this.dlg.resize(i, 50)
        text.setText(i)
    }, 100)

}
jdotrjs commented 5 years ago

My only theory right now is that the text is getting drawn to the same underlying canvas and stretched when the dialog is resized so that the text redraw produces the blur. Off the top of my head I don't have a good reason that redrawing the center would not clear the existing content though...

Oh, this is absurd - the blurry text isn't even in the area that should be being drawn by the plugin :rofl:.

I know this is a month old and all (and sorry for the delay*) but it's going to be weirder than I expected.

* For those playing along at home I chatted with OP in discord and this wasn't any kind of blocking/pressing issue

mudala commented 5 years ago

@jdotrjs @Secretmapper

I was looking in to this, and on a whim tried removing the call to clear the RenderTexture here: https://github.com/jdotrjs/phaser3-nineslice/blob/c5ca67dd556bbbcf8b3e176c7ad7cb16304c3057/src/NineSlice.js#L299

This fixed the text rendering for me. I figured this would be okay because RenderTexture.resize does an implicit clear according to: https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.RenderTexture.html#resize__anchor.

Does this fix it for either of you? I can submit a pull request that adds a skipClear parameter to drawFrames, and when it's set to true (during resize) it will skip clearing the RenderTexture.

jdotrjs commented 5 years ago

@mudala huh. nice find; I'm a bit confused why this works but if you want to go ahead and submit a PR I'll merge and do a release ~this weekend.

Thanks for looking into this! I had been dreading it for a while 😛

mudala commented 5 years ago

@jdotrjs Bad news. I went back and checked today and realized this actually doesn't fix it! I spoke too soon. 🙁

However, I did notice that the text rendering looks good if you use Phaser v3.14.0 and below! But, it breaks with versions greater than 3.15.0.

It looks like there was some work done in Phaser 3.15.0 on texture rendering (https://github.com/photonstorm/phaser/releases/tag/v3.15.0), so this might be where things broke. In particular:

Texture batching during the batch flush has been implemented in the TextureTintPipeline which resolves the issues of very low frame rates, especially on iOS devices, when using non-batched textures such as those used by Text or TileSprites. Fix #4110 #4086 (thanks ivanpopelyshev sachinhosmani maximtsai alexeymolchan)

and

The WebGLRenderer method canvasToTexture has a new optional argument noRepeat which will stop it from using gl.REPEAT entirely. This is now used by the Text object to avoid it potentially switching between a REPEAT and CLAMP texture, causing texture black-outs (thanks ivanpopelyshev)

For now, in my own project, I'm omitting the RenderTexture and using a Container to position the 9 frames, which does work. Less efficient for some transformations but in my case those objects are mostly static.

I'll look in to it more when I have time and update you if I find anything.

michelwacker commented 5 years ago

Hey @mudala and @jdotrjs, having the same issue with Phaser 3.16.2 and managed to find a workaround:

With me, it happens when I a) create a 9-slice with add or make or b) resize a 9-slice. After a couple of hours of debugging and reading the above I accidentally ran into the workaround:

If you create a text field after the creation/resize the glitch does not appear. You don't have to add that textfield and can destroy it right away. Creates a bit of garbage but at least solves the issue until a solid solution is at hand. Maybe that even hints to the source of the problem?

Thought I'll let you guys know.

ivanpopelyshev commented 5 years ago

Yo guys! You've tagged me here . Its fine and I'd like to know more about the issue, but watch out for those quotations next time to not to summon some demons ;)

tomwilsn commented 4 years ago

Did anyone ever solve this properly?

Creating a random text object after resizing is working for me but its a bit gross

michelwacker commented 4 years ago

That’s how we’ve been doing it last year. I never checked back since.

Am 03.06.2020 um 05:56 schrieb Tom Wilson notifications@github.com:

Did anyone ever solve this properly?

Creating a random text object after resizing is working for me but its a bit gross

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

JstnPwll commented 4 years ago

This is actually a Phaser core issue, not a problem with this plugin. See this comment on the Phaser repo which fixed it for me: https://github.com/photonstorm/phaser/issues/5064#issuecomment-646183833