Welcome to Sprite Lamp!

Sprite Lamp is a tool designed to help artists process natural-looking hand-drawn artwork into normal maps and other image types that are required for creating dynamic lighting. To use Sprite Lamp, an artist draws several images, called 'lighting profiles', for Sprite Lamp to process into a normal map, depth map, and ambient occlusion map. These lighting profiles take the form of pictures of the same object, drawn in greyscale, and lit from different angles. The artist must draw at least two of these, and Sprite Lamp can make use of as many as five. Ultimately, it's up to the artist to draw these images themselves, but there are some provided examples to help you get an idea of what they should look like, as well as how to use the software.

Sprite Lamp was made possible with the help of over 500 backers of the original Kickstarter project, as well as people backing/preordering via PayPal. This version of Sprite Lamp is also built using the excellent Qt libraries, along with the Spine from Esoteric software, and some excellent gif-exporting code shared publicly by Charlie Tangora. For more information, check out credits.txt.

Table of Contents

Tutorial

Art First: Creating lighting profiles
Getting Started: Loading images
The Fun Part: Processing images
Saving Your Work: Two method

Manual

General Layout
Preview Window
Images Tab
Map Generation Tab
Preview Window Tab
Palette Tab
Spine Tab
Depth Editing Tab (pro only)
Anisotropy Tab (pro only)
Command Line Interface (pro only)


Art first: Creating lighting profiles

The first thing you're going to need to make use of Sprite Lamp is some artwork for it to process. The actual creation of these of these is up to you (and your chosen art tool and/or physical medium), so this section is to help you understand what you should be drawing.

The thing that Sprite Lamp is most concerned about is the lighting profiles. For reasons lost to history, I'm going to be demonstrating what these are with a picture of a sort of goaty creature. As you can see, we have here the same goat in the same pose, but with five different lighting set ups. Note that you don't always need all five of these - I'll go into more detail about which images you need under what circumstances below.

A goat, lit from five angles

The goat has been lit from the top, from the bottom, from the left, from the right, and from the front (think of this as similar to the result of overdone flash photography). Consider these to be large area lights - avoid drawing in shadows, particularly hard shadows. You don't need all five of these images - the more there are, the rougher the input can be, but you can get by with as few as two. Specifically, you need at least one of the left and right pair, and at least one of the top and bottom pair. The front light is optional. For cases where you're drawing the lighting very precisely, you can get away with fewer profiles. In situations where you're doing things very roughly, particularly using physical media that are being scanned in, more can help.

The lighting profiles are all you really need to get started, but there are a few other images that Sprite Lamp can make use of, and one of the most important is the diffuse map. Unlike the lighting profiles, this one should be in colour - it contains the colours that you left out of the lighting profiles. Think of it as being how your picture would look if it was lit perfectly evenly from all directions. Importantly, the diffuse map should also have an alpha channel if you want some parts of your image to be transparent (as is the case for character work, for instance). Our goat's diffuse map looks like this:

A coloured image of a goat, lit evenly, as though from all angles

I'll go into more detail about all the types of maps that Sprite Lamp can make use of a bit later - for the moment, the lighting profiles and the diffuse map are a good start. One last thing though - it's important to name your images in a standard way. Sprite Lamp expects certain suffixes on images so it can automatically load them all in one go - this isn't required, but it saves you loading them in one by one. The above images are called:
    Goat1_Top.png
    Goat1_Bottom.png
    Goat1_Left.png
    Goat1_Right.png
    Goat1_Front.png
    Goat1_Diffuse.png
The important part of that is the underscore and the part after it - if you are drawing a picture of a flying pig, you might call your files "FlyingPig_Top.png", "FlyingPig_Bottom.png" etc. They should also be in the same directory. Note also that I'm just using '.png' as an example here - you can load other image types with Sprite Lamp (though a set of images should be the same type, in order for them to be automatically detected as part of the same set).

So, if you want to go and try your hand at creating some of those images, the next section will be waiting for when you get back. If you just want to jump in, the above goat images are included in the Examples folder of Sprite Lamp, so you can use them to get the hang of how the interface works.

Getting Started: Loading images

