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

Add new Parallax2D node #87391

Merged
merged 1 commit into from
Mar 4, 2024

Conversation

markdibarry
Copy link
Contributor

@markdibarry markdibarry commented Jan 20, 2024

This is a new node, intended as a replacement for the current ParallaxBackground and ParallaxLayer workflow. In contrast to ParallaxBackground, Parallax2D inherits from Node2D, which provides a few benefits over the old workflow:

  • Automatic adhering to the current camera's transforms (rotation, zoom, etc)
  • Able to be modified and transformed with non-parallax textures
  • Compatibility with CanvasGroup
  • More performant
  • Flexibility to be used in or outside a CanvasLayer
  • Ability to override the number of repeats for zooming out or rotating the camera
  • Auto-scroll feature

The inspiration for this was a few pain points regarding the old workflow. There's still a lot to work on, as I'd like some community feedback and to add some more (reasonable) helpful features, but this is a good start with feature parity to the old system. I have a few ideas to fix some more issues, like handling zoom-out repeats, and some editor guides, but this is a nice beginning.

This should close quite a few old open issues:
Fixes: #22453, fixes: #30988, fixes: #39347, fixes: #42586, fixes: #67120, fixes: #77827
Possibly fixes: #63352, #71701, #82380, #87317

Also implements the following proposal:
Closes: godotengine/godot-proposals#8779,
Closes: godotengine/godot-proposals#8107,
Closes: godotengine/godot-proposals#7237

Obviously, this is too much of a breaking change to flat out remove the old workflow, but with this the ParallaxBackground and ParallaxLayer nodes can be deprecated for removal in a later version. In the meantime, I was able to retrofit the new changes for mirroring into ParallaxBackground, so users who aren't ready for a change can still benefit from a speed up. Here is my cursory benchmarks:

2500-2600 FPS: ParallaxBackground with 8 ParallaxLayers while scrolling (master branch)
4100-4200 FPS: ParallaxBackground with 8 ParallaxLayers while scrolling (Parallax2D branch)
4400-4500 FPS: 8 Parallax2Ds while scrolling
4900-5000 FPS: Empty scene

2024-01-19.22-01-46.mp4

Here it is working in a CanvasGroup:

2024-01-19.22-06-14.mp4

Also thanks to our neighborhood svg wizard @MewPurPur for the quick work on an alternative icon!

Any and all feedback is welcome!

@markdibarry
Copy link
Contributor Author

markdibarry commented Jan 20, 2024

I just started with a feature to add number of repeats. This is to address the issue some users face when zooming out on an infinite repeat background since it only draws twice per.

The performance isn't bad. Even with 8 layers with 5 repeats (36 copies per item per layer), it still performs better than ParallaxBackground on master, but obviously it's not free or infinite. You'd still need to update it when you're zooming out, but this at least provides an avenue for those who need it. That being said, you could also just set your texture to repeat and make it large enough for the size of your screen zoomed out. Either way, there should be a note about performance when doing this with a large number of large textures.

Before:

2024-01-20.13-56-18.mp4

After:

2024-01-20.13-57-15.mp4

@markdibarry markdibarry force-pushed the new_node_parallax_2d branch 2 times, most recently from a7bd784 to 47aa23d Compare January 21, 2024 22:29
@markdibarry
Copy link
Contributor Author

Also added a highly requested autoscroll feature, since it doesn't affect much and was easy enough to implement. I think that's all I want to start with, so I'm gonna open this up for review. I think it'd be great to have some editor guides, but I think we should have a discussion on what that should look like, since parallax is hard to visualize, and too much going on may cause more confusion than help.

2024-01-21.17-58-32.mp4

@markdibarry markdibarry marked this pull request as ready for review January 21, 2024 23:06
@markdibarry markdibarry requested review from a team as code owners January 21, 2024 23:06
@tartley
Copy link

tartley commented Jan 22, 2024

Dumb question from the peanut gallery: Would this branch work for parallax of Nodes which draw themselves using 'draw_polygon' commands and the like? Or just for textures? Thanks for unpacking.

@markdibarry
Copy link
Contributor Author

@AThousandShips Thanks for the quick review! A lot of stuff I overlooked while having a million tabs open.

@tartley Absolutely!
image

@enderprism
Copy link

i can't wait for this to get merged! i actually need this a lot for my game, i'd be glad to know if there was a way i could use it right ahead.

@markdibarry
Copy link
Contributor Author

@enderprism You can go to the "Checks" tab and download one of the build artifacts. I'd wait for it to be merged before using it for anything serious, since it hasn't been approved yet. If you would be willing to try it out and tell me if there's any issues or things I've overlooked, it would help out a lot!

@Mickeon Mickeon self-requested a review January 27, 2024 13:27
@akien-mga akien-mga modified the milestones: 4.x, 4.3 Mar 4, 2024
@akien-mga akien-mga merged commit 1a9c0ee into godotengine:master Mar 4, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks! Amazing work 🎉

