About this project
Note: You can now support Sprite Lamp via PayPal!
Other note: I've added proper stretch goals further down the project!
Third note: Sprite Lamp has been greenlit, and will therefore be available on Steam when the time comes!
In a time when even phones have considerable graphical power under the hood, why do so many developers continue to make games with a visual style based around traditional 2D art styles, such as pixel art? Clearly, it's because people love how it looks.
So why did we spend all this time coming up with pixel shaders and lighting algorithms? Because they're pretty awesome too, of course.
Unfortunately, you kind of have to choose between these two great things. Having a game that looks like Metal Slug or Bastion, but also allows full dynamic lighting of the scene as the sun sets or as explosions go off around the player, has generally fallen somewhere between 'impossible' and 'kind of possible but really annoying to set up'.
Sprite Lamp brings this within reach.
Say you're making a zombie game, and you like pixel art, but you'd also like the main character to light their way with a flaming torch, because atmosphere is cool. With Sprite Lamp, you could create a dynamically lightable zombie, without touching any 3D modelling software, and maintain the style of pixel art — something like this:
At its core, Sprite Lamp is a tool for generating assets — primary among them, a normal map. Most game engines, and virtually all 3D game engines these days, support lighting with normal maps; this isn't anything new. The trick is the way the normal maps are generated.
Traditionally, normal maps have been generated in one of two ways. You can render out a normal map based on a 3D model — so, if you want a normal map for a brick wall, you fire up a 3D modelling tool of your choice, build the brick wall, and then render out a normal map. Alternatively, you can take a photo of a brick wall, and pass it through an analysis tool (such as CrazyBump) to generate a normal map.
I'm not planning for Sprite Lamp to displace these tools or methods — sometimes they are just what you need — but they have downsides. Making a mesh of an object is time-consuming, often involves expensive software, and isn't something every artist knows how to do. It can also be difficult to preserve artistic style such as brushstroke placement. Analysing photos or other images can be great, and is much quicker, but the results aren't always physically accurate unless you create it from a depth map, which is almost as difficult to create from scratch as a normal map anyway.
My goal with Sprite Lamp is to offer a third option, for when quality or style is a high priority, but 3D modelling isn't a good option.
Sprite Lamp requires the artist to draw several images. For the zombie above, five images were used. First, the artist draws an outline of the zombie, and colours it without any shading. This is called the diffuse map, and it looks like this:
Sprite Lamp currently creates normal maps, depth maps, ambient occlusion maps, and anisotropy maps. The first three all stem from what I call 'lighting profiles'. These are created by imagining that the subject of your picture is made out of white plaster, and then drawing them with lights shining on them from different angles. For this zombie example, four lighting profiles were used. They look like this:
That's it! Sprite lamp processes those images into a normal map (as well as a depth map and an ambient occlusion map, if you so desire). The created images look like this:
You can then import these into your game engine and use them as you see fit.
Sprite Lamp works well for pixel art, but that's not all it's for. It's entirely possible to use digital painting with Sprite Lamp to obtain a hand-drawn look. In fact, the first test we ever ran on Sprite Lamp was with a hastily scribbled picture of a goat. Here we've used four lighting profiles.
Note that in general, Sprite Lamp can make do with as few as two lighting profiles, and can make use of as many as five. The more you have, the rougher they can be and still get you good results. We've found that three or four profiles usually works best.
These images, combined with a very simple diffuse map, yields these results:
In fact, if you feel so inclined, you can use Sprite Lamp to process physical media. We tested this out here using a ball point pen and a light box:
Based on a survey conducted with early backers, Sprite Lamp now has official stretch goals. Note that regardless of stretch goal status, my hope is to release Sprite Lamp in the second quarter of 2014. However, depending on how this goes, some of the stretch goal features might come out in an update after launch.
Palette system, and expanded engine support (reached!): The palette system will be a combination of image processing and shaders, and it will allow artists to directly control the colours that get rendered for a given image. For instance, this allows the artist to set the colour of shaded areas versus highlights. Expanded engine support will involve me writing shaders for several engines beyond Unity. Currently the frontrunners for this treatment are Construct 2, Game Maker, and libgdx.
Expanded depth map options (reached!): At this level, I'll add the ability to tweak the depth map from within Sprite Lamp using various intelligent tools. I'm also going to make it possible to export a mesh of the depth map, which will be useful under certain situations when parallax is required but pixel shaders aren't a good solution.
Skelmesh functionality (reached!): According to the survey, the majority of Sprite Lamp backers so far who are looking for skelmesh functionality are Spine users. At this level, I will add the ability to view Spine animations in Sprite Lamp's preview window, as well as release examples of integration between Sprite Lamp and at least one of Spine's runtimes.
Streamlined interface: Regardless of stretch goals, I'm going to be putting some time towards smoothing the rough edges of Sprite Lamp's interface. However, at this level I'll be able to put some major code work towards the task of making it more usable, such as enabling live updates in the preview window as input files are changed, writing my own (more appropriate) colour picker, and allowing the user to save and load sets of options (such as lighting and shader conditions).
Beyond: I really haven't had the chance to think much about this, and I'm not in a position to name a funding goal. However, given more time, I would love to look into realtime algorithms for improving the visual quality of illuminated pixel art, by identifying and 'fixing' bad clusters. I have a few similar ideas for approaching making painted images look better, too. Of course, on a more mundane level, more time will allow me to expand the number of engines with shader integration.
One of the most common questions people ask about Sprite Lamp is, "Does it work with the engine I'm using?" The answer is that Sprite Lamp simply creates assets, and you can put them to any use you want. Most game engines with a lighting system — such as Unity, Unreal, and CryEngine — are good to go. If you're using an engine specifically for 2D, and maybe a bit more lo-fi, you should check if it supports normal mapping, or failing that, custom shaders.
There are some shader techniques you can use to help achieve whatever 2D art style you're going for. The zombie example (above) is made using a simple cel-shading shader. The plague doctor example (the fellow with the funny mask and the cane, above) makes significant use of self-shadowing, which in this case uses the depth map created by Sprite Lamp. This option probably isn't included as a built-in shader in most game engines.
For that reason, even though it's not technically part of Sprite Lamp, I'm going to do my best to provide free custom shaders for some common engines (such as Unity) that will help you get the most out of what you make with Sprite Lamp. Stuff like per-texel lighting, self-shadowing, and palette lookups aren't super-advanced features, but they're daunting if you don't write shaders. They are also unlikely to be included in most engines — because the assets they look best with are usually so hard to create. I'll only be able to provide actual shaders for common engines like Unity, but I'll also write some tutorials to describe exactly how it all works, so if your game engine supports customisable shaders, you'll be able to get things looking good.
This stuff isn't really part of the Kickstarter; it's not a reward level, because I'm just going to make these shaders and tutorials freely available. Hopefully this will help people be more productive with Sprite Lamp.
Some ambitious folk might be reading this and thinking, "Could I use this to make a game in the spirit of Metal Slug or Link to the Past, but with full dynamic lighting?" And just to be clear, the answer is absolutely YES. If you do it, you should tell me so I can play your game.
However, you might also be thinking, "That sounds like way too much work, so Sprite Lamp is not for me." Fair enough — it might not be — but before you go, I'll mention that there are a couple of other applications for this technology that don't involve overhauling your whole art pipeline.
Reducing the need for varied assets: One of the things you have to do as an artist is make sure that repeating artwork isn't too obvious. For instance, tiling textures need to be large enough that there isn't an eye-catching and undesirable pattern. Likewise, variations have to be drawn onto individual sprites if they are to be part of a horde, to avoid the horde looking too samey. As an example, here is a 64x64 tiled texture:
Here is that same texture, at the same resolution and tiled the same amount of times, with a single point light to provide some variation:
I think it's fair to say that most people would notice the tiling in the first image fairly easily; while I wouldn't go so far as to say it's horrible or anything, an artist might be inclined to draw at a higher resolution to get some nicer variation. However, it's harder to notice that the second image features a tiling texture at all.
Relighting characters for different environments: Sometimes it can be a challenge to have a single character travel to different levels in a game, because the character has to fit multiple colour schemes. If you were to make that character's assets with Sprite Lamp, you could intelligently recolour them for lots of different environments without having to rework any art. This can even be done completely as a pre-processing step — no need to have any dynamic lighting in your game engine at all. More importantly, this means that you only have to do the lighting profiles for your main character; all the environmental art, enemies that belong to specific levels of your game, etc. can all be done the traditional way.
Plain old normal maps for your 3D game: This might seem like an obvious one, but I think it's worth mentioning. Since Sprite Lamp produces fairly standard assets, they are just as usable in a 3D engine as any other normal map. The same goes for the depth and ambient occlusion maps, and perhaps most importantly, the anisotropy maps, too. If enough people ask for it, I'll even implement the ability to load up a 3D model in the Sprite Lamp preview window. It might seem a little confusing, but the way you paint lighting profiles for a UV-unwrap works in the least counterintuitive way possible, and isn't much harder to get your head around than most UV-unwrap texture painting.
Creating stereograms from 2D art: This is the reason I've included an Oculus Rift in my budget. I haven't explored this fully yet, because I don't have the right hardware — but because Sprite Lamp generates depth maps, it should be possible to offset pixels in such a way that a stereogram is created. This would allow for an Oculus Rift-friendly 2D game. Here's a sample of a hand-drawn stereogram we made as an experiment:
Better-looking rotation of sprites: You know that thing where a lovely hand-painted 2D platformer will have the occasional physical object — a rock, or a crate or something — that bounces around and rotates? I find that those objects tend to look somewhat out of place compared to the rest of the game. This is because when you draw an object normally, it has 'baked in' lighting of some kind. For a normal 2D game, you'd probably avoid painting in shadows and the like because it will look wrong when the object rotates. However, there is still some implicit lighting, usually in the form of more light coming from above than below (the kind of lighting you get on a bright but cloudy day outside). When the object rolls, it looks wrong; it's very hard to paint completely omni-directional generic lighting into a picture. Having a hand-drawn normal map makes it straightforward to make the object fit with the rest of the world at every orientation.
2D skeletal mesh animation: By the same token, Sprite Lamp is a natural fit for 2D skeletal mesh animation. It's currently a bit awkward to paint shading into the components of a 2D skelmesh character, because when they rotate relative to each other, the shading becomes inconsistent. Having a normal map fixes that. (I should note that while it is absolutely possible to have normal mapping and skeletal mesh animation work in harmony, I haven't had the time to do this yet.)
Anisotropy maps: The Pro version of Sprite Lamp allows you to convert a hand drawn 'flow map' into an anisotropy map. Anisotropic specular highlights occur on materials that have microfacets aligned in the same direction, such as hair or brushed metal. Though shaders that render anisotropy have existed for some time, the maps used to indicate microfacet direction are quite difficult and inconvenient to author, and this is particularly so for hand-drawn art. As such, I've developed a way to process an image that contains the direction of microfacets and convert it into an anisotropy map.
To illustrate this point, I have developed an unrealistically shiny elephant. The artist draws a flow map, which looks something like this:
The white lines indicate the direction of microfacets on the elephant. This map is processed by Sprite Lamp to create an anisotropy map. When this is combined with an appropriate shader (as well as a diffuse map and a normal map) the result looks like this:
I expect that a significant number of users will make use of this feature for 3D modelling, rather than 2D artwork. With that in mind, I intend to find out what standard forms anisotropy maps take and export to those standards, so that artists can work easily with the out-of-the-box anisotropy shaders found in common 3D modelling programs.
As is traditional with software tools like this, I'm going to make a few versions of Sprite Lamp available: a free version, that you can play around with but not export the maps you create (so you can't use it for making games), a hobbyist version that is similar except with the ability to export, and a pro version with more features, such as the ability to use custom shaders in the preview window. When Sprite Lamp is finished, the non-Kickstarter price for the hobbyist version will be $40, and for the pro version will be $100.
This chart leaves out a few potential features that may appear if I exceed my goal, or pending the results of some experimentation that hasn't yet succeeded to my satisfaction. Probably the most important of these is the ability to edit depth maps in a useful fashion from within Sprite Lamp. I'd very much like to add this, because there are certain circumstances where the 'correct' depth map would have discontinuities that are impossible to derive from a normal map alone. Ideally, those cases should be possible to handle with human intervention.
Currently, Sprite Lamp is in development on my PC, which means the things you've seen here are from the Windows version. I fully intend to release Sprite Lamp for Windows, MacOS, and Linux. In fact, one of the major reasons for bringing the project to Kickstarter is so I can afford to buy a mac. I do currently have intermittent access to a Mac for some basic proof-of-concept work, however.
My goal is to have a basic functional version of MacOS and Linux by shortly after the end of the kickstarter. This means that although pledging to receive beta access will be a slightly better deal for Windows users, users of other operating systems will at least get something worthwhile and usable (at least the ability to create and preview normal maps).
So, as you can see, Sprite Lamp is currently unpolished but development is very much underway. So, why am I on Kickstarter at all? There are a couple of reasons.
My costs of living are pretty low out here, and so to some extent I can work on a project like Sprite Lamp self-funded without too many problems. However, I need to make the thing releasable. This means:
- Making versions of Sprite Lamp for MacOS and Linux.
- Making sure Sprite Lamp runs on a variety of hardware and OS configurations.
- Making sure Sprite Lamp works smoothly with major engines such as Unity.
- Developing a more professional and usable UI design.
- Testing stereoscopic images with an Oculus Rift.
Some of that just costs time, but some of it costs money as well. Some of Sprite Lamp's budget will go toward my cost of living so that I can devote more time to it, but mostly it will go toward buying hardware that I don't have (such as a Mac) and licensing software that I need (such as Unity Pro).
Thanks to Giselle Rosman for help and support with the project so far, particularly for advice and sanity-checks on public release of information.
Thanks to Erica Sharpe for helping me come up with the name 'Sprite Lamp', which was a considerable step up from its previous name, 'the goat tech'.
Thanks to Jason O'Callaghan for helping me out with camera/lighting hardware and expertise for the video. Any questionable editing that happened after filming is my fault alone.
Thanks to Jonathan Blow, Tom Francis, and Robot Loves Kitty for giving me permission to use their games (Braid, Gunpoint, and Legend of Dungeon) as examples as examples of excellent painted art, pixel art, and illuminated sprites, even though I ended up only using them in this section here.
Thanks to Esoteric Software for consulting with me about what's involved with their excellent 2D skelmesh animation system, Spine, and for letting me use a lit version of Spineboy in my video.
Risks and challenges
As you can see, Sprite Lamp is past the proof-of-concept stage. I'm not asking for any faith in the idea that the algorithms behind Sprite Lamp work, because they already do. This Kickstarter is to help me polish up the final product, get it ported to platforms besides Windows, and make sure that everything works smoothly in the most likely use cases (such as common engines like Unity).
There are some risks in terms of the project taking longer than I expect. These come in the form of my not being an experienced MacOS or Linux developer. However, these aren't terminal risks to the project. I think the algorithms behind Sprite Lamp are pretty cool, but the software itself isn't exactly a staggering engineering project. Even if I was forced by unexpected incompatibilities to rewrite the whole project for each different OS, all it would do is delay the release for a few months.
There is also the possibility that I'll get hit by a bus, or perhaps something less dramatic but similarly project-ending. If that happens and the project is cancelled, I intend to release the source code for the project, so backers will still get at least part of what they signed up for.Learn about accountability on Kickstarter
Support this project
- (30 days)