Unity 2D dynamic lighting tutorial with custom Sprite DLight shader
While integrating dynamic lighting in a 2D game with Sprite DLight's normal maps, Unity users have reported several issues with the built-in materials and shaders.
With a new custom Sprite DLight shader and a step-by-step tutorial for beginners and advanced Unity users, anyone should now be able to easily improve their 2D game with normal maps.
Danilo Ganzella, backer of Sprite DLight and Game Designer of the game “Tower of Samsara”, wrote the custom shader and the tutorial, which covers all the basics from generating sprite sheets and normal maps to bringing everything together in Unity.
Special thanks to Danilo and his team Martelo Nero™ for sharing the shader and dynamic lighting techniques used in their upcoming platformer "Tower of Samsara", which will be on Kickstarter on May, 3.
The game looks very promising with beautiful pixel art, atmospheric music and a deep and immersive storyline and is definitely worth backing (they are also currently doing a Thunderclap here).
Sprite DLight + Unity: Normal Maps & 2D Dynamic Lighting
This tutorial will show how to properly integrate Sprite DLight’s normal maps with Unity in seven simple steps.
You will be guided through the whole process of using dynamic lighting in your game project, from generating sprite sheets and normal maps to integrating the assets and the provided custom Sprite DLight Shader with Unity.
Step 0 - Create a Unity 2D Project
Skip this step if you already have some experience with Unity 2D.
Download and open Unity and create a new 2D Project.
This will create 4 folders in the directory of your new project.
The folder that matters to us is the Assets folder. This is where all the assets (images, sounds, materials, etc) of your project will go.
Inside Unity, every section of what you see is called a window. Defaults are: Hierarchy, Scene, Game, Inspector Project and Console. The asset folder can be accessed through the Project Window. Note that all changes made to the Assets folder outside of Unity, like adding new files or creating new subfolders will be automatically imported when you open Unity.
Step 1 - Building your sprite sheet
Generating a sprite sheet is the easier way to pack animations, for example, of a character or an enemy.
First, choose your preferred sprite sheet generation tool. You can use a free tool like stitches or a commercial tool like the popular TexturePacker (whose creator is also a backer of Sprite DLight).
If you choose a free tool, pick the resulting sprite sheet PNG and put it inside your Unity project Assets folder.
To make the slicing in Unity easier, make all frames the same size so you can use automatic slicing: more details here.
If you choose Texture Packer, follow its generating and importing instructions here.
Either way, you should end up with the sprite sheet PNG file inside your Unity project Assets folder. Click on it on the Project View, it should show something like this on the Inspector View:
Now you will need to slice it in the Sprite Editor.
Texture Type has to be “Sprite” and Sprite Mode “Multiple”.
Click the Sprite Editor Button to open the Sprite Editor and click Slice in the top left corner to choose the slicing mode. After applying the settings, you return to the Inspector with a properly sliced sprite sheet.
In this example, I set the Filter Mode to “Point” because I am working with pixel graphics, and 20 pixels per unit because of the game’s scale. You should adjust these two variables to fit your needs.
Step 2 - Generating the normal map
Now open the sprite sheet in Sprite DLight and let the tool generate the normal map.
Adjust the in-app settings according to your needs (note that the alpha channel of the normal map will be ignored by Unity), then export the normals:
Back in Unity, be sure to put the generated normal map and the original sprite sheet file into the same folder, anywhere inside your project Assets folder. Click on the normal map and set Texture Type to “Normal map” and Wrap Mode to “Clamp”.
Step 3 - Adjusting the default materials - Layer Order
The first thing you need to know about is the concept of layer ordering.
Unity has a bug that makes the layering order of the default Sprites/Default material not work with any user-created material (should it be of shader Sprites/Default or any other shader).
So first you need to create a new Sprites/Default material (Assets->Create->Material) inside the Assets folder, name it anything (I’ll name mine User-Created-Sprites-Default), and change all your sprites of the current scene that will not use dynamic lightning to this material in order to make the layering order work with the custom material we will be creating in the next steps.
Click on your current sprite game objects, and on the “Sprite Renderer” tab in the Inspector. Any of your sprites that use the Sprites-Default material, like this one:
Should now use the newly created material:
Step 4 - Importing the Sprite DLight Custom Sprite Shader
You can download the SpriteDLight Shader here!
Open the ZIP and put the files anywhere in the Assets Folder of your Unity Project. Close and open Unity to make sure it will be loaded.
Step 5 - Creating the Unity custom material
Create a Unity material (Assets->Create->Material) anywhere inside the Assets folder. Set its shader from Standard to Sprites -> SpriteDLight.
Drag & Drop the normal map file generated by Sprite DLight onto the Normal Map field, and the Toon Ramp file on the Cel Shading ramp field:
You may change the toon ramp sprite to create other Cel-Shading effects or completely turn Cel-Shading off with the checkbox.
Like in the normal map tuning options of Sprite DLight, you can also change the Normal Scale multiplier inside Unity to adjust the intensity of the normal map, most likely it will be used from 0 to 2, with 1 being exactly as exported from Sprite DLight.
This custom SpriteDLight shader is lit, which means that the Ambient Light will affect its value. Check Window/Lighting to adjust the ambient light.
Step 6 - Create the Sprite
Create a sprite game object in Unity (GameObject -> 2D Object -> Sprite).
Set its material to the custom SpriteDLight material created in the previous step.
Set the Sprite to the original sprite. If using a sprite sheet (multiple-sprite), don't forget to pick the sprite inside the sprite sheet.
You may now animate using the animator, always selecting the sprite inside the multiple-sprite.
Step 7 - Create the Lights
Now for the fun part, you may add any Unity Lights: point, spot or ambient, and they will now illuminate the sprite.
Be sure that the range of the point and spot lights are within the sprite, because Z-distance will also count.
Edited by Dennis Faas (2deegameart.com)
Please feel free to post any questions here!