# DirectX/10.0/Direct3D/Diffuse Lighting

In this tutorial I will cover how to light 3D objects using diffuse lighting and DirectX 11. We will start with the code from the previous tutorial and modify it.
The type of diffuse lighting we will be implementing is called directional lighting. Directional lighting is similar to how the Sun illuminates the Earth. It is a light source that is a great distance away and based on the direction it is sending light you can determine the amount of light on any object. However unlike ambient lighting (another lighting model we will cover soon) it will not light up surfaces it does not directly touch.
I picked directional lighting to start with because it is very easy to debug visually. Also since it only requires a direction the formula is simpler than the other types of diffuse lighting such as spot lights and point lights.
The implementation of diffuse lighting in DirectX 11 is done with both vertex and pixel shaders. Diffuse lighting requires just the direction and a normal vector for any polygons that we want to light. The direction is a single vector that you define, and you can calculate the normal for any polygon by using the three vertices that compose the polygon. In this tutorial we will also implement the color of the diffuse light in the lighting equation.

## Framework

For this tutorial we will create a new class called LightClass which will represent the light sources in the scenes. LightClass won't actually do anything other than hold the direction and color of the light. We will also remove the TextureShaderClass and replace it with LightShaderClass which handles the light shading on the model. With the addition of the new classes the frame work now looks like the following:
We will start the code section by looking at the HLSL light shader.
You will notice that the light shader is just an updated version of the texture shader from the previous tutorial.

## Light.vs

Both structures now have a 3 float normal vector. The normal vector is used for calculating the amount of light by using the angle between the direction of the normal and the direction of the light.
The normal vector for this vertex is calculated in world space and then normalized before being sent as input into the pixel shader.

## Light.ps

We have two new global variables inside the LightBuffer that hold the diffuse color and the direction of the light. These two variables will be set from values in the new LightClass object.
This is where the lighting equation that was discussed earlier is now implemented. The light intensity value is calculated as the dot product between the normal vector of triangle and the light direction vector.
And finally the diffuse value of the light is combined with the texture pixel value to produce the color result.

## Lightshaderclass.h

The new LightShaderClass is just the TextureShaderClass from the previous tutorials re-written slightly to incorporate lighting.
The new LightBufferType structure will be used for holding lighting information. This typedef is the same as the new typedef in the pixel shader. Do note that I add a extra float for size padding to ensure the structure is a multiple of 16. Since the structure without an extra float is only 28 bytes CreateBuffer would have failed if we used a sizeof(LightBufferType) because it requires sizes that are a multiple of 16 to succeed.
There is a new private constant buffer for the light information (color and direction). The light buffer will be used by this class to set the global light variables inside the HLSL pixel shader.

## Lightshaderclass.cpp

Set the light constant buffer to null in the class constructor.
The new light.vs and light.ps HLSL shader files are used as input to initialize the light shader.
The Render function now takes in the light direction and light diffuse color as inputs. These variables are then sent into the SetShaderParameters function and finally set inside the shader itself.
The polygonLayout variable has been changed to have three elements instead of two. This is so that it can accommodate a normal vector in the layout.
We also add a new description variable for the light constant buffer.
Load in the new light vertex shader.
Load in the new light pixel shader.
One of the major changes to the shader initialization is here in the polygonLayout. We add a third element for the normal vector that will be used for lighting. The semantic name is NORMAL and the format is the regular DXGI_FORMAT_R32G32B32_FLOAT which handles 3 floats for the x, y, and z of the normal vector. The layout will now match the expected input to the HLSL vertex shader.
Here we setup the light constant buffer description which will handle the diffuse light color and light direction. Pay attention to the size of the constant buffers, if they are not multiples of 16 you need to pad extra space on to the end of them or the CreateBuffer function will fail. In this case the constant buffer is 28 bytes with 4 bytes padding to make it 32.
The new light constant buffer is released in the ShutdownShader function.
The SetShaderParameters function now takes in lightDirection and diffuseColor as inputs.
The light constant buffer is setup the same way as the matrix constant buffer. We first lock the buffer and get a pointer to it. After that we set the diffuse color and light direction using that pointer. Once the data is set we unlock the buffer and then set it in the pixel shader. Note that we use the PSSetConstantBuffers function instead of VSSetConstantBuffers since this is a pixel shader buffer we are setting.

## Modelclass.h

The ModelClass has been slightly modified to handle lighting components.
The VertexType structure now has a normal vector to accommodate lighting.

## Modelclass.cpp

The only change to the InitializeBuffers function is here in the vertex setup. Each vertex now has normals associated with it for lighting calculations. The normal is a line that is perpendicular to the face of the polygon so that the exact direction the face is pointing can be calculated. For simplicity purposes I set the normal for each vertex along the Z axis by setting each Z component to -1.0f which makes the normal point towards the viewer.

## Lightclass.h

Now we will look at the new light class which is very simple. Its purpose is only to maintain the direction and color of lights.

## Graphicsclass.h

The GraphicsClass now has two new includes for the LightShaderClass and the LightClass.
Render now takes a float value as input.
There are two new private variables for the light shader and the light object.

## Graphicsclass.cpp

The light shader and light object are set to null in the class constructor.
The new light shader object is created and initialized here.
The new light object is created here.
The color of the light is set to purple and the light direction is set to point down the positive Z axis.
The Shutdown function releases the new light and light shader objects.
We add a new static variable to hold an updated rotation value each frame that will be passed into the Render function.
Here we rotate the world matrix by the rotation value so that when we render the triangle using this updated world matrix it will spin the triangle by the rotation amount.
The light shader is called here to render the triangle. The new light object is used to send the diffuse light color and light direction into the Render function so that the shader has access to those values.

## Summary

With a few changes to the code we were able to implement some basic directional lighting. Make sure you understand how normal vectors work and why they are important to calculating lighting on polygon faces. Note that the back of the spinning triangle will not light up since we have back face culling enabled in our D3DClass.

## To Do Exercises

1. Recompile the project and ensure you get a spinning textured triangle that is being illuminated by a purple light. Press escape to quit.
2. Comment out "color = color * textureColor;" in the pixel shader so that the shaderTexture is no longer used and you should see the lighting effect without the texture.
3. Change the color of the light to green at the m_Light->SetDiffuseColor line of code in the GraphicsClass.
4. Change the direction of the light to go down the positive and the negative X axis. You might want to change the speed of the rotation also.