Tag Archives: Unity

Multiple sprite sheets, Sprite Lamp, and Unity

So I mentioned yesterday that I’ve been working on a small tech demo in Unity, to help make sure I notice all the difficulties that can come up with Sprite Lamp, and the first one that has presented itself is the issue of animating with multiple (sets of) sprite sheets. A few people asked me about this already but I didn’t quite have my head in the game enough to give good answers. Hopefully now that I’ve played with it a bit more directly, I can do better.

Here’s the script referenced in this post.

Oh and before I go on, a quick annoying reminder that Sprite Lamp is at 30% off on Steam as I write this!

Animations with a single sprite sheet

The simple situation for frame animation in Unity is one big sprite sheet. This is, I suspect, reasonably common – especially with people working with pixel art, and textures going up to 4096×4096. Someone in this situation who wants to use Sprite Lamp is in a pretty easy situation in terms of programming – essentially, everything just works easily. You’ll want to make a sprite sheet of the diffuse channel, cut it up with Unity’s sprite editor, create animations, and apply them to a game object with an animation controller. So far, everything is normal. Then, you’ll want to create a corresponding normal map sprite sheet with Sprite Lamp (either using whatever texture packer tool you want, though be wary of rotating normal maps, or by drawing the lighting profiles in sprite sheet positions then processing them all at once). You don’t need to cut this up into sprites in Unity after you’ve imported it. Then, apply a Sprite Lamp (or other) material to your game object, drag the normal map sprite sheet into the NormalDepth slot, and everything should be fine.

The reason this works smoothly is because if you have one big sprite sheet, all the animation system is changing is the UVs on the sprite, and because the Sprite Lamp shader doesn’t do anything fancy with UVs, it’ll just look up into each sheet in the same spot.

Multiple sprite sheets

This is where things get tricky. The issue is that Unity’s animation controller automatically switches textures as necessary, but it only provides for switching the main texture, because usually you only have one texture when you’re doing this kind of animation. By way of example, say you have a character who can walk or run. If you’re making a normal 2D game without lighting, you might have two textures: WalkSheet, and RunSheet. Ordinarily, when your character is walking around, Unity will be switching between sprites in one sheet, and thus changing the UVs – but when your character switches to running, Unity has to switch to the RunSheet texture, which it does automatically.

Suppose instead though, you are using Sprite Lamp, so you have six textures. WalkSheet, WalkSheet_Normal, WalkSheet_Emissive, RunSheet, RunSheet_Normal, and RunSheet_Emissive. Your character starts walking around fine, with WalkSheet, WalkSheet_Normal, and WalkSheet_Emissive applied – all is well. Then they break into a run though, and we’re screwed. The animation system switches the diffuse texture to RunSheet, but the normal and emissive channels keep the Walk versions. This will look somewhere between pretty broken and horribly broken, depending on whether or not the walk and run sheets have similar layouts.

How to get around this? Well, essentially, I’ve written this script. It’s still not tested all that much, so I haven’t added it to the official Unity pack yet, but it has worked in my use case and will hopefully work in yours (if not, let me know). The script works by creating a dictionary at load time, which uses a texture as its key, to look up the corresponding textures. Then in the update, it will check the object it’s attached to to see if the texture it’s using has changed – if it has, it automatically sets all the other textures.

To use it, the first thing to do is attach it to your character (or whatever). Second, you have to populate some lists – this is currently done manually, but I’m looking into nicer ways to handle this.  The lists are ‘primaryTextures’ and ‘otherTextures’. Into ‘primaryTextures’, drag all the sprite sheets that your AnimationController knows about – so in our above example, that would be WalkSheet and RunSheet. In the ‘otherTextures’ list, you’ll want to drag all the auxiliary stuff Sprite Lamp uses – here, that would be ‘WalkSheet_Normal’, ‘WalkSheet_Emissive’, ‘RunSheet_Normal’, and ‘RunSheet_Emissive’. For each element of ‘primaryTextures’, the script will search for any textures in ‘otherTextures’ that are suitably named, and associate them so that they get set at runtime.

That should be just about it! As always with Unity things, if I’ve missed some obvious smarter way to do this, please let me know. Also, I’ll be along soon with a more concrete example of this method that you can download, in case my description here doesn’t make things clear.

Coming up next…

The other problem I rapidly ran into here is the problem of ‘light sources’ that exist in the emissive texture map. They tend to move around within the sprite, and you’ll likely want an actual light source to move with it, but the engine doesn’t know how to move it appropriately. I’m working on a script that will automatically parse an emissive map and approximate clusters of bright pixels by creating a light of the appropriate intensity/colour/position. It’s at proof-of-concept-ish stage now and isn’t ready to distribute just yet, but so far it looks pretty cool, particularly by matching the light’s movement to the animation’s framerate.