@arkology
Copy link
Contributor

arkology commented Mar 4, 2024

Hooray, we will see this in next dev version🥳 Thanks a lot!
Idk why but I thought it was already in master in 4.3dev4😄

@Araraura
Copy link
Contributor

Saw this in the 4.3 dev 5 changelog and tried playing around with it a little bit. I was wondering if it's possible to preview the parallaxing in the editor in the same way ParallaxBackground allows you? (This is done by changing the scaling under "follow viewport" and enabling "preview canvas scale" in the editor)

@cody82
Copy link
Contributor

cody82 commented Mar 15, 2024

The Parallax2D does not work correctly with multiple cameras/viewports. In one viewport I can see the background move correctly when the camera moves, but on the other viewport where the camera does not move, the background still moves.
Is this intended or a bug?

@AThousandShips
Copy link
Member

AThousandShips commented Mar 15, 2024

The Parallax2D does not work correctly with multiple cameras/viewports.

See the instructions here

@markdibarry
Copy link
Contributor Author

@Araraura I tried this with ParallaxBackground and wasn't able to get consistent results while previewing in the editor. It's a bit of a hack in the first place, but I'm exploring having a formal way to preview stuff in the editor. On the bright side, the offset and other settings are reflected in the editor where ParallaxBackground didn't.

@cody82 I'm currently finishing a blog post touching on some of these topics. Some of the same drawbacks to ParallaxBackground still unfortunately applies to Parallax2D. Multiple cameras/viewports are tricky, since the textures are moving across the screen determined by the current camera for the layer (or manually scrolled) just like how ParallaxBackground handled it. For split-screen or multiple worlds, you'd still need to clone the Parallax2D for each viewport, since otherwise, it'd have no idea which camera should move the textures!

@filkata
Copy link

filkata commented Mar 15, 2024

I experience broken behavior on 4.3 dev5 when using the old ParallaxBackground, I have tried to strip down my project to illustrate the issue.
BgBug.zip
The idea is to have an infinitely scrolling background with 2 layers that follow the camera at different scales. Clicking and dragging moves the camera around, mouse wheels zooms in and out. This works fine on 4.2 but on 4.3 dev5 there are issues when zooming- one or both layers will not show.

Also I have so far sound it hard to replicate this behavior using the new node, I will likely have more time to elaborate tomorrow, Thanks for your time!

@markdibarry
Copy link
Contributor Author

markdibarry commented Mar 15, 2024

@filkata Your zip file is being flagged and won't let me download it. Not sure why. If you can fix it I'll take a look. Though I'm glad that the problem is with ParallaxBackground and not Parallax2D, that def shouldn't be the case! I'll get right on it!

@filkata
Copy link

filkata commented Mar 15, 2024

@markdibarry Still I think a regression in the behavior of ParallaxBackground is not ok. Please try this link instead: https://drive.google.com/file/d/1MSKnS9JGnw3KpCmLP5y3ZU3LpNYPdS2i/view?usp=sharing

@Mickeon
Copy link
Contributor

Mickeon commented Mar 15, 2024

@filkata Please open a separate issue about this as it makes it much easier to track and troubleshoot.

@filkata
Copy link

filkata commented Mar 16, 2024

Opened #89563

@ettiSurreal
Copy link
Contributor

Trying it out in 4.3dev5, works great from my initial testing.
My main gripe is that it uses top left of the screen instead of the center, I think there should be a toggle to use the screen center, and maybe let you input a custom center value (should have both, as the former would go towards the center no matter the resolution).

Also not sure if this is in scope of the node, but maybe a sort of "perspective mode" could be nice to have? Basically, multiply the offset by the scroll scale. So with lower scroll scale, the object slowly goes towards the center, which can create a "building from above" effect. For this the toggle above could be important as it would let you input a custom center point. This is relatively easy to make yourself (so I left some code below), but it could be nice to have as a built-in feature.

Example and Code

image
image
image

extends Node2D

@export var scroll_scale: Vector2 = Vector2.ONE
@export var scroll_offset: Vector2 = Vector2.ZERO
@onready var original_position: Vector2 = global_position
@onready var camera: Camera2D = get_viewport().get_camera_2d()

func _process(delta):
	global_position.x = lerp(camera.get_screen_center_position().x + scroll_offset.x, original_position.x, scroll_scale.x)
	global_position.x = lerp(camera.get_screen_center_position().y + scroll_offset.y, original_position.y, scroll_scale.y)

Also I found documentation bug, Less than 1 scrolls slower, making object appear *closer* should be "further".

@markdibarry markdibarry deleted the new_node_parallax_2d branch March 16, 2024 19:22
@markdibarry
Copy link
Contributor Author