Dealing with input images is done in the Images tab, which is the one that should be open when you first launch Sprite Lamp. This next part should be pretty straightforward. Hit the big button that says "Load Image Sets", and then select one of the images you've created and click 'Open'. Alternatively, select one of the images in your operating system's file explorer and drag it into the Sprite Lamp window (drop it anywhere so long as it's not directly on one of the image preview boxes). You should see the images you've opened down the right hand side of the tab, and a (simple, unlit) version of the image in the preview window. There's a bit more to learn about this tab, but we'll come back to that later.


The fun part: Processing images

Now, we get to the whole point of Sprite Lamp. Click on the Map Generation tab. At the top, you should see your lighting profiles. The simplest thing to do now is click the Generate Normals button. If you have a very high-resolution image this might take a little while, but if all goes well, you'll see your generated normal map below the Generate Normals button. More importantly, you'll get to see how it looks lit over to the right, in the preview window - you can now drag the light source around over in the preview window to the right (drag with the left mouse button), to get a good look at how things turned out. Hopefully this is a good experience, but if not, it's an opportunity to have a look and try to figure out what doesn't work. Sprite Lamp has been tried with a few art styles from a few different artists, some of which work better than others, but to some extent it's up to you to experiment. I hope you get some good results!

If you're happy with your results from the normal map generation, and your image is one that would benefit from self-shadowing (this is especially true for textures, such as brick walls), you can then move on to the next stage - generating a depth map. Though there are parameters to play with later, at the moment try just pressing the Generate Depth button and see what you get. Note that though technically the depth map makes a minor difference to shading at this point, it will only really have a worthwhile effect if you enable shadows. This and other rendering effects can be tinkered with in the Preview tab - more on that later.

Finally, from this tab, you can generate an ambient occlusion map (often abbreviated to 'AO'). This simulates where shadows get cast when light is coming from all directions (known as 'ambient light' - for instance, this is the case on an overcast day). This requires a depth map to have been generated - once that's done, simply click the Generate AO button. Again, this is only used when certain settings are tweaked in the preview window. There'll be an in-depth description of all these settings in the chapter on the Preview Tab.


Saving your work: Two methods

If you have one of the paid versions of Sprite Lamp, you can now export your work (so you can load it in your game engine of choice). There are two ways to save the maps you've generated. The first is from within the Map Generation tab - next to each map you've generated, there is a corresponding Save button. If you click this you'll have the opportunity to save each individual file. There's also a drop down menu asking you if you want to pack anything into the alpha channel of the normal map - this can be either the depth value, or the opacity value (from the loaded diffuse map). Some of the official Sprite Lamp shaders (including for Unity and Game Maker) expect the depth value to be in the alpha channel of the normal map.

There's also a quick way of saving everything you've generated with the default names. If you click back over to the Images tab, you'll find a Save Output Set button at the bottom. To its right are several check boxes - the boxes that are checked are the types of map that will be saved out (assuming you have generated them). If you click the Save Output Set button, Sprite Lamp will automatically give appropriate names to the output (such as "FlyingPig_Normal.png, "FlyingPig_Depth.png", etc) and save them alongside the input images.

So, that's it for the simple run through Sprite Lamp! I hope your art turns out well. There are a couple of other things that you can do with Sprite Lamp, so now I'm going to go into detail for every tab and feature the program has to offer.

Sprite Lamp - The Manual

General Layout

Sprite Lamp has a fairly simple UI layout, as seen here.

The Sprite Lamp interface, with the map generation tab open

The right hand side of the view is taken up by the preview window. This is a key feature of Sprite Lamp, because it lets you get some idea of how your artwork will look in game. The left hand side consists of a number of tabs - these contain all the controls that actually let you do things in Sprite Lamp.


Preview window

The preview window in Sprite Lamp shows the currently loaded artwork and allows you to examine it under different lighting conditions. The parameters for viewing (such as lighting and shader settings) are managed in the preview window tab. Dragging with the left mouse button moves the light source (or paints if you're in depth editing mode). The camera can be panned by dragging with the right mouse button and zoomed in and out by dragging up and down with the left and right mouse buttons held down. The mouse wheel also works for zooming.

Reset camera: This returns the camera to a neutral position that allows you to see all of the loaded image.

Render lighting: This will render the current lighting conditions to an image file. If you have the 'animate' check box checked, this will render to a 30-frame animated gif, using an orbiting light source (the orbit you have selected will be used - if you don't have one selected, it will use a vertical orbit). This is largely for sharing your artwork with others. Leaving 'animate' unchecked will render a single frame of lighting, using the light source location and settings from the current preview window state. Checking the 'native res' check box will render the image out at the dimensions of the source image, and with the image framed the same way - if it's not checked, it will render at the resolution and framing of the preview window.

Show log: This will open a separate window that shows a log of everything that Sprite Lamp is doing. It's mostly useful for keeping track of processes that are taking place, or certain debugging.

CLI Params Helper: This button - present only in Pro versions of Sprite Lamp, where you have access to the command line interface - pops up a window to help you create command line arguments. The Params Helper window shows the command line arguments needed to replicate the map creation parameters you currently have selected in the main Sprite Lamp window. You can also select which maps you wish to automatically save out and it will create arguments for doing so. In this way, you can fine tune the creation parameters you need for a given asset, then create a script to iterate over all your assets, using the same parameters.


The Images Tab

The Images tab lets you control which images you have loaded into Sprite Lamp. This can be straightforward, as in the example above (simply loading a single set of images), but in the pro version it's also where you go to load multiple image sets as frames of an animation, select which frame you're currently looking at, and control how Sprite Lamp handles the multiple sets. This tab also lets you look at all the images that are loaded, together in one place.

Load image set: This button will load sets of images based on the name of the image or images you select. The pro version of Sprite Lamp will allow you to load multiple image sets - in this case, you can select multiple files and Sprite Lamp will open all sets that you have selected an image from.

Image previews: This area shows all of the images that are currently loaded by Sprite Lamp. Mouse over them to get a brief description of what that image does if you're not sure. You can right click any of these image previews to get a context menu, allowing you to load an individual image into that slot, examine the image (this pops up a window that will show you the image in detail), or clear that image (which will revert to an appropriate 'empty' version of the image type). You can also drag an image file from your operating system's file explorer onto one of these image preview boxes to load it into that image slot. Note that all of this applies to the other image previews that appear in other parts of Sprite Lamp's interface - not just the ones in the Images tab.

Multiple image sets: This section exists only in the pro version of Sprite Lamp. The list contains all image sets that are currently loaded. Currently you are able to select the current set of image for preview and processing - in the future you will be able to reorder the sets of images here for animation purposes as well.

Save output set: This allows you to save multiple generated maps in one go - every map type that you have checked will be saved (provided it has been generated). If you have Normal/Depth selected but haven't generated depth, it will save a normal map regardless of whether the Normals checkbox is checked.


The Map Generation Tab

This, as they say, is where the magic happens. The simple use case of this tab is to generate a normal map, a depth map, and an ambient occlusion map, in that order. The details that really need covering are the parameters that control how each map is generated. After you've generated images, you can save individual generated images out from here using the save buttons on the left. These work in a fairly predictable manner. Be aware that when saving the normal map, you have the option of putting some data in the alpha channel - the drop down menu lets you select between leaving the alpha channel empty, putting the depth values into the alpha channel (if they're available), and putting the opacity values from the diffuse map in the alpha channel - these options can be useful for various shader optimisations, and in fact, most of Sprite Lamp's official shaders will expect the normal map to have depth data in the alpha channel.

Normal maps

A normal map is a way of communicating the orientation of a surface at every point in the image. A 'surface normal' is a vector that points in a direction perpendicular to a surface, and subsequently communicates the orientation of the surface - as such, a normal map is an image where every pixel is a surface normal. In most cases, including Sprite Lamp, the x, y, and z components of the surface normal vector are encoded into the red, green, and blue channels of the image's pixels. The game engine/graphics card then decodes this to figure out the orientation of the image at that point, and once it knows the surface's orientation relative to the direction the light is shining, it can perform shading.

Normal rotation direction/amount: This will simply take the normal vector, after generation, and rotate it in a certain direction by a certain amount. It's good for tweaking a normal map if you made a mistake with the input map's colour balance. For instance, if you drew the right lighting profile a bit too bright or the left profile a bit too dim, the entire image will be facing slightly to the right - in this situation, pointing the direction to the left and the amount to five or ten degrees might help balance things out. Note that you can control the direction by dragging the arrow around or by tweaking the number. You can rotate the normals in any direction up to 90 degrees, but that's almost certain to give you weird results - small tweaks work best here.

Bend normals: This is a value that the Z component of the normal gets multiplied by prior to normalisation - the effect that this has is that a value greater than one 'flattens' the map and a value less than one makes it more severe (pushes the normals out from the centre). This has no relation to the graphical technique known as 'bent normals', so pay no attention to that similarity.

Flip Y (invert green): Different game engines have different standards for whether the positive Y axis is up or down. Sprite Lamp's default is to make positive Y point up, because that's what makes sense to me in my head, but I believe Unity and quite a few other engines go the other way. If this box is checked, Sprite Lamp's preview window will start rendering as though positive Y is down, but it won't regenerate the map that way until you regenerate the normal map (so checking the box will temporarily make things look broken).

Autofix flat normals: If you interpret the artist's input images very precisely - some would say perversely so (where pure white is the result of a light shining directly on a surface) - sometimes artists will paint things that don't make mathematical sense. That's hardly the artist's fault, and the point of Sprite Lamp is to avoid having to paint in an annoyingly precise way as much as possible, hence 'autofix flat normals'. Checked by default, this feature will detect those situations and compare them to the lighting in the rest of the image, to scale everything to what the artist intended. Note that this has no effect (and isn't needed) if you have painted a front lighting map. However, occasionally for an artist looking for a specific effect, turning this off might be worth doing.

Depth maps

While a normal map contains surface orientation at each pixel, and the position of the pixel in the image tells us its horizontal and vertical position, we still don't know the depth position of the pixel. For instance, if you were creating a stone wall image and the image was facing the camera, the graphics card wouldn't be able to tell that the bricks are closer to the camera than the crevices between the bricks. Not knowing this means that certain visual effects aren't possible - for instance, you need to know that the bricks jut out further than the mortar in order to have the bricks cast shadows.

A depth map contains distance from the camera in each pixel. Whiter pixels are closer to the camera, and darker pixels are further away. Because this is just a single component, it often makes sense to save a 'Normal/Depth map', where the normal values are in the RGB channels, and the depth value is in the alpha channel - this saves space and also makes for quicker lookup. This is as good a place as any to recognise that this technically isn't a 'depth' map, it's a 'shallowness' map or something like that, because greater depth corresponds to lower luminance values. Unfortunately, I'm probably to far along to correct this without causing people pain, so I will just have to live with my failure of pedantry here.

Creating a depth map from a normal map when the image is a complicated object with discontinuities in the depth value is a bit of an inexact process - for that reason, in the pro version of Sprite Lamp, there is a depth editing panel that lets you manually tweak the depth map for best results. More on this later.

Low frequency emphasis: When creating a depth map, Sprite Lamp does several passes over the painted normal map at different sizes of detail. For instance, with our goat example, a low frequency shape would be the shape of the goat's body, whereas a high frequency shape would be the detailing in the fur. In theory, sliding the low frequency emphasis all the way to the left (that is to say, maximum emphasis on low-frequency details) will give you 'correct' results. However, there are certain situations where this isn't what you want. For instance, if you paint a texture map that ought to be flat (like a brick wall), it's possible that you will inadvertently paint certain bricks with a bit more of a tilt in a certain direction, and the result is that there is a kind of weird bulge in part of the brick wall's depth map. This is an example of low frequency noise that you don't want - moving the slider a little to the left will help with this kind of problem. Ultimately, it's probably best to figure out how this works through experimentation.

Refinement steps: This simply determines how many times Sprite Lamp will run through its refinement process for obtaining a depth map. To a point, a higher number will get you better (or at least, more accurate) results. However, it will also increase the amount of time taken linearly (that is, doubling the refinement steps also doubles the algorithm's run time). For very low resolution images (such as pixel art), turning this up very high won't have much effect.

Respect selected edges (Pro only): If you have the Pro version of Sprite Lamp, you can select edges from the depth editing tab. Checking this box will cause the depth generation process to ignore connections between pixels that have an edge between them - that is, it will make no attempt to make the pixels on either side of an edge match their depth based on the normals in the area. This often causes some weird discontinuities, and the results aren't usually what you want initially, but it can create a better place to start on depth editing.

Ambient occlusion maps

Ambient occlusion maps aren't as ubiquitous as normal and depth maps, but they can be useful for adding some lighting detail to an image. Ambient occlusion is a form of shadowing, cast by ambient light, and ambient light is light that comes from all directions rather than from a well-defined light source. These shadows tend to darken crevices and other concave areas. Ambient occlusion maps can be used by the shader directly in a mathematically correct way, or they can be multiplied with the diffuse map rather than painting in soft self-shadowing manually. Generating an ambient occlusion map requires you to have generated or loaded a depth map first.

Ambient light flatness: This determines whether the ambient lighting comes from all around the object, or from one direction. If you are drawing a single object (like, say, a character), you'll want the ambient light flatness to be low, because the light should be coming from all around. If you're painting a texture, like a brick wall, which will be used to tile on some larger surface, it makes more sense to make the flatness higher because the light comes mostly from one side.

Cone gradient: The higher this is, the narrower the 'cone' that Sprite Lamp traces from each pixel to see how much of it is occluded. In practice, setting this lower will result in an area having to be less and less dramatically concave before it gets shadowed. Setting this to a negative value will mean that pixels will have to be on a convex point in order to not be in shadow (this isn't really physically accurate but it can be used as an interesting hack for creating a specularity map).

Box size: This refers to how large (in pixels) a box the algorithm will look in for occluding features. Increasing this value increases the runtime of the algorithm quadratically (doubling the box size quadruples the run time). Bigger is not necessarily better.

Step size: This refers to how many pixels will be skipped while looking for occlusion features. Increasing this number speeds up the algorithm's runtime quadratically, but in theory it will degrade the quality of the results. Fortunately, for higher resolution images this often isn't noticeable.


The Preview window tab

This is where you control what you see over to the right. None of this has any effect on the maps you're creating (with the exception of light renders) - it's purely to help you tweak the preview window's rendering set up so you can get as close as possible to the rendering set up in your game.

Lighting parameters

These let you change the colour, position, and a few other features of the lighting in the scene. To change any colours, click the colour swatch, and a colour selector will appear. Note that there is a certain amount of conceptual overlap between some lighting and shader parameters, so look in both places if you can't find what you're looking for.

Direct light: This changes the colour of the light source - the one that follows your cursor.

Upper ambient light: This changes the colour of the ambient light coming from above. If upper and lower ambient colours are locked via the 'lock' checkbox, this will control uniform ambient light. Note that for both ambient light colours, if you have a bright directional light doing most of the scene's lighting, you'll want the ambient light multipliers quite low to avoid washing out the scene.

Lower ambient light: This changes the colour of the ambient light coming from below (unless the colours are locked, in which case it has no effect). These different ambient light settings are part of a system called 'hemispheric ambience', which is a simplified version of spherical harmonic lighting - the shader will blend between the two colours, based on how much the surface is pointing up or down, allowing for a cheap way of avoiding ambient lighting that looks extremely flat and uniform.

Light multipliers: These multiply the intensity of the various lights in the scene (point/directional, upper and lower ambient). This allows you to adjust the brightness of the lights without messing about with a colour chooser.

Background colour: This isn't exactly a property of the lighting - rather, it just changes the colour of the background behind your artwork. Can be helpful for seeing how the art will work in different coloured surroundings.

Wrap-around lighting: This determines how much the lighting will illuminate surfaces despite those surfaces facing away from the light source to varying degrees, having the effect of the light wrapping around what would normally be dark parts of the object. Having this set all the way to the left will be 'correct' lighting from a point light. Increasing the wrap around effect will cause it to resemble a larger area light. Because this isn't a physically accurate technique, it will sometimes give you odd results. In particular, it doesn't interact very well with self-shadowing, especially when turned up very high.

Attenuation strength: This determines how quickly the light drops off in power the further it gets from the point it's illuminating. Having it at minimum means that the strength of the light remains constant at any distance.

Light Z position: This moves the light towards and away from the camera. Most of the time, you'll want it to be to the right of the centre, since that means it's in front of the image you're lighting, but it still makes sense to move it in the other direction to see what the object looks like backlit.

Light animation style: This selects different movements for the light source. If you have one of the orbit animations selected, moving your cursor over the preview window will override it and lock the light source to the cursor. The selection of orbit is also what is used for generating a preview gif.

Show light source: Checking this will show the position of the light source, as a line-rendered diamond. Can help you see what's going on, but you probably want to turn this off for light renders.

Use directional light: Checking this will switch from a point light source to a directional light source. The direction of the light is determined by the line from the light's 'position' through the centre of the sprite. This tends not to look as nice in the preview window, but can be valuable for prerendered lighting. Of particular note is the fact that the resulting light render will tile seamlessly, assuming the underlying textures do, so this lighting mode can be useful for making pre-lit tilesets.

Save lighting: This saves the current lighting parameters, so that they become the new 'default' (which will persist between instances of Sprite Lamp). This covers the four colours (direct light, upper/lower ambient, and background) as well as the light Z position, light wrap value, attenuation factor, and whether you're using a point or a directional light..

Load saved lighting: This will let you return the lighting settings to their defaults, user-defined or otherwise.

Reset saved lighting: This will delete your saved lighting, returning it to factory defaults.


Shader parameters

From here you can tweak the settings of the shaders that render to the preview window. There is some conceptual overlap between this and the lighting parameters section, so if you can't find what you're looking for, check both places.

Ambient occlusion intensity: This affects how strong the effect of the ambient occlusion map (if you have one) is. In effect, having it at less than 100% is similar to fading the AO map towards white.

Amplify depth: This affects the strength of the depth map, if you have one. The higher the value, the closer the light parts of the depth map become. This has a minor effect on shading, but it mostly matters for self-shadowing.

Specular intensity: This multiplies the intensity of the spec map, and thus the brightness of any specular highlights that are rendered. The middle of the slider represents no multiplier - all the way to the left will turn the specular highlights off completely, and all the way to the right will double the intensity.

Shadows: Checking this box will enable the shader's self-shadowing. Requires a depth map to work.

Gloss from spec alpha: If this box is checked, the shader will derive the glossiness (aka the specular exponent) from the alpha channel of the specularity map. If it's not checked, glossiness is set to a constant value.

Cel shading: Checking this box enables the simple implementation of cel shading (more precise control over cel shading can be achieved with palettes). The number spinner next to it allows you to change the levels of colour that the cel shader can choose from - higher numbers will look closer to smooth lighting, while lower numbers will make the cel shading more severe.

Filter textures:  By default, Sprite Lamp's textures are unfiltered (or more precisely, they are drawn with nearest neighbor filtering, aka 'blocky textures'). This is because pixel art is a common use case for Sprite Lamp. However, if desired, bilinear filtering (aka 'blurry textures') can be enabled with this check box.

Select shader: Sprite Lamp has three shaders to choose from. The default shader, standard Phong, will be used for most purposes. The palette shader is used for cases when you're making use of Sprite Lamp's palette system. Pro users making use of the anisotropy map generation can make use of the Phong/Ward shader, which shows anisotropic highlights.

Reload shaders: This button is mostly for development use - it forces a reload of all of Sprite Lamp's shaders. If you are playing around with the shaders for some reason, this allows you to reload them without rebooting Sprite Lamp (note that errors associated with the shader compilation can be seen in the log window).

Geometric parameters

These settings are to do with the way geometry is rendered in the preview window.

Rotation about Z/Y: Which axis you're rotating about depends on whether you have the 'draw as mesh' box checked. This allows you to adjust the orientation to inspect either hemispheric ambience or the shape of the depth map.

Recentre: This will return the rotation slider to precisely the middle position.

Geometry mode: By default, this is set to 'single billboard' which will simply draw the sprite as a rectangle. Setting it to 'mesh' allows you some ability to rotate the object horizontally and observe its depth (note that Sprite Lamp's preview window uses an orthographic projection). Setting this to 'tiled' will draw a five-by-five grid of billboards, allowing you to ensure that your texture maps tile properly in cases where that's desirable.

The Palette Tab

The palette system in Sprite Lamp has the goal of giving artists more precise control over the colours that appear in the end result of their artwork. It can be used as a way of tweaking the colours of shadows and highlights (for instance, giving shadows a blue tint and highlights a yellow tint), for instance, or for giving more nuanced control over cel shading. It can also be used for palette-swapping - more on that later.

The way this works is based on the diffuse map. It works best with only a few distinct colours in the diffuse map, and you currently can't have more than 256 distinct colours (and be aware that it's very easy to accidentally create an image with many more colours than this by using antialiased brushes). First, Sprite Lamp processes the diffuse map to create a 'palette map'. This is an odd-looking map, insofar as it doesn't resemble the shape or the input image at all, nor does it have the same dimensions. Rather, it is a collection of colours that appear in the diffuse map, arranged left to right. Each column of pixels represents a distinct colour that appears in the diffuse map. For this reason, you might have to zoom in close on palette maps generated from low-colour diffuse maps - they might only be a few pixels wide. 

To explain how this all works, I'll go through an example using the infamous Sprite Lamp Zombie. The required inputs for this are included in the examples folder. In Sprite Lamp, hit 'open image set' and open up the relevant set of images - there should be a set of lighting profiles, a specular map, and a diffuse map. If you look at the specular map, you'll notice that it's all white, and as a result the zombie shinier than you might expect - this makes more sense once we're rendering with the palette system. First off, you'll need to go into the map generation tab to generate a normal map (you can generate depth too if you want, but for this art I've found it doesn't make a very obvious difference). Then, head over to the palettes tab.

From here, for the moment, I'll get you to hit 'generate palette map', and then 'generate index map'. You should end up with two maps that look a bit like this (the palette map is the one on the left - zoomed in a lot so you can see it):

The default (flat) palette is on the left, and the index map is on the right.

Before we continue, I'll get you to save the images you've generated (normal, palette, and index maps). At this point, you should click the 'select palette shader' button - this will switch the preview window over to the shader that makes use of palette maps (note that you can also choose different shaders in the preview tab). If all goes well, when you do this, the preview window will show no lighting at all - you'll just see the diffuse map. Contrary to how it seems, this is actually what we want, because the palette map we've generated has no lighting painted into it.

At this point, check the 'create sample lighting' checkbox, and regenerate the palette map. Hopefully now you have lighting back. It's not very exciting - in fact, it probably looks very much like it did before, but you have it. Save this palette map out with a different name, but keep it handy.

We're now finished with Sprite Lamp for the moment (though it's useful to keep it open so we don't have to reload everything later), so minimise it. Fire up your favourite image editing software (ideally something that allows for easy manipulation of individual pixels), and open up the two palette maps you saved - the original one that got rid of the lighting, and then the 'populate with sample lighting' one as well, and have a look at them. You'll have to zoom in pretty close to look at the individual pixels, because the images are very narrow. The 'flat' palette and the one with sample lighting, side by side, will look something like this:

These are the two default palettes Sprite Lamp can create

The general idea of the way palettes work is that each pixel column represents a distinct colour in the original diffuse map (a 'material', in a sense - such as the zombie's skin, or shirt, or pants). Within that column, the middle pixels represent the colour of that material when it has full diffuse illumination, but no specular lighting. The pixels below that represent diminishing diffuse lighting, with the bottom pixel representing the material's colour at zero light. The pixels above that represent the colour of the pixels as specular highlights are ramped up, with the top representing a (fairly nebulously defined) maximum level of specular lighting. Based on that, the palette you generated with 'create sample lighting' checked contains colours that replicate a standard shader - the pixels fade to black at the bottom, and fade to white at the top, which is why when you were using that palette, you got something similar to a single default light source. The original 'empty' palette has every column be the same colour from top to bottom, which means that those pixels will be the same colour regardless of level illumination - this is why using the original palette made everything look flat.

Your role in all this as an artist is to paint what you want into the palette map, to determine the colours you get at different levels of lighting. Depending on how well you intuitively grasped my description of how this all works, you might need to play around a bit to get a feel for how this all works. When you have a palette that you want to try out, go into Sprite Lamp and click the 'load palette' button to select a specific file for use as the palette map. Make sure you enable the palette shader to see how it looks. Here are some examples of colouring effects that can be achieved with different palettes, with the palette in the bottom left corner for comparison:

A simple application of some nicer shade and highlight colours
A palette swap to give the zombie a significantly different colour scheme
This one uses a low colour palette for a more retro feel

Final notes: You can probably figure out what the 'palette height in pixels' parameter means at this stage, but note that you should probably make the height a power of two (8, 16, 32, 64, 128, 256, or 512). The setting tops out at 512 because of limitations on how monitors display colour, but if you can come up with some reason why you need a 2048-high colour palette, there's nothing to stop you from resizing the image outside of Sprite Lamp and loading it back in.


The Spine tab

Spine is an animation tool from the fine folks over at Esoteric Software, and due to popular demand you can now load Spine animation files in the Sprite Lamp preview window, complete with dynamic lighting. This is all about previewing your work with dynamic lighting - Sprite Lamp doesn't modify Spine files in any way.

To start with, you'll need to prepare your Spine files as normal - you will need a .json file containing your skeleton/animations/etc, an .atlas file of the same name, and the texture atlas that is referenced by the .atlas file. You'll also need some lighting profiles that match the texture atlas that Spine exported. Because Spine names the texture atlas image file the same as the other files, I took some slight liberties automating the image set loading process - rather than expecting a file that ends with "_Diffuse", Sprite Lamp interprets the referenced texture atlas as the diffuse map and simply appends the other suffixes to it. For instance, your files might be as follows:

AwesomeCharacter.json

AwesomeCharacter.atlas

AwesomeCharacter.png

AwesomeCharacter_Left.png

AwesomeCharacter_Right.png

...and so on. It's up to you to decide how you want to get your images to this stage (more on that later). If you have these files ready to go, click the "Load Spine file" button and select AwesomeCharacter.json. Sprite Lamp will grab all the other relevantly-named files it can find and set them up. You'll need to go through the normal process of generating normal maps before you see your character lit.

Most of the Spine tab is probably self-explanatory. You are able to select an animation to play, and a skin to apply. You can also adjust the speed and direction of the animation's playback.

Spine and depth maps

Unlike conventional sprite graphics, Spine renders characters using multiple pieces of geometry. For this reason, self-shadowing isn't simply a matter of having a depth map to trace along in the shader. Currently, Sprite Lamp is rendering Spine characters in a fairly straightforward way using a modified version of the standard Phong shader, and as such, certain complex lighting effects aren't yet available. For a similar reason, Ambient Occlusion maps can be generated but won't really look right because there won't be any occlusion between Spine attachments - only within them.

In theory, this can be solved by rendering the spine character to a series of render targets, essentially creating a new set of maps (depth, normals, diffuse, etc) every frame, before rendering them with a conventional shader. Thus far, there hasn't been any demand for this feature in Sprite Lamp's preview window, but it could be done. If you're after this feature, or want help getting it working in your game, feel free to get in contact with me via www.snakehillgames.com/contact-me/.

Spine, lighting profiles, and rotation

It seems logical that if you have normal mapping working, and Spine working, then Spine with normal mapping should be trivial. Unfortunately, this isn't quite true. Spine involves drawing a texture map at different orientations, but because the texture map is just a texture map, this is fine - a picture of a person, drawn upside-down, is the same as a picture of an upside-down person. Because a normal map encodes a direction instead of a colour, though, if you rotate a normal map (or a piece of a normal map) you will get the normals referring to incorrect directions. This is a problem, but fortunately it's a solved one, and it's not really the artist's problem anyway - it's just a reason for a slightly more complex shader.

However, conceptually, the problem relates to lighting profiles as well. If you draw an image, like say "ExampleHead_Right", and rotate it 90 degrees clockwise, the resulting image is no longer lit from the right - it's lit from below. Depending on your workflow with Spine and lighting profiles, this can become a problem - specifically, if you draw all your body parts as separate images, create individual normal maps with Sprite Lamp, and then create a texture atlas from those normal maps, make sure that you disable rotation in the atlas creation parameters. An alternative pipeline would be to draw your body parts' diffuse images, turn them into an atlas, and then use that atlas as a basis for drawing the lighting profiles (and then process the whole atlas in one go with Sprite Lamp).

It's possible that, if hand-drawn normal maps become a bigger deal than they currently are, we might see some atlas creation tools that can be told that they're handling normal maps and modify the normals accordingly, but until then, one of the above workflows is recommended.


The depth editing tab (pro only)

Sprite Lamp has the facility to generate depth maps from normal maps. This is generally pretty accurate when it comes to fairly simple images, particularly textures (such as a brick wall). However, there is fundamentally not enough information in a normal map to always accurately create a depth map, and Sprite Lamp has to make certain assumptions. These aren't always correct - this is usually more problematic with complex images such as character art. For this reason, the Pro version of Sprite Lamp has facilities for tweaking the depth map to get better results when accurate self-shadowing is important and the default algorithm doesn't give results you're happy with. While you can start from an empty depth map and use Sprite Lamp to create one from scratch, the recommended workflow is to generate one first, and then tweak it - that way you can make adjustments in broad strokes that will be much quicker to sort out, and let Sprite Lamp do the fiddly details (which it doesn't usually have a problem with). As such, to begin editing a depth map, you will want to load up lighting profiles (a diffuse map can also be useful, as we will see), and generate a normal map and then a depth map. From there, click on the 'Depth editing' tab. Click the 'Depth editing' check mark in the top left of this tab to start. The image in the preview window will change to show something initially resembling the normal map you have created.



This shows the depth editing interface in action. On the right, we can see the example head image being editing, including the display of edges, contours showing the shape of the depth map, and some selection as well. There are two major subsections of the depth editing tab - the 'Edit edges' panel and the 'Edit selection' panel. Further, there are some miscellaneous (but vital) controls outside of these. Note that the 'undo' and 'redo' buttons in this tab apply to all depth editing operations, including edge and selection editing. The shortcuts of control-Z and control-Y also work here. Note that undo/redo currently ONLY work in the depth editing tab, so be careful not to regenerate the depth map over the top of the one you're working on.

Edge editing

Most of the reasons behind Sprite Lamp's depth map generation giving bad results fall into the same category - depth discontinuities. If, say, a character's arm passes in front of their face, their arm will have a depth value that should be quite different from their face. Since Sprite Lamp has no way of knowing this, you're likely to have to manually fix it by selecting the arm pixels and pulling them forward (towards the camera). The selection process is greatly eased by being able to select the boundary between arm pixels and face pixels, which is where edge editing comes in. As seen in the above screenshot, selected edges are shown in red. Note that these edges are between pixels, not on pixels. This distinction is sometimes lost in higher-resolution artwork, but in the case of pixel art it can be very important. Sprite Lamp has two main methods of obtaining edges - detecting them, or painting them directly.

Detecting edges

Sprite Lamp can automatically detect edges based on input images. There are four ways of doing this, but they all work in similar ways - differences between adjacent pixels.

All of these detection buttons work with the checkbox below labeled "Only detect edges within selection". If this is checked, the edge detection algorithms will only operate on pieces of the image that have been selected (see section on editing selections, below).

Painting edges

The edge detection is usually good for getting, broadly, the edges you want. However, often they will leave small gaps, or create extra small edges where you don't want them to be. If you select the "Add Edges" or "Remove Edges" paint mode, you can add or remove edges by left clicking on them in the preview window.

Other edge operations

Remove edge specks: This will delete any edges that exist on your image that aren't connected to any other edges and are only one pixel in length. These isolated edges don't make a great deal of difference to depth generation or selection painting, but they are annoying and make it hard to see what's going on sometimes.

Clear all edges: This somewhat self-explanatory button simply removes all edges that you have created.


Selection editing

Making intelligent selections are important for varying your depth map. It's the selections that are used when you move parts of the depth map forwards or back. Note that selections mostly have to be 'soft' to be useful - a given pixel is selected by a fractional amount between zero and one. The less selected a pixel is, the less affected it is when you drag pixels forward or back.

Selections are made and removed in Sprite Lamp usually by painting directly onto the preview window with the left mouse button (ensure you have 'Add Selection' or 'Remove Selection' selected as the paint mode). The brush you use has a radius, but more importantly, respects edges. This allows you to select the areas that are most useful.

Solid painting radius: This is the radius of the circle that your brush will select at full selection, in pixels.

Painting dropoff: This is the distance in pixels, beyond the edge of the solid painting radius, that the selection will take to fade to nothing. Set this to zero for a hard-edged brush (though this is rarely what you want).

Painting intensity: This is the amount of selection that results within the solid paining radius. Usually set to 1.0, meaning that you paint at 100% selection, but can be set to less.

Select only similar depths: This is a very useful check box - when checked, when you start painting Sprite Lamp will take note of the depth of the pixel you started painting on, and only select pixels of similar depth. This is a common requirement when you have, for instance, a crevice that is too deep - check this box, then start painting in the bottom of the crevice to select only pixels in the crevice. The selection will drop off as the depth moves away from where you started. The slider beneath this check box allows you to choose how wide the range of depths you want to select is.

Grow selection: Clicking this button will expand your selection by one pixel in all directions (respecting edges as it does so).

Growth dropoff: This will determine how much your growth operation reduces the intensity of the selection when it expands into adjacent pixels. For instance, if you set this to 0.1, the grown selection will fade to nothing within ten pixels. This is useful for achieving smooth gradients over long distances.

Clear selection: This deselects all pixels. Edges aren't affected.


Depth operations

Oddly enough, the majority of time spent editing depth maps is all about defining selections, and a lot of defining selections involves defining edges. Once that's all taken care of, though, you have come to the comparatively straightfoward operation of actually editing the depth map.

Move selection forward/back: These buttons will move the selected pixels forward (towards the camera) or back (away from the camera). The slider to their left determines how much of a shift happens. Note that these buttons work whether or not the 'depth editing' checkbox is checked, which can sometimes be useful for directly viewing the effect the changes have on the casting of shadows.

Show depth contour lines: Checking this will cause contour lines to be visible on the image in the preview window (the screenshot at the top of this chapter includes these contours). This can be very useful for determining the shape of the depth map while you're editing it, but sometimes it can get in the way of seeing what edges and pixels you have selected.

Saving your work

Having modified your depth map, it is saved out in the same way as a generated one - flip over to the map generation tab and click the 'Save depth map' button. This works the same if you're including it in the alpha channel of a normal map, or if you're saving it as part of a set in the images tab.


The Anisotropy tab (pro only)

This is another feature exclusive to users of the pro version of Sprite Lamp. Anisotropic highlights are a feature of certain materials that have microfacets that are aligned in roughly the same direction. You see this, for instance, on brushed metal (as the process creates tiny grooves in the surface of the metal), and also on well-looked-after hair. The shader technology to render anisotropic highlights has been around for a while, but the shader requires a map that tells it the orientation of the microfacets at every point. This is the anisotropy map, and it can be quite difficult to create.

To create an anisotropy map in Sprite Lamp, you'll need to draw something that I call a flow map. A flow map is something that artists can draw reasonably easily - it's simply a matter of drawing lots of soft white lines on a black background, and making sure the lines follow the direction of the microfacets. It's important that the lines not be extremely hard-edged, because it gives Sprite Lamp slightly more of a gradient to hook into. Here is an example of a flow map, the anisotropy map that was generated from it, and the lighting that resulted:

Three images demonstrating how anisotropy maps work
Currently the only parameters for the generation of anisotropy maps are the iteration count, and the output type. The iteration count is the number of times that the algorithm expands anisotropy information into pixels without any information. Increasing this count is necessary if the lines in your flow map are very sparse, but it makes the output blurrier as well (which may or may not be desirable). You also have the option of output type - there are three types currently supported.

Standard vector format: The red and green channels make up the x and y components of a vector that points in the direction of the microfacet. This is the easiest form for a shader to make sense of, and as such currently the only form that Sprite Lamp's built in anisotropy shader uses. This method suffers from seams if you are filtering the texture (see note, below).

Angle-doubled vector: The red and green channels still make up the x and y components of a vector, but the vector doesn't point in the direction of the microfacets - it has had its angle 'doubled'. That is, the vector's angle in terms of a unit circle, has been doubled to make use of the full circle. This has the advantage of allowing simple maths to be done on the map via GPU operations like filtering and blurring, but the disadvantage that the angle has to be halved again in the shader to make use of it in a lighting equation.

Orientation angle: This simply keeps the angle, in unit circle terms, in the luminance of a greyscale image. Zero (black) points east, ninety degrees points north, etc. This has the advantage of only using one channel of an image, but has some seam problems and has some costs associated with deriving a vector form in the shader before use in a lighting algorithm.

A technical note about anisotropy values: An important aspect of understanding maths surrounding anisotropy maps is that microfacet direction only ranges across 180 degrees, not 360. This has repercussions when handling maths. For instance, a section of an image with microfacets running north is the same as a section where the microfacets run south - microfacets are bidirectional in this way. However, a vector pointing north and a vector pointing south are not. As such, if we want to 'average' two microfacet values, as often happens in graphical applications, averaging the vectors is not necessarily good enough. A vector pointing north and a vector pointing south will average to the zero vector, but a microfacet pointing north/south and a microfacet pointing south/north are the same thing and should average to the same thing, rather than 'cancelling out' to nothing like opposites would. Most maths done on colours in hardware is fairly simple - blending or filtering, for instance, are simple weighted averages. This falls down when it comes to storing vectors for microfacet direction, however, which leads to lighting seams along the edges of standard vector format anisotropy maps. The angle-doubled format appears to solve these issues, allowing for naive generation of mipmaps or naive filtering to produce correct results - however, it complicates the maths in the shader substantially.


The command line interface (pro only)

So Sprite Lamp can be integrated into automated build processes if necessary, it includes a command line interface from which most (currently excludes lighting renders) of the map generation features can be accessed. Currently, generation of normal, depth, and ambient occlusion maps is supported. The simplest way to use Sprite Lamp's command line interface is using the 'copy params to clipboard' button. In the map generation tab, each set of parameters (normal, depth, and AO) has such a button, and it will automatically copy to the clipboard the necessary command line arguments for the current parameters. This means you can tweak the settings within Sprite Lamp, then copy them straight to a batch file or script or whatever.

In general, a single invocation of Sprite Lamp from the command line loads a single image set, performs some operations, and then saves out some of those results. The user specifies which maps to save, and Sprite Lamp will determine which processes it needs to perform to do that.

The basic form will be "SpriteLamp.exe -source <filename>" where 'filename' is the name of one of the images in the set you want to load. You then specify which outputs you want to save:

Beyond this, each of the processes has parameters that can be set via command line.

Normal generation:

Depth generation:

Ambient occlusion generation:

Palette and index map generation:

Anisotropy map generation: