I'm Morgan McGuire (@CasualEffects). I've been working on computer graphics and games for 20 years at great places including NVIDIA, University of Waterloo, Williams College, Brown University, Roblox, Unity, and Activision.

See my home page for a full index of my blog posts, books, research, and projects.

Tuesday, May 28, 2013

Pixel Art Evolution

I've been working on a dungeon crawl cooperative ARPG with my children in the evenings. Our emphasis is on design and interaction, not graphics. To keep art time low and accomodate the very small characters, I chose a 2D pixel-art style. I began by purchasing low fidelity 8x8 sprites from Oryx Design Lab and upsampling them using hq4x (in this case, using Darnell's Depixelizer). This enabled me to bring the implementation to playtesting  in a few hours. Having reasonable initial graphics was important for my co-designers, who aren't as willing to identify with programmer art.

As the game became more refined, I revisited the sprites and redrew many of them to add increased detail and match the features of their corresponding character portraits.




The images above show the evolution of two characters: the human female Ranger (currently named d'Arc) and the dwarven male Builder Crefftwyr.  This is frame 0 of each of their idle animations. The in-game shots are less sharp because the engine renders at fixed high resolution and then filters down to the current screen resolution. The result reminds me of the early game consoles of my own childhood when displayed on 1980's television.

To make the Ranger appear female, I narrowed the waist by one pixel on the upsampled size, pulled in her right cheek, and added long hair. To make the hair stand out, I traced a thin dark outline around her cowl. The final touch was adding a small mouth. Many of the other male characters (not shown) look acceptable without mouths, but somehow defining the mouth increased a sense of delicacy and precision in the face.  I tried adjusting the neckline of her shirt, but at scale it just read as a larger head and not an exposed neck.

The challenge in drawing the Builder was emphasizing the classic fantasy dwarven racial characteristics at small scale.  I pushed his head down so that he fit in 8x7 instead of 8x8 and then cheated and shaved another pixel off his legs in the upsampled 32x24 version.  Making the right-side eye triangular and drawing in an eyebrow gave the appearance of a large nose.  I thickened his arms by one pixel and raised the shoulders to increase the hunchback appearance.



Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.

Thursday, May 23, 2013

Upsampling Pixel Art with Alpha on OS X

It is easy to find low-resolution pixel art "sprites" for indie games, for example, by browsing the legally-distributed, Creative-Commons-licensed art at OpenGameArt.org. Such sprites are popular partly for their nostalgia factor for 30-something developers, but I think primarily because such low-fidelity graphics are easier both for indies to produce and to match surrounding image quality for. I use such art extensively in my teaching programming samples and jam games.

Unfortunately, in a world of high-resolution displays, 32x32 pixel art sprites are simply too small. Nearest neighbor upsampling retains the pixel quality but often (to my eyes) plays up the lo-fi nature a bit too much.  I prefer to increase sprite resolution using a pseudo-vectorizing filter such as Maxim Stepin's hq4x. It yields results like this:
BeforeAfter

















There are several open source implementations of hq4x available. Finding one that actually builds without a number of dependencies and supports your operating system (mine is OS X when doing artwork) is tricky, however.

I use Nelson's Windows + Linux implementation (which works fine for OS X if you compile from the Makefile) that simply wraps Maxim's code and doesn't introduce any library dependencies.  To install this on OS X:

  1. Download the source from http://www.somebits.com/weblog/tech/hqnx/
  2. Double-click to unzip the code 
  3. Type "sudo make install" in the directory to compile the programs
The resulting script doesn't work correctly because it uses the Linux-specific tempfile command and because the hqnx code doesn't write correct .bmp files out.  I originally started patching this, but found that it was easier to simply invoke the hqx routines directly on .tga files, which it handles fine.  To upsample artwork simply use:

    hq4x source.tga destination.tga

This process does not preserve alpha (transparency). There are some variants that do support alpha, but again, it was easier for me to solve this problem in Photoshop. I paint backgrounds green (0, 255, 0) and then use the free Photoshop Green Screen filter.  You can also roll your own green (or other) screen removal code, since the algorithms were published by Smith and Blinn in 1996.

Here's the process for a spaceship that I downloaded from http://opengameart.org/content/modular-ships and then modified:



If you like this particular space ship, then you can download the set of 12 that I created by the process described here (as Public Domain content) at http://opengameart.org/content/2d-spaceship-sprites-with-engines.

In closing, I'd like to note that there is still a great need for all-in-one pixel art resampling, and providing this would be a great way for a junior game developer or Ph.D. student to gain great exposure. One could provide a simple, artist-ready tool that wraps hq4x and directly supports input alpha, or perform true vectorization for more significant upsampling, say, in the style of Depixelizing Pixel Art.



Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.

Saturday, May 11, 2013

Sol LeWitt and Voxel Ambient Occlusion

I've previously written about the relationship between the work of artist Sol LeWitt and computer science. Some representative geometric works by Lewitt include:


Note the exploration of the regular grid, mathematical patterns, tone and contrast, and light and shadow. The image that I created below follows in this vein of patterns in (exhaustive) combinatorial art and, I fancy, echoes LeWitt's interests.


Each tile in this image is a top view of a square of a white plane. The square is akin to the center of a Tic-Tac-Toe (UK: Naughts and Crosses) surrounded by up to eight white cubes in the adjacent squares. Those boxes are cropped out, so that only the effects of shadowing on the central square are present. That is, this is the complete set of ambient occlusion masks needed in a voxel system (such as Minecraft).

Each of the surrounding squares on the 3x3 grid of the Tic-Tac-Toe board may have a shadowing cube present or not. If you think of "there is a cube here" as the digit 1 and "there is no cube here" as the digit 0, then these patterns correspond to the possible values of an 8-digit binary number...there are 28=256 of them. Of course, many of these are duplicates.  For example, once the horizontal and vertical squares are filled, no additional shadowing can come from corners.  So, there are 24=32 tiles that look like the one in the lower-right.

I created these tiles using the G3D Innovation Engine to generate all possible scenes of this description and then applied the Scalable Ambient Obscurance algorithm (which is built into G3D) to efficiently generate the shadowing. I then used Image Magick's montage tool to combine them to produce this image.  The idea for generating tiles in this way is due to Mike Mara at NVIDIA. Below is an image showing their application for efficient illumination effects for the codeheart.js expert "orthovoxel" example. The left image has no ambient occlusion.  The right image uses these tiles to produce dynamic ambient occlusion in real-time.




Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.

Wednesday, May 8, 2013

This may be a good time to learn some Computer Science

According to the US Bureau of Labor Statistics, students who start on a computer science degree are far more likely to find employment in the years after their graduation.  Other science and engineering fields will have a labor oversupply, but CS will be drastically undersupplied:



Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.

Saturday, May 4, 2013

SSH with command-line password on OS X and Linux

Sometimes you have to connect via SSH or SCP to another machine inside of a script.  For example, when I update the codeheart.js website, I do so by running a script that builds the site, examples, and documentation, and then uploads them via SCP with multiple commands. Since the connection is launched by a script, it is inefficient..and annoying...to repeatedly type the password for SSH each time that the script needs it.  There are some common solutions to this problem, which don't happen to work well if your environment is OS X or Linux, or you don't have permission (or inclination) to modify the accounts to which you are connecting, or the accounts that you're connecting to have remotely-hosted file systems. Those common solutions are kerberos authentication forwarding/sshagent, TortoisePlink's windows SSH password option, and editing the known_hosts + authorized_keys files.

My solution is to use the Unix "expect" domain-specific language to trick SSH into communicating with a virtual terminal, and then programming the input that it receives until the connection is established.  The script below runs on OS X and Linux and allows you to supply a password on the command line.  I implemented this script to terminate with an interactive prompt, but you could instead close the connection after the remote command executes.

#!/usr/bin/expect -f
#
# syntax: sshnopassword password host command

set password [lindex $argv 0]
set host     [lindex $argv 1]
set command  [lindex $argv 2]

spawn ssh $host $command
expect {
  # Agree to modify known_hosts if prompted
  "(yes/no)?"   { 
      send -- "yes\r"
      exp_continue 
  }

  # Enter the password
  "*?assword:*" { 
     send -- "$password\r" 
  }
}

interact




Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.