This repository contains the research assignement subject of the Project II by Marc Guillén Saltó, student of Videogame's Degrees at CITM
In films or videos, camera transitions are a post-production technique used to connect one shot with another. Simple enough, but what about video games?
Although the purpose is practically the same. In videogames, camera transitions won’t be a post-production technique, but a slice of code being executed seconds before - while - and after a scene change.
A camera transition can also be a smooth movement of the camera through the scene, without the need for a scene change.
Why don’t we use just a basic cut where one scene is instantly replaced by the next one?
In cinema, there’s no problem using a basic cut, because there are no existing delays or freezes between the scene change. So filmmakers use complex or more artistic transitions most commonly to spice up the narrative or move backward or forward in time.
While in video games, when we change a scene, the game unloads the current scene and loads the entering scene information, making the game even freeze for a small period of time. So if we don’t use any transition to ‘hide’ that procces, the scene change will look really sketchy, poor or like a bug. Camera transitions are useful to tell the player; “ok, we are moving into another place of the game”.
Like in films, we also use camera transitions with a narrative or aesthetic background.
A fade in is when the scene gradually turns to a single color, a fade out is exactly the opposite. Narratively, it often symbolizes the passage of time or signifies completion.
A wipe is when a shot travels from one side of the frame to the other, replacing the previous scene. We can also see wipes where a black image comes from one side of the camera hiding the outgoing scene, then the black image returns to its original position giving a view to the incoming scene.
A dissolve overlaps two shots or scenes, gradually transitioning from one to the other.
Zoom is when a camera shot that changes smoothly from a long shot to a close-up or vice versa.
A shader is a piece of code that is executed on the Graphics Processing Unit (GPU), usually found on a graphics card, to manipulate an image before it is drawn to the screen.
The use of shaders in camera transitions is very extended because it gives a lot of possibilities when creating a transition. I have not created any shader in my research because of its complexity and because it is not the focus of this research.
I decided to keep both functionalities (change of scene and transition) separate to work independently and keep the code as encapsulated as possible, in addition to allowing me to make a greater diversity of types of transitions and the possibility of having multiple active transitions at the same time.
SceneManager is a module whose purpose is to control the behavior of the active scene and change the scene.
enum SceneType{
SCENE_01,
SCENE_02
};
class SceneManager :
public Module
{
public:
SceneManager();
~SceneManager();
// Called before render is available
virtual bool Awake(pugi::xml_node&);
// Called before the first frame
virtual bool Start();
// Called each loop iteration
virtual bool PreUpdate();
// Called each loop iteration
virtual bool Update(float dt);
// Called each loop iteration
virtual bool PostUpdate();
// Called before quitting
virtual bool CleanUp();
virtual bool Load(pugi::xml_node&);
virtual bool Save(pugi::xml_node&) const;
void ChangeScene(int new_scene);
Scene* current_scene = nullptr;
};
The Scene class is an abstract class from which the various scenes of the project will be inherited.
class Scene
{
public:
Scene() {};
~Scene() {};
// Called before the first frame
virtual bool Start() { return true; };
// Called before all Updates
virtual bool PreUpdate() { return true; };
// Called each loop iteration
virtual bool Update(float dt) { return true; };
// Called before all Updates
virtual bool PostUpdate() { return true; };
// Called before quitting
virtual bool CleanUp() { return true; };
virtual bool Load(pugi::xml_node&) { return true; };
virtual bool Save(pugi::xml_node&) const { return true; };
};
TransitionManager is a module that consists of a factory of transitions. Contains a container with active transitions and updates the behavior of them, in addition to the methods of creation and destruction of these.
class TransitionManager :
public Module
{
private:
std::list<Transition*> active_transitions;
public:
TransitionManager();
~TransitionManager();
// Called before render is available
virtual bool Awake(pugi::xml_node&);
// Called before the first frame
virtual bool Start();
// Called each loop iteration
virtual bool PostUpdate();
// Called before quitting
virtual bool CleanUp();
//-----Creation Methods-------
void CreateFadeTransition(float transition_time, bool is_scene_change = false, int scene_to_transition = 0, Color color = Black);
void CreateZoomTransition(float transition_time, float scale = 2);
void CreateCameraTranslation(float transition_time, iPoint destination);
void CreateBarsTransition(float transition_time, bool is_scene_change = false, int scene_to_transition = 0, bool horizontal = false, Color color = Black);
void CreateWipeTransition(float transition_time, bool is_scene_change = false, int scene_to_transition = 0, Color color = Black);
void CreateSquaresTransition(float transition_time, bool is_scene_change = false, int scene_to_transition = 0, Color color = Black);
void DestroyTransition(Transition* transition_to_destroy);
//-----Is there any active transition?
bool transitioning = false;
};
When we talk about the basis of a transition, I propose this structure.
Where:
So thats where the Transition abstract class come from.
class Transition
{
private:
enum class TransitionState {
NONE,
ENTERING, //Before the scene change
ACTION, //The frame where the scene changes
EXITING //After the Scene change
};
protected:
TransitionState state;
float transition_time; // total transition entering and exiting time
Timer* current_time = nullptr;
float percent = 0; //percent of the current respect the total time. It goes from 0 to 1
public:
Transition(float transition_time);
~Transition();
void PostUpdate();
//-----Update process-------
virtual void Entering();
virtual void Action();
virtual void Exiting();
float LerpValue(float percent, float start, float end);
};
Let’s create a wipe transition where a rectangle slides in and out of the scene.
TODO 01
Fill the method DrawRect().
TODO 02
Implement the Entering method of the wipe transition.
TODO 03
Implement the Action method of the wipe transition.
TODO 04
Implement the Exiting method of the wipe transition.
TODO 05
Create a CreateWipeTransition method in your TransitionManager.
TODO 06
Uncomment this code and introduce a case for your wipe transition! Try all transitions and choose one possible for your game or try design another one.
About video transitions
About Shaders
Fan collection of transitions