# DirectX/10.0/Direct3D/Specular Lighting

This tutorial will be an introduction to using specular lighting in DirectX 11 with HLSL. The code in this tutorial builds on the code from the previous tutorial.
Specular lighting is the use of bright spot highlights to give visual clues for light source locations. For example a red sphere with just ambient and diffuse lighting looks like the following:
Now if we add a white specular highlight we get the following result:
Specular lighting is most commonly used to give light reflection off of metallic surfaces such as mirrors and highly polished/reflective metal surfaces. It is also used on other materials such as reflecting sunlight off of water. Used well it can add a degree of photo realism to most 3D scenes.
The equation for specular lighting is the following:
We will modify the equation to produce just the basic specular lighting effect as follows:
The reflection vector in this equation has to be produced by multiplying double the light intensity by the vertex normal. The direction of the light is subtracted which then gives the reflection vector between the light source and the viewing angle:
The viewing direction in the equation is produced by subtracting the location of the camera by the position of the vertex:
Lets take a look at the modified light shader to see how this is implemented:

## Light.vs

We add a new constant buffer to hold camera information. In this shader we require the position of the camera to determine where this vertex is being viewed from for specular calculations.
The PixelInputType structure is modified as the viewing direction needs to be calculated in the vertex shader and then sent into the pixel shader for specular lighting calculations.
The viewing direction is calculated here in the vertex shader. We calculate the world position of the vertex and subtract that from the camera position to determine where we are viewing the scene from. The final value is normalized and sent into the pixel shader.

## Light.ps

The light buffer has been updated to hold specularColor and specularPower values for specular lighting calculations.
The PixelInputType structure is modified here as well to reflect the changes to it in the vertex shader.
The reflection vector for specular lighting is calculated here in the pixel shader provided the light intensity is greater than zero. This is the same equation as listed at the beginning of the tutorial.
The amount of specular light is then calculated using the reflection vector and the viewing direction. The smaller the angle between the viewer and the light source the greater the specular light reflection will be. The result is taken to the power of the specularPower value. The lower the specularPower value the greater the final effect is.
We don't add the specular effect until the end. It is a highlight and needs to be added to the final value or it will not show up properly.

## Lightshaderclass.h

The LightShaderClass has been modified from the previous tutorial to handle specular lighting now.
We add a new camera buffer structure to match the new camera constant buffer in the vertex shader. Note we add a padding to make the structure size a multiple of 16 to prevent CreateBuffer failing when using sizeof with this structure.
The LightBufferType has been modified to hold a specular color and specular power to match the light constant buffer in the pixel shader. Pay attention to the fact that I placed the specular power by the light direction to form a 4 float slot instead of using padding so that the structure could be kept in multiples of 16 bytes. Also had specular power been placed last in the structure and no padding used beneath light direction then the shader would not have functioned correctly. This is because even though the structure was a multiple of 16 the individual slots themselves were not aligned logically to 16 bytes each.
We add a new camera constant buffer here which will be used for setting the camera position in the vertex shader.

## Lightshaderclass.cpp

Initialize the new camera constant buffer to null in the class constructor.
The Render function now takes in cameraPosition, specularColor, and specularPower values and sends them into the SetShaderParameters function to make them active in the light shader before rendering occurs.
We setup the description of the new camera buffer and then create a buffer using that description. This will allow us to interface with and set the camera position in the vertex shader.
Release the new camera constant buffer in the ShutdownShader function.
The SetShaderParameters function has been modified to take as input cameraPosition, specularColor, and specularPower.
Here we lock the camera buffer and set the camera position value in it.
Note that we set the bufferNumber to 1 instead of 0 before setting the constant buffer. This is because it is the second buffer in the vertex shader (the first being the matrix buffer).
The light constant buffer now sets the specular color and specular power so that the pixel shader can perform specular lighting calculations.

## Lightclass.h

The LightClass has been modified for this tutorial to include specular components and specular related helper functions.

## Graphicsclass.h

The header file for the GraphicsClass has not changed for this tutorial.

## Graphicsclass.cpp

In the light class object we now set the specular color and the specular power. For this tutorial we set the specular color to white and set the specular power to 32. Remember that the lower the specular power value the greater the specular effect will be.
The light shader render function now takes in the camera position, the light specular color, and the light specular power.

## Summary

With the addition of specular lighting we now get a bright white flash each time the cube surface evenly faces the camera viewing direction.

## To Do Exercises

1. Recompile and run the project and ensure you get a spinning cube that flashes a bright specular highlight each time if faces the camera.
2. Change the direction of the light such as m_Light->SetDirection(1.0f, 0.0f, 1.0f) to see the effect if the light source is from a different direction.
3. Create a 5000+ poly sphere model with a red texture to recreate the sphere images at the top of the tutorial.