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

[Suggestion] Allow for more background transitions out of the box #1826

Closed
Pheubel opened this issue Oct 24, 2023 · 4 comments
Closed

[Suggestion] Allow for more background transitions out of the box #1826

Pheubel opened this issue Oct 24, 2023 · 4 comments
Labels

Comments

@Pheubel
Copy link
Contributor

Pheubel commented Oct 24, 2023

Is your feature request related to a problem? Please describe.
During a visual novel it is common to change the background to go to a different "scene", to make those background changes feel nicer transitions are used. However in dialogic it seems that the only options are either a hard cut to the next background or a fade. It would be nice if it was possible to create your own transitions in order to create a more diverse experience while switching backgrounds. examples include:

  • non linear fades (like a sudden flash to white to show a heart racing event)
  • pattern based transitions to fit the theme of a game (for example a game with cats could have paw prints covering the original BG)
  • a melt fade to creep out the player
  • etc.

Additionally the current background fade seems to have a small issue where the background can become noticably darker during a quick fade between two almost identical BG's.

Describe the solution you'd like
I think a nice way to give power into the developer's hand would be to allow shader materials to be passed to the background event. These shader materials would have 3 parameters in common:

  • progress (this would be a float between 0 and 1)
  • previousBackground (this would be a background set by a previous background event. not always assigned, for example at the start or after a clear with backgrounds turned on)
  • nextBackground (this would be the background that is being assigned in the current background event)

When a background event happens, it would make use of the fade time to get the current progress. It sets the previous and next background parameters and from there the mechanism that currently handles fades between background can most likely be used to update the progress.

If a developer wants to create their own transition they can create a shader that has those parameters and even other parameters. Inside of the fragment function they can then decide how the transition should behave and they can tweak settings inside a shader material that they then pass to the background event. if no shader material is passed, it could fall back on a default shader material that does a fade like the current fade between background events.

This way the transitions become fairly plug & play and can easily be shared.

an example of how one of these transition shaders could look would be like so:

shader_type canvas_item;

uniform float progress : hint_range(0.0, 1.0);
uniform sampler2D previousBackground : source_color, hint_default_transparent;
uniform sampler2D nextBackground : source_color, hint_default_transparent;

uniform float diamondPixelSize = 10.;

void fragment() {
	float xFraction = fract(FRAGCOORD.x / diamondPixelSize);
	float yFraction = fract(FRAGCOORD.y / diamondPixelSize);
	
	float xDistance = abs(xFraction - 0.5);
	float yDistance = abs(yFraction - 0.5);
	
	bool check = xDistance + yDistance < progress;
	
	vec4 color = texture(screenTexture, UV) * float(!check);
	color += texture(transitionTexture, UV) * float(check);
	
	COLOR = color;
}

The resulting shader material would look like this
image
as mentioned earlier, progress, Previous Background and Next Background would be handled automatically by Dialogic's background event. But I as a developer can tweak the size of Diamond Pixel Size in the inspector until I find that it fits my needs.

After setting the Diamond Pixel Size to 50, it looks something like this

demo

Describe alternatives you've considered
The alternative would be to create an extension module for this, but it would not have the same reach as compared to a built in feature. It could allow for people to share their transitions with each other without having to worry about different implementations that can differ in standards.

Another alternative would be to create your own scene and pass that to the background event, but this would require writing in gdscript and doesn't have the same image processing power as a shader running on a GPU.

@Jowan-Spooner
Copy link
Collaborator

Thanks for the issue!
I agree with the problem (it should be easy to provide different transitions, even using the same scene).
I'm not too sure about the solution though.

What we have right now

You can already achieve different transitions by creating a custom background scene and overwriting _fade_in() and _fade_out().

This means you could have a shader setup on your custom scene and tween the progress in those methods. It's not perfect though, I agree as it
A) requires setting up the custom scene (we could provide such an example though) and
B) hardly allows different transitions on the same scene.

Your solution

While shaders can create quite cool transitions, they are not very beginner friendly at all. They are also a bit limiting as they only allow image-backgrounds (which to be fair the default background does too). But custom backgrounds can be made of different (possibly animated) objects. For those you might want to use very different ways of animating/fading them.

I will think about different solutions to this a bit more.

@Pheubel
Copy link
Contributor Author

Pheubel commented Oct 24, 2023

While shaders can create quite cool transitions, they are not very beginner friendly at all. They are also a bit limiting as they only allow image-backgrounds (which to be fair the default background does too). But custom backgrounds can be made of different (possibly animated) objects. For those you might want to use very different ways of animating/fading them.

I agree that shaders are definitely not the easiest to learn and use, i do think that they can be more useful than you might expect. Scenes that have animations in them, you could probs makes use of a viewport's texture as one of the inputs. that could at least alleviate that bit of pain.

If shaders indeed become usable for background changes, i think it would be no harm in providing some out of the box materials to use, i think that it would cover a majority of the people's needs and give enough examples for those that aren't satisfied with what you can get out of the box.

I don't think they should be excluded because they are a more advanced topic, but if they are included it should definetely be in a way that makes them easy to interact with.

@Pheubel
Copy link
Contributor Author

Pheubel commented Oct 25, 2023

Another option that would handle a large set of use cases would be that instead of passing a shader material to the background event, the background event would be passed a transition texture to dictate how it will transition and a feather value to smear the transition a bit.

this would remove the complexity of having to know how to use shaders all the way down to "the whiter it is, the later it goes away" and "should it be a hard cut or should it be speared out a bit". This shader is actually not hard to make, assuming the same rules from my original proposal.

here's a rough draft of how it would look:

shader_type canvas_item;

uniform float progress : hint_range(0.0, 1.0);
uniform sampler2D previousBackground : source_color, hint_default_transparent;
uniform sampler2D nextBackground : source_color, hint_default_transparent;

uniform sampler2D whipeTexture : source_color;
uniform float feather = 0.1;

void fragment() {
	vec4 prevColor = texture(previousBackground, UV);
	vec4 nextColor = texture(nextBackground, UV);
	
	float whipeAlpha = (texture(whipeTexture, UV).r) - progress;
	
	float whipeBlend = smoothstep(0., feather, whipeAlpha + (feather * (1. -progress)));
	
	COLOR = mix(nextColor, prevColor, whipeBlend);
}

(this draft assumes a 1:1 aspect ratio for simplicity sake)

As an example, using the following grayscale image:
8ea2407d312cda1ca82f4b26a3c1c7d6
It would produce a transition like this:
ezgif-2-93926cfa1f

I think this would be a good intermediate solution to add a nice bit of charm to the background transitions as the barrier of entry is quite low.

But considering the systems that are in place, what would be the best way forwards in terms of passing arguments with the
background event, considering that some people want to implement their own scene for backgrounds, they might want to implement their own solution and ignore the values passed through to the background event. As said earlier, these user made scenes have their own limitations due to them being fairly set & done with how you structure them. I don't know how feasible it would be, but if you were able to dynamically build the arguments and pass them to the custom scene, then that would be a powerful feature that allows custom made scenes to be more modular.

@Pheubel
Copy link
Contributor Author

Pheubel commented Oct 27, 2023

I forgot to mention, but this might also be useful for the clear event, as it removed the background as well, useful for when you want to transition back into the scene (for example you are in a city and are done with an exposition dump by an NPC)

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

No branches or pull requests

2 participants