2D or not 2D

 

In this platforming adventure game, you play as a guardian spirit of an ancient village, tasked with finding and recruiting other spirits to aid the village. Inspired by games like Okami and Paper Mario, you take the form of a woodblock print able to move in both 3D and 2D space -- allowing you to traverse up walls, through tight spaces, and over large gaps!

2D or Not 2D was made in Unreal Engine 4 during the COVID-19 pandemic by a collection of CMU students and alumni during the summer of 2020. We were interested in capturing the aesthetics of woodcut prints in video game form and exploring the capabilities of UE4, and so chose the above setting and story.

 

CREDITS

Production

Trento von Lindenberg - Producer

Code

Amy Huo - Lead Programmer

Kalpa Anjur - Gameplay Programmer

Art

Sydney Ayers - Technical Artist, VFX Artist, 2D Artist

Austin Garcia - Environment Artist, 3D Modeler

Trento von Lindenberg - Prop Artist, UI Artist

Sound

Amy Huo - Music Composer

Trento von Lindenberg - Sound Designer

Design

Kalpa Anjur - Concept Design

Lisa Lo - Narrative Design

Sydney Ayers - Character Design

Janny Mongkolsupawan - Concept Artist

Shaders

  As Technical Artist for 2ON2 (2D or Not 2D), a large part of my job was creating shaders.  There were two main shaders that had to be created to get a toon shader: a cel shader and an outline shader.  

With Shaders
With Shaders

With Cel and Outline Shader

press to zoom
Without Shaders
Without Shaders

Without Shaders

press to zoom
With Shaders
With Shaders

With Cel and Outline Shader

press to zoom
1/2

Outline Shader

117706963_750522082458543_66630296351164

 First up on my list was the outline shader.  It unfortunately was absolutely the more difficult shader to create.  I learned a ton while making this shader.  Although I will only be talking about these main two iterations, there many smaller changes that took place.

 

The first shader I created was a good start, however it wasn't quite what I wanted.  Although it was definitely aesthetically pleasing, it was heavily based off of the Custom Depth Node in UE4.  This node is incredible, but it basically is used only for true outlines (with no inner lines- I used this for object outlines in Plant Planet).  I realized from this I needed to do true edge detection to get the inner lines that I needed.  

  For my next attempt at an outline shader, I knew I needed to adjust the way I approached it.  I decided to use edge detection with convolution.  I used a laplacian edge detection kernel to achieve the desired effect.  This essentially just compares each pixel to one another and determines if there is  a large difference between the pixels.  If there is a large difference between pixels ( say between a white pixel and a black pixel in a grayscale image), we can assume that this represents an edge.  This worked far better to get more of the inner lines that we needed.  

OutlineShader3.jpeg
unknown-8.png

For my current iteration, I used the previous shader and added variable dilation and did a lot of tuning.  I also added a custom depth buffer so that I could choose exactly which objects got this outline.  I also added a paper overlay from a texture I created to get a more drawn feel.  

Cel Shader

The cel shader was actually easier to make than expected.  I first had to learn what a CLUT was (Color Look Up Table) and how banding worked, but after that it wasn't too bad! My first ones I did in shades of blue and because of the setup of the shader, it did indeed cel shade it, but didn't take into account the true colors of the objects.

Cel Shaded
Cel Shaded

press to zoom
No Cel Shader
No Cel Shader

press to zoom
Cel Shaded
Cel Shaded

press to zoom
1/2
unknown.png

Once I accounted for the base color, I started to create more and more CLUTs with different amounts of bands, and different proportions of each color.  One of the simplest (yet most important) things I had to learn was to not include straight black or white as it would drastically skew the dark shadows and bright highlights of the cel shader to being purely black or white.  I ended up creating about 2 dozen CLUTs to get to one where I was happy.  

 

Particle Effects

Hover Sparkle Effect

Our woodblock character can not just jump, but hover! This needed a separate particle effect to signal that you were indeed hovering, not just jumping.  I created a small sparkle effect for this to signal the magical nature of the woodblock.  I created the glowing shape in Unreal and made them appear randomly in small area while gently blinking in and out of existence.  

Poof.gif
SparklesGif.gif

Disappearing Poof Effect

When you find each spirit, they disappear in a poof- like cloud.  Although relatively simple, this effect made a big difference in signifying that the spirit went back to the woodcarver.  Here, I made a rough cloud like shape in illustrator that I then used in a burst particle effect.  I changed the alpha in color over time using the curve editor to make it so that it would quickly (but smoothly) fade out of existence. 

Other Effects

Rice Field

Creating the rice field for 2ON2 was new for me as I had never really created a large amount of foliage before for a game (only individual plants / trees that would be placed).  I ended up drawing a rice plant in photoshop, then just plastering it onto an array of planes.  Each plant had two planes that were crossed so that from either side you could see the plant.  After getting a perfect array, I purposefully moved them about to make the field look more natural.   After that, it was pretty much just applying a texture.  I did however, make it so that the plants were slightly interactive in that they will move slightly away from the player if touched.  

Rice Plant Sprite
Rice Plant Sprite

press to zoom
Mesh without Textures
Mesh without Textures

press to zoom
Implemented Rice
Implemented Rice

press to zoom
Rice Plant Sprite
Rice Plant Sprite

press to zoom
1/3
 

River Shader

unknown-2.png

Although I could probably work on creating the perfect river shader for months, because of time constraints, the river ended up being rather simple.  With that being said, it still definitely worked.  I think the part that helps create the river aesthetic the most is the Depth Fade.  This node and surrounding code creates a murkier bottom of the river while near the edges it gets more transparent.  I also have textures that are panning across the surface and have the river ebbing slightly based on an amplified perlin noise texture.