Obscure Unity/Surface Pro 2 problem solved

Okay so this is a post that has little to do with Sprite Lamp. In fact, it’s probably not interesting to most people who have subscribed – sorry about that. It’s about an obscure problem I had today that I seem to have fixed, but couldn’t really find anything about it online. So I post it here, on the off chance that someone else has the problem and maybe googles their way to this page, and maybe can waste slightly less time on it than I did.

I’m using a Surface Pro 2 (the 256GB model, though I doubt that matters), and was going to do some work in Unity3D. I hadn’t run Unity for a little while, and when I fired it up today, it had some problems. Specifically, lots of messed up visual stuff. Unfortunately I didn’t get a screenshot, but to my eye it looked like some fairly low level VRAM corruption of some kind… within the Unity Editor, various things were messed up, including button and other UI graphics being busted, text was garbled and screwy, and various texture previews were busted. Interestingly, it seemed to also screw up some of the actual game assets when rendering in the viewport.

Anyway, I tried the usual raindances, restarted Unity, restarted Windows, etc. to no avail. My graphics drivers were up to date, so that seemed all good. However! Long story short, a couple of people have reported that using Intel’s generic drivers rather than the ones Microsoft provides with Windows Update can help with some gaming applications (plus it gives you a control panel to mess with certain options), and I had actually done this on my Surface some time ago – but, I had since reinstalled the OS and obliterated the changes. Also, Unity never used to have this problem… curious. So, I got myself over to Intel’s driver page, navigated to the HD4400 area, and got the drivers from there. And that seems to have fixed it! Happy Unity shader editing since then, and all is well in the world. So if, by chance, I’m not the only person to have ever had this issue, and one of the other poor souls happen to wander here in their confusion, there you go. It’s what worked for me, anyway.

Engine integration so far

Hi folks! I’ve been spending some time lately investigating a few of the most commonly requested engines for Sprite Lamp integration – namely Unity, Game Maker, and Construct2. The results so far have been pretty positive – I’m hoping to get at least some support for these three engines made public before I head to GDC. With this article, hopefully people who have been wondering about these three engines will come away with a better idea of what will be possible.

Unity

So, Unity takes the lead as most commonly requested (even though I think mostly people assume it goes without saying). Fortunately, despite it being used for 2D games very often, it is a 3D engine, and that means it has a lighting engine, which means this will be both a smooth integration and a feature-complete one.

As some may have seen, this article by Steve Karolewics of Indreams Studios details an initial attempt at getting Sprite Lamp lighting working in Unity. Steve (along with everyone else who has ever used Unity for anything) knows more about Unity than I do, and I’ve taken his work as a base for the full shader (currently a work in progress). So far, I’ve been working on the hardest part – self-shadowing. Here’s progress so far (hint: it’s working).

The light on the left is closer to the stone wall than the one on the right, which affects shadow length and attenuation.
The light on the left is closer to the stone wall than the one on the right, which affects shadow length and attenuation.

The big part that remains to be done here is that the Sprite Lamp shader has to know the resolution of the textures (for per-texel lighting and for shadowing). At present (for the above screenshot) it’s just hardcoded, but obviously that’s not a long term solution – I’m going to write a little script that runs at load time that sets up the relevant shader variables automatically, so the user doesn’t have to worry about it.

The important thing to note with the Unity integration is that, as mentioned, it already has a lighting system. Light entities already exist in the game, and they will work with Sprite Lamp as you’d expect. Multiple lights work as expected, and Unity will automatically handle stuff like calculating which lights affect a given object. You can also place lights in 3D space (that is, vary their depth position) and have everything work as expected, because as mentioned, Unity is at its heart a 3D engine.

Basically, everything that can be done in the Sprite Lamp preview window is going to be achievable in Unity. Other features that I will most likely add at some point will be support for tessellation (making use of the depth map) which might be cool for the sake of parallax or 3D, and (pending further investigation) support for the deferred rendering pipeline.

Game Maker

I often say that I don’t have a clue about Unity, and that’s pretty much true, but I have at least used it before. That is not the case with Game Maker – I literally opened it for the first time the other day to investigate stuff. It’s therefore possible that I’m missing obvious things – if so, please let me know!

That said, the results of this investigation have been positive. The short answer is, lighting is go:
GameMakerSL

This might not look like much, and it’s not as far along as the Unity integration, but the important thing is that I can load my own custom shader – from here on in, being able to get cel shading and self shadowing working is kind of just details.