@ettiSurreal I appreciate the feedback! This initial PR is mainly focused on being able to replicate the behavior of ParallaxBackground but in a friendlier format. It's awesome to see others interested in improving the usability and features of the new node and it's designed specifically to be built on top of. I'd encourage you to open a proposal for some of your ideas and how to implement them, so it can get some more visibility and interest!

@Braveo
Copy link

Braveo commented Mar 19, 2024

Testing works great as well for me on 4.3dev5. I haven't had any issues.

Also not sure if this is in scope of the node, but maybe a sort of "perspective mode" could be nice to have? Basically, multiply the offset by the scroll scale. So with lower scroll scale, the object slowly goes towards the center, which can create a "building from above" effect. For this the toggle above could be important as it would let you input a custom center point. This is relatively easy to make yourself (so I left some code below), but it could be nice to have as a built-in feature.

I also want to add to this and ask if we can have an option to scale objects according to perspective scale as well? So we can have objects appear smaller as their distance is further away.

And on top of that, an equivalent to "Preview Canvas Scale" but for this instead, since we can't really preview the parallax effect in editor like we could with ParallaxBackground. This is mainly so we can preview the background as a pseudo-3D space. I'm not sure how much work that is, but it'd be nice to have, and is one big feature I feel is missing in this one.

@markdibarry
Copy link
Contributor Author

markdibarry commented Mar 19, 2024

@Braveo This is some great feedback as well. This is a closed PR, and it'd be a shame for your findings to be ignored, so it'd be great if you could create a proposal or issue!

While I'm here, though, I've heard the technique you mentioned once or twice, but I haven't found any official documentation on this (just a few random comments from users on forums). I also tried replicating it using ParallaxBackground, but it was kinda buggy and inconsistent. Of course, I think it'd be much preferred if we could come up with a solution that's officially supported rather than a hack that just happens to work sometimes! I know KoBeWi made a great custom node that supports editor perspective before I even started work on this PR, but they couldn't use ParallaxBackground since it was a CanvasLayer, so maybe they'd have an easier time now integrating it. I'd also be happy to champion anyone who'd be interested in making an editor tool. Parallax is hard to visualize, and what I found during my discovery period was that what made sense for one person didn't make sense for another, so having a bunch of guides and different ways to view it would be really cool!

EDIT: I was able to get similar results by just putting the Parallax2D node in a CanvasLayer. That, of course, enforces both size scale and scroll scale, but you now have access to repeat_times if you didn't prepare the image for resizing ahead of time. This way you can have both infinite scroll and scaling.

@KoBeWi
Copy link
Member

KoBeWi commented Mar 20, 2024

I know godotengine/godot-proposals#8779 (comment) that supports editor perspective before I even started work on this PR

btw I managed to recreate more or less the same thing using Parallax2D (it's easy using screen_offset, the tricky part is setting up the preview area to look like in-game), but I also want to figure out how to make it editable while previewing.

@DrCanvas
Copy link

It's probably too late. But this guy made a plugin to preview parallax in the editor. I don't know if it can be replicated in the new system.

@AThousandShips
Copy link
Member

AThousandShips commented Mar 23, 2024

That'd be up to the developer of that plugin to adjust to, if it's even needed, but that wouldn't really change the decision or progress of this PR, you should probably talk to them about this instead

@adamscott
Copy link
Member

While I'm here, though, I've heard the technique you mentioned once or twice, but I haven't found any official documentation on this (just a few random comments from users on forums).

I think this is the only "official" mention: https://godotengine.org/article/godot-32-will-get-pseudo-3d-support-2d-engine/

@killwecan
Copy link

God damn genius! This will be awesome!

@FrederickKDP
Copy link

Hey, just because it was asked, and I'm current working with Parallax in my project. It was a huge problem for me working with parallax and split screen. Reason being, because parallax inherits from canvas layer, it makes its contents to be dependant on the viewport.
The old implementation from my understanding requires the content of the canvas layer to be duplicated for each view. If there's any element that should be synchronize, that can easily turn into a nightmare. So my solution for now was to not use parallax layers at all, instead, using an intricate setup of viewports and cameras. It is cumbersome, but does the job, so I only have to worry about background objects in one place.
Since the new system is moving away from canvas layers to node2d, I assume it's possible that the problem doesn't exist anymore. Each new parallax layer is displaced according to the camera position as expected, I hope. If split screens are a factor to be considered at all, I find to be worth testing this.

@markdibarry
Copy link
Contributor Author

markdibarry commented Jul 3, 2024

@FrederickKDP Thanks for the interest! This PR is closed, so it'd be best to open a discussion regarding this. Feel free to tag me, since I'm currently looking at good ways to accomplish split screen easily! In the meantime, please take a look at this proposal to make this easier. godotengine/godot-proposals#10014

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