# MonoGame on Windows Phone 8 Lighting and Normal Mapping Your Game

In this article, I will try to explain how to use HLSL and MonoGame for deferred lighting and normal mapping in 2D for Windows Phone 8 games.

Compatibility
Platform(s):
Windows Phone 8
Article
Created: this_is_ridiculous (06 Mar 2013)
Last edited: kiran10182 (11 Mar 2013)

## Introduction

In good old days of Microsoft XNA Game Studio, I was browsing the web in search for good HLSL articles for study purposes. I found one article which was written in Russian here. After some time spent with the code described in the article, I felt comfortable with techniques presented and implemented similar stuff in Windows Desktop version Undead Carnage: Redemption. When I got my hands dirty with MonoGame, a cross platform and open source implementation of XNA 4.0, I felt that I had to do the same for WP8 with MonoGame framework. I knew that in this case the code for both C# and HLSL would not be 100% compatible due to some differences between MonoGame and XNA. And I thought it would be great to share my experience about porting this awesome stuff to MonoGame. So let's start.

## Theory

If you are unfamiliar with MonoGame, I strongly recommend on reading XNA Games On Windows Phone 8 with Monogame and MonoGame on Windows Phone 8 Post-Processing Your Game articles first. These will guide you through getting started with MonoGame and then shader compilation and usage within MonoGame game.

Now let's talk about the techniques we will be using here. These are Deferred Lighting and Normal Mapping.

## OK. Let's assume I Understood That. Then What is Normal Mapping?

Normal mapping is a technique of faking geometry complexity. This technique is used to add details without adding polygons to 3D geometry. A common usage of this is to have tons of details in a low-polygonal geometry (3D model). In other words, this is a 3D graphics trickery that dramatically enhances the overall look of 3D geometry. Normal maps are commonly stored as simple images where R, G and B channels correspond to X, Y and Z coordinates of surface normal. For more information on Normal Mapping technique, please have a look at this article on Wikipedia.

## Practice

So what do we need to have both these techniques in our game?

• First we need MonoGame binaries for Windows Phone 8 which can be obtained from here.
• We need at least two textures preferably of the same size. These will be the color map (or diffuse texture) and the normal map.
• We need at least one source of light. This can be the simplest point light.

We don't need the following at least in our case:

• The actual G-Buffer information. We will not draw any complex 3D geometry or complex scenes to G-Buffer. All we need we will have just after we load our two textures (these will be the diffuse and normal maps)

## Implementation

At the time of porting this code to MonoGame, I had compiled the shader using the 2MGFX tool with /dx11 flag at the first place. But the shader did not compile. The problem was in custom defined parameters inside the shader. There was a
`Light`
structure defined. It nested two
`float3`
and one
`float`
fields. And then it had an array of this structure. That did not compile. So I had to change the array of
`struct`
to three separate arrays to replicate the fields inside the structure. After that the shader compiled successfully. Then I changed the C# code to supply three arrays for lights parameters instead of just one. And after that I added some touch screen controls to be able to manipulate with lights.

You may ask why am I mentioning number three for parameters count. Well, that's because of Shader Model 2.0 limitation. We can have only to 64 arithmetic instructions in pixel shader per pass. And we are actually targeting SM 2.0 for WP8. So just three lights for now. However we can render more than three using multi-pass rendering with just shifting start index in our array of lights. That is not complex. For limitations and comparisons of Shader Models in HLSL, please refer here.

## Let's Take a Look at Results

Diffuse Map Only
Normal Map Only
Just the Lights
Normal Mapping with Deferred Lighting
Normal Mapping with Deferred Lighting with controls

Let's talk about controls. On the last screenshot you can see some buttons.

Let's start from last one with three dots.

0) This button switches the states between controlling lights and controlling their properties. Then we go left to right:

1) R+ / R- increases / decreases the radius of both lights

2) Z+ / Z- increases / decreases the distance between light sources and the our surface (brick wall)

3) C+ / C- increases / decreases the light correction attribute. This serves as a Color multiplier for the actual color of light. Say it changes the power of light source

When the controls panel is turned off you can manipulate with the lights. At this point only red light is controlled by the user. The white light changes it's position by inverting screen space coordinates of the red one. All calculations are done in screen space of size 800x480.

## Summary

In this article we've seen how we can dramatically enhance the overall look of our rendered scene with very small effort thanks to simple shading techniques and ingenious algorithms for indirect lighting (and the creators of these algorithms of course). Other thing that deserves mentioning is inverting of touch locations reported by the TouchPanel. As it's earlier been told we do not get the landscape mode in MonoGame just out of the box. This applies to touch points as well.

## Side Notes

Say you're developing a side scrolling 2D action game. In this case you may this technique almost unchanged. The only changes will be in the rendering itself. If you have a tile map for your level and the same tile map for normal texture (like me :) ) then you should use render targets for the actual diffuse and normal. So on the first pass you draw your scene using normal texture to one render target, then on the second pass you draw the same scene with diffuse texture to another render target. And after that you update your lights, supply the normal target to the shader, apply shader passes and draw your diffuse render target.

To generate normal maps from textures you can use Paint.Net Image editor and a NormalMapPlus plugin

## The Code

There you go! Have fun HLSLing :) File:DeferredNormals.zip

## Thank You

• Many thanks to ForhaxeD from http://habrahabr.ru for the original tutorial
• Even more thanks to MonoGameTeam for creating such a good implementation of XNA and letting it all "Just Work" like in old good times so we can just keep working with our favorite framework.
206 page views in the last 30 days.