At present, there’s some boilerplate scripts that go along with this too – one that you’ll attach to the Create event of your dynamically lit objects and one that goes with the Draw event – which sets appropriate shader variables and that kind of stuff. My understanding is that Game Maker is actually usable without any custom scripts at all, so for the benefit of users who aren’t scripters, I’ll keep the interface with that script as small as possible and document thoroughly any interactions you have to do with it. They’ll almost certainly be very simple – stuff like setting light levels, etc.

That brings me to the next part of this. Unlike Unity, Game Maker doesn’t have a lighting engine built in – this means that there aren’t, for instance, native entity types for stuff like light sources. At this point, I don’t understand the engine well enough to know what the best solution to this is, but it should at least be possible to have a dummy object that acts as a light source, and then tell the scripts on the lit objects to update their shader variables based on the position of the dummy object.

Slightly more complicated is the question of multiple light sources. At the very least, it is simple to have an hemispheric ambient light and a single point light at any given time. I can also add a few more lights by just making the shader more complex (basically, have multiple shader variables for multiple light positions, and add the results together in the shader). However, having an arbitrary number of light sources becomes more complicated – this will involve building a system that automatically tracks lights and what objects they’re close enough to have an effect on. For the moment, my first release of the integration with Game Maker will be the shader and code snippets necessary to get basic lighting going. I’d rather get a basic implementation going for multiple engines, then return to more in depth work like that later if it’s in high demand.

Construct2

This is the least advanced and most recent investigation I’ve done, but I know a few important things so far, and I wanted to pass them on. I’ve also been in touch with one of the developers of the engine, which helped a lot.

Basically, the way Construct2 works doesn’t naturally lend itself to this kind of thing, because of course a 2D engine designed for ease of use isn’t designed with 3D lighting in mind. But, it can be done, with a few caveats.

The rendering engine of Construct2 works, simply enough, by drawing sprites. In addition to regular sprites, you can draw effect sprites – these have shaders attached to them, and are often used for things like colour shifts and distortion effects. They also have a texture attached to them, and can sample the colour of what they’re drawn over. We can leverage this to make some lighting effects.

My first attempt is based on a shader by a developer named Pode. Here goes:
ConstructLighting

So far so good. The folks from Scirra tell me there’s a built in bump map shader that would be a good basis for me to work from too, which works in a slightly different way (the above example multiplies the effect result with the underlying colour, but you can also directly sample the underlying colour and render the result over the top).

From here, given access to the shader, I can get a lot of Sprite Lamp’s lighting effects going. The things I said in the last two paragraphs on Game Maker apply to Construct2 as well, regarding multiple lights and dummy objects and whatnot.

However, there’s another issue with Construct2 that is a limiting factor – namely, an effect sprite can only have one texture attached to it. Now, the Sprite Lamp shader makes use of a lot of textures, some more necessary than others. The diffuse texture is taken care of – the diffuse channel will be contained in the layer underneath, rendered before the effect sprite. Obviously normal maps are required. If shadows are required, the depth map can probably be squished into the alpha channel of the normal map, except insofar as you will also need that alpha channel for opacity (since it’s a separate sprite) – possibly this can be worked around, however. Emissive maps can simply be rendered as another additive layer for objects that have them – you won’t even need a special shader for that. However, ambient occlusion and specularity/gloss maps might have to be sacrificed.

There is a possible workaround here that involves putting multiple textures into one (that is, literally just the diffuse and normal maps next to each other in one image, for instance) and then extracting them with uv maths in the shader. If this turns out to be worthwhile, I’ll add an option to Sprite Lamp to automate exporting maps in this form. However, I foresee visual issues if this is used on tiling textures if your game has a camera that zooms in and out (bilinear filtering and mipmaps will not be kind in this situation).

The other possible issue is performance. Shader complexity not withstanding, this system requires you to draw at least two sprites for every game entity that needs dynamic lighting. I don’t have much of a feel for how performance gets limited in Construct2, but as an educated guess, if your game already has (or almost has) performance issues relating to the number of sprites on screen at a time, they will probably get worse if you add dynamic lighting to them all – my guess is that this will be a load on the CPU and the GPU.

One last thing to note about Construct2 that the devs warned me about is the renderer. Everything I’ve said here is completely dependent on shader effects, which require a WebGL renderer. Unfortunately, this means that environments that use canvas2d instead won’t have access to any dynamic lighting effects (notably, Internet Explorer and Safari, apparently). Sorry about that – that’s out of my (and Scirra’s) hands.

Other engines

If you’re reading all this wondering when I’ll get to your engine – don’t worry, this isn’t a complete list. It just made the most sense to approach the most commonly requested engines first, but a minimal implementation doesn’t take a terribly long time (assuming it’s possible) for a given engine. Even if it’s an obscure engine that I’m not going to do an official engine for, I’m entirely happy to help you out with getting it up and running yourself. Feel free to give a shout regarding the engine you want looked at (besides these three) in the comments.