Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.86.0] Gaps/lines between the images on camera move #6927

Open
Asphiii opened this issue Oct 21, 2024 · 19 comments
Open

[3.86.0] Gaps/lines between the images on camera move #6927

Asphiii opened this issue Oct 21, 2024 · 19 comments
Assignees

Comments

@Asphiii
Copy link

Asphiii commented Oct 21, 2024

Version

3.86.0

Operating system

Windows 11, Google Chrome 129.0.6668.101

Description

If you place four graphics next to each other, a visible line will appear between them. Something similar happened to me on 3.85.X, but it was always visible on specific camera zoom. This time it appears on camera moving; there is a position when it is not visible. Changing "pixel perfect" in the config doesn't change anything. This is a regression bug; the last stable version is 3.80.1.

Expected behaviour

There's no gaps between the images

Example Test Code

backgroundImages.forEach(image => { const bgImage = this.add.image(image.x, image.y, image.key); bgImage.setDisplaySize(image.displayWidth, image.displayHeight); if (image.origin) { bgImage.setOrigin(image.origin.x, image.origin.y); } });
phaser_bugless_0
phaser_bug_1

@yemtelazer
Copy link

This is still an issue. We were using 3.85.1. Had that exact same issue, random lines.

For some reason it ignores the tile front and displaying the color at bg.

Saw the similar issue has been resolved at the 3.86 and upper. We upgraded the version to 3.87.0.

Still having this. I hope this will resolved immadietely/

@yemtelazer
Copy link

One quick note for @photonstorm . This issue only reproducing when we have Camera.setBounds() method used.

If there is no bounds set to camera. Everything works smoothly (In our case). But whenever a bound set, it is starting to appearing

@photonstorm
Copy link
Collaborator

@yemtelazer you need to provide a test case, with assets, that clearly demonstrates what is happening, because we cannot replicate this as it stands.

@yemtelazer
Copy link

Trying to create a case in sandbox, it is really hard to reproduce. Dont know the exact cause. Will post link here once I achieve

@photonstorm
Copy link
Collaborator

Ok. Let's keep this issue open until you've found a way to demonstrate it (because we struggled, too).

@yemtelazer
Copy link

@photonstorm

Cool that I have a reproducable sandbox code now here.

I think its good enough for you to understand the issue we are having here.

The test case covers one issue, I hope there are no more things to resolve. I hope that everything we are facing here is sharing the same root cause.

I am going to provide a video, files (for some reason my public files are not loading in incognito mode) and the sandbox link so you can fork if you want.

In 4.0.0 beta.x this is issue seems resolved (at least this test case is not reproducing), but still there are tons of games using 3.x.x versions. I think it would be a good update to have it on version 3.x.x.

Sandbox link
https://phaser.io/sandbox/SHjvmLgG

Uploaded video
https://youtu.be/CZjG2Uax5Tg

Source Files
Image
hub.json

@yemtelazer
Copy link

@photonstorm Did you have some time to look at test case?

@yemtelazer
Copy link

@photonstorm ping :)

@yemtelazer
Copy link

@zekeatchan adding you to the loop :) Can you reach out to @photonstorm ?

@yemtelazer
Copy link

Currently this link is up to date

https://phaser.io/sandbox/SHjvmLgG

@zekeatchan
Copy link
Collaborator

@zekeatchan adding you to the loop :) Can you reach out to @photonstorm ?

Hi @yemtelazer, thanks for the test case. I'll have a look.

@zekeatchan zekeatchan self-assigned this Feb 6, 2025
@zekeatchan
Copy link
Collaborator

Hi @yemtelazer, it seems you're facing this issue with tile maps? The common solution is to create an extruded tileset.

Here are some links that may help resolve this:
https://github.com/sporadic-labs/tile-extruder
https://discord.com/channels/244245946873937922/1329245755181105195
https://www.youtube.com/watch?v=4E-Bl8i5sto

@Asphiii
Copy link
Author

Asphiii commented Feb 11, 2025

Hi @yemtelazer, it seems you're facing this issue with tile maps? The common solution is to create an extruded tileset.

in my case, these are normal images placed next to each other and it works perfectly fine up to and including version 3.80.1. Should I make a reproduction of these two versions; a working and broken one?

@zekeatchan
Copy link
Collaborator

Hi @yemtelazer, it seems you're facing this issue with tile maps? The common solution is to create an extruded tileset.

in my case, these are normal images placed next to each other and it works perfectly fine up to and including version 3.80.1. Should I make a reproduction of these two versions; a working and broken one?

Yes, that would be helpful. Best is to create a sandbox example in the phaser site for us to have a look.

@yemtelazer
Copy link

@zekeatchan Thanks for the reply. My tileset was fine there were no pixel errors. But in any case I tried to extrude. Issue is still exist on my end. Nothing much changed

@yemtelazer
Copy link

Also I know that this is not extrude issue, I know the examples of that non-extruded tileset issues. This is something different.

@Asphiii
Copy link
Author

Asphiii commented Feb 12, 2025

ok give me some time - I will create repo in my free time

@Asphiii
Copy link
Author

Asphiii commented Feb 16, 2025

So I can't reproduce this issue on the assets from Phaser CDN, but I can do it in the project, forcing me to check if my images are cut correctly. At first glance, it looks okay, but I will double-check it.

https://phaser.io/sandbox/iVCdAJfq
Paste this code:

class Example extends Phaser.Scene {
    constructor() {
        super();
    }

    preload() {
        this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
        this.load.image('pic', 'assets/pics/a-new-link-to-the-past-by-ptimm.jpg');
    }

    create() {
        this.worldWidth = 3200;
        this.worldHeight = 2400;

        this.cameras.main.setBackgroundColor(0xff00ff);

        this.background = this.add.container(0, 0);

        // correct positions
        // const tiles = [
        //     { x: 0, y: 0 }, { x: 1067, y: 0 }, { x: 2134, y: 0 },
        //     { x: 0, y: 1500 }, { x: 1067, y: 1500 }, { x: 2134, y: 1500 }
        // ];

        // incorrect positions
        const tiles = [
            { x: 0, y: 0 }, { x: 1068, y: 0 }, { x: 2136, y: 0 },
            { x: 0, y: 1501 }, { x: 1068, y: 1501 }, { x: 2136, y: 1501 }
        ];

        tiles.forEach(tilePos => {
            let tile = this.add.image(tilePos.x, tilePos.y, 'pic');
            tile.setOrigin(0, 0);
            tile.displayWidth = 1067;
            tile.displayHeight = 1500;
            this.background.add(tile);
        });

        this.cameras.main.setBounds(0, 0, this.worldWidth, this.worldHeight);

        this.isDragging = false;
        this.startX = 0;
        this.startY = 0;

        this.input.on('pointerdown', (pointer) => {
            if (pointer.leftButtonDown()) {
                this.isDragging = true;
                this.startX = pointer.x;
                this.startY = pointer.y;
            }
        });

        this.input.on('pointermove', (pointer) => {
            if (this.isDragging) {
                let deltaX = (this.startX - pointer.x) / this.cameras.main.zoom;
                let deltaY = (this.startY - pointer.y) / this.cameras.main.zoom;
                this.cameras.main.scrollX += deltaX;
                this.cameras.main.scrollY += deltaY;
                this.startX = pointer.x;
                this.startY = pointer.y;
            }
        });

        this.input.on('pointerup', () => {
            this.isDragging = false;
        });

        this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
            const camera = this.cameras.main;
            const zoomSpeed = 0.001;
            let targetZoom = camera.zoom - camera.zoom * zoomSpeed * deltaY;

            targetZoom = Phaser.Math.Clamp(targetZoom, 0.5, 3);

            const worldPoint = camera.getWorldPoint(pointer.x, pointer.y);

            this.tweens.add({
                targets: camera,
                zoom: targetZoom,
                duration: 150,
                ease: 'Sine.easeInOut',
                onUpdate: () => {
                    const newWorldPoint = camera.getWorldPoint(pointer.x, pointer.y);

                    camera.scrollX -= newWorldPoint.x - worldPoint.x;
                    camera.scrollY -= newWorldPoint.y - worldPoint.y;

                    camera.scrollX = Phaser.Math.Clamp(camera.scrollX, 0, this.worldWidth - camera.width / camera.zoom);
                    camera.scrollY = Phaser.Math.Clamp(camera.scrollY, 0, this.worldHeight - camera.height / camera.zoom);
                }
            });
        });
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example,
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
    }
};

const game = new Phaser.Game(config);

There are two arrays of tiles; I'm using the correct one.

I noticed that version 3.80.1 works completely differently than 3.86.0. If you pick an older version, zoom in/out, and move a map you will notice, that sometimes these "gaps" are hidden. On 3.86.0 they're always visible, lighter or darker, but still visible. Maybe I always had a badly cut version of images, but it worked because of different color blending? It's more visible in some colors(like blue, and light green), so maybe that's the issue.

I will double-check my images and tell you the result.

@urueda
Copy link

urueda commented Feb 18, 2025

Let me provide some light, hope not confusion, to the issue.

In my case, I found a workaround to tackle those kind of ugly artefacts (lines) as camera did zoom and/or pan.
Just a matter of playing with pixel-art and roundPixels. It did work perfect @ Phaser 3.70.0, til upgraded to Phaser 3.87
Trying to fix the line artefacts went into a nightmare w/out success. I had to make another workaround, now more like a design decision than a fix.

In the process of fix attempts (with and w/out pixel-art, roundPixels) I spot a potential reason through Phaser changelogs:

BaseCamera.renderRoundPixels is a new read-only property that is set during the Camera preRender method every frame. It is true if the Camera is set to render round pixels and the zoom values are integers, otherwise it is false. This is then fed into the MultiPipeline when rendering sprites and textures

Might Phaser code changes around rounding pixels @ 3.85 and @ 3.86 provide hints for resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants