# DirectX/10.0/Direct3D/Multitexturing and texture arrays

This tutorial will cover how to do multitexturing in DirectX 11 as well as how to implement texture arrays in DirectX 11. Multitexturing is the process of blending two different textures to create a final texture. The equation you use to blend the two textures can differ depending on the result you are trying to achieve. In this tutorial we will look at just combining the average pixel color of the two textures to create an evenly blended final texture.
Texture arrays is a new feature since DirectX 10 that allows you to have multiple textures active at once in the gpu.
Past methods where only a single texture was ever active in the gpu caused a lot of extra processing to load and unload textures all the time.
Most people got around this problem by using texture aliases (loading a bunch of textures onto one large texture) and just using different UV coordinates.
However texture aliases are no longer needed with this new feature.
The first texture used in this tutorial we will call the base texture which looks like the following:
The second texture we will use to combine with the first one will be called the color texture. It looks like the following:
These two textures will be combined in the pixel shader on a pixel by pixel basis. The blending equation we will use will be the following:
Using that equation and the two textures we will get the following result:
Now you may be wondering why I didn't just add together the average of the pixels such as the following:
The reason being is that the pixel color presented to us has been corrected to the gamma of the monitor. This makes the pixel values from 0.0 to 1.0 follow a non-linear curve. Therefore we need gamma correction when working in the pixel shader to deal with non-linear color values. If we don't correct for gamma and just do the average addition function we get a washed out result such as this:
Also note that most devices have different gamma values and most require a look up table or a gamma slider so the user can choose the gamma settings for their device. In this example I just choose 2.0 as my gamma value to make the tutorial simple.
We'll start the code section by first looking at the new multitexture shader which was originally based on the texture shader file with some slight changes.

## Multitexture.vs

The only change to the vertex shader is the name.

## Multitexture.ps

We have added a two element texture array resource here for the two different textures that will be blended together. Texture arrays are more efficient that using single texture resources in terms of performance on the graphics card. Switching textures was very costly in earlier versions of DirectX forcing most engines to be written around texture and material switches. Texture arrays help reduce that performance cost.
The pixel shader is where all the work of this tutorial is done. We take a sample of the pixel from both textures at this current texture coordinate. After that we combine them using multiplication since they are non-linear due to gamma correction. We also multiply by a gamma value, we have used 2.0 in this example as it is close to most monitor's gamma value. Once we have the blended pixel we saturate it and then return it as our final result. Notice also the indexing method used to access the two textures in the texture array.

## Multitextureshaderclass.h

The multitexture shader code is based on the TextureShaderClass with some slight modifications.

## Multitextureshaderclass.cpp

The multitexture HLSL shader files are loaded here in the Initialize function.
Shutdown calls the ShutdownShader function to release the shader related interfaces.
The Render function now takes as input a pointer to the texture array. This will give the shader access to the two textures for blending operations.
The InitializeShader function loads the vertex and pixel shader as well as setting up the layout, matrix buffer, and sample state.
The multitexture vertex shader is loaded here.
The multitexture pixel shader is loaded here.
ShutdownShader releases all the interfaces that were setup in the InitializeShader function.
The OutputShaderErrorMessage function writes out an error to a file if there is an issue compiling the vertex or pixel shader HLSL files.
SetShaderParameters sets the matrices and texture array in the shader before rendering.
Here is where the texture array is set before rendering. The PSSetShaderResources function is used to set the texture array. The first parameter is where to start in the array. The second parameter is how many textures are in the array that is being passed in. And the third parameter is a pointer to the texture array.
The RenderShader function sets the layout, shaders, and sampler. It then draws the model using the shader.

## Texturearrayclass.h

The TextureArrayClass replaces the TextureClass that was used before. Instead of having just a single texture it can now have multiple textures and give calling objects access to those textures. For this tutorial it just handles two textures but it can easily be expanded.
This is the two element texture array private variable.

## Texturearrayclass.cpp

The class constructor initializes the texture array elements to null.
Initialize takes in the two texture file names and creates two texture resources in the texture array from those files.
The Shutdown function releases each element in the texture array.
GetTextureArray returns a pointer to the texture array so calling objects can have access to the textures in the texture array.

## Modelclass.h

ModelClass has been modified to now use texture arrays.
The TextureArrayClass header file is included instead of the previous TextureClass header file.
We now have a TextureArrayClass variable instead of a TextureClass variable.

## Modelclass.cpp

I will just cover the functions that have changed since the previous tutorials.
We initialize the new TextureArray variable in the class constructor.
We call the LoadTextures function which takes in multiple file names for textures that will be loaded into the texture array and rendered as a blended result on this model.
ReleaseTextures is called to release the texture array in the Shutdown function.
We have a new function called GetTextureArray which gives calling objects access to the texture array that is used for rendering this model.
LoadTextures has been changed to create a TextureArrayClass object and then initialize it by loading in the two textures that are given as input to this function.
The ReleaseTextures function releases the TextureArrayClass object.

## Graphicsclass.h

The header for the MultiTextureShaderClass is now included in the GraphicsClass.
Here we create the new MultiTextureShaderClass object.

## Graphicsclass.cpp

We will cover just the functions that have changed since the previous tutorials.
We initialize the new multitexture shader object to null in the class constructor.
The ModelClass object is now initialized differently. For this tutorial we load in the square.txt model as the effect we want to display works best on just a plain square. We also now load in two textures for the texture array instead of just a single texture like we did in previous tutorials.
Here we create and initialize the new multitexture shader object.
We release the multitexture shader in the Shutdown function.
We set the position of the camera a bit closer to see the blending effect more clearly.
We use the new multitexture shader to render the model. Notice that we send in the texture array from the ModelClass as input to the shader.

## Summary

We now have a shader that will combine two textures evenly and apply gamma correction.
We also now know how to use texture arrays for improved graphics performance.

## To Do Exercises

1. Recompile the code and run the program to see the resulting image. Press escape to quit.
2. Replace the two textures with two new ones to see the results.