---
title: "How to create light effects in Phaser 3"
description: "Learn how to create dynamic light effects with Phaser 3. Add depth to your flat 2d sprites with normal maps."
canonical: "https://www.codeandweb.com/spriteilluminator/tutorials/how-to-create-light-effects-in-phaser3"
date: "2022-01-02T00:00:00.000Z"
modified: "2022-01-02T00:00:00.000Z"
source: "html"
---

# How to create light effects in Phaser 3

Joachim Grill

[spriteilluminator](https://www.codeandweb.com/tags/spriteilluminator),  [phaser](https://www.codeandweb.com/tutorials/phaser.md),  [tutorial](https://www.codeandweb.com/tags/tutorial)

[GitHub](https://github.com/CodeAndWeb/Phaser3-Lighting)

![How to create light effects in Phaser 3](https://www.codeandweb.com/static/2bf0c7070239df9b1a3ff0980527f455/a6312/_opengraph-image.png)

## Light demo

This demo shows how you can enhance a 2d sprite with normal maps to create real time light effects.

Move your mouse over the demo to change the light position.

## Prerequisites

#### You already have normal maps for your sprites.

To learn how to create normal maps have a look at [this tutorial](https://www.codeandweb.com/spriteilluminator/tutorials/normal-map-painting-with-spriteilluminator.md). For more details about the [SpriteIlluminator](https://www.codeandweb.com/spriteilluminator.md) tool visit its [documentation page](https://www.codeandweb.com/spriteilluminator/documentation.md).

#### Sprite sheets require a corresponding normal map sheet

The sprite sheet containing the normal maps must be packed with the same layout as the sheet containing the sprite images. [TexturePacker](https://www.codeandweb.com/texturepacker.md) has a dedicated mode to support this. [This tutorial](https://www.codeandweb.com/texturepacker/tutorials/packing-normal-map-sprite-sheets.md) describes normal map packing in detail.

## Throw light on your sprite

To load a sprite image together with its normal map, the file names of the image and its normal map are passed to `this.load.image()` as an array. In the following example the normal maps are marked with a `_n` suffix.

After loading the images, the sprite can be placed as usual. To enable dynamic lighting the corresponding shaders are activated using `setPipeline('Light2D')`. **Important:** Light effects require a browser with WebGL support.

```js
function preload()
{
    this.load.image('character', ['assets/character/01.png', 'assets/character/01_n.png']);
}

function create()
{
    var character = this.add.sprite(250, 300, 'character');
    character.setPipeline('Light2D');
}
```

As we haven't added any light source yet, the scene remains black. Add these to lines to the `create()` function to switch on a light:

```js
    var light  = this.lights.addLight(500, 250, 200);
    this.lights.enable().setAmbientColor(0x555555);
```

This adds a point light at position (500,250) with radius 200. The ambient light increases the brightness of all pixels of the scene, independent of the position of the point light.

## How to use sprite sheets with normal maps

For sprite sheets the normal maps must also be packed on a sheet. TexturePacker automatically stores the file names of the textures in the generated JSON file, a simple call of `load.multiatlas()` loads both and links the normal map sheet to the sprite image sheet:

```js
function preload()
{
    this.load.setPath('assets/');
    this.load.multiatlas('character_sheet', 'character.json');
}
```

Adding sprites and animations works as usual, it's just the `setPipeline('Light2D')` call which is additionally needed to enable lighting:

```js
    // add sprite from sheet
    var character_anim = this.add.sprite(550, 300, 'character_sheet', '01');
    character_anim.setPipeline('Light2D');

    // play animation
    var frameNames = this.anims.generateFrameNames('character_sheet', { start: 1, end: 8, zeroPad: 2 });
    this.anims.create({ key: 'walk', frames: frameNames, frameRate: 10, repeat: -1 });
    character_anim.anims.play('walk');
```

## Play around with it

To illuminate the sprites from different directions we attach the light position to the mouse pointer:

```
    this.input.on('pointermove', function (pointer) {
        light.x = pointer.x;
        light.y = pointer.y;
    });
```

## Finally

That's all for this tutorial. You should now have learned how you use normal maps for dynamic lighting and how to use sprite sheets with normal maps.

## Structured data

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "How to create light effects in Phaser 3",
  "author": [
    {
      "@type": "Person",
      "name": "Joachim Grill"
    }
  ],
  "dateModified": "2022-01-02T00:00:00.000Z",
  "image": "/static/2bf0c7070239df9b1a3ff0980527f455/a6312/_opengraph-image.png"
}
```
