Materials and Shaders

Shaders are short programs which define how the GPU should render incoming vertex and pixel data. A Shader on its own does not have the necessary knowledge of state to accomplish anything of value. It requires inputs such as diffuse textures, normal maps, colors, and so on, and must decide what Render State variables are required in order to complete its intended task.

Unity's Material system is essential to providing this information to our Shaders. Ultimately, this just means a Shader is dependent upon a Material in order to be used to render an object. Every Shader needs a Material, and every Material must have a Shader. Even newly imported meshes that are introduced into the Scene without any assigned Materials are automatically assigned a default (hidden) Material, which gives them a basic diffuse Shader and a white coloration. So, there is no way of getting around this relationship.

Note

A single Material can only support a single Shader. The use of multiple Shaders on the same mesh requires separate Materials to be assigned to different parts of the same mesh.

These two systems capture the majority of the Render State variables we discussed in the previous section. As a result, if we can minimize the number of Materials being used to render the Scene, then we minimize the amount of Render State changes required, and hence reduce the amount of time the CPU spends preparing the GPU each frame.

Let's begin with a simple Scene in order to visualize the behavior of Materials and batching. But, before we start, we should disable several global options for rendering features to avoid distracting ourselves with advanced rendering features:

  • Navigate to Edit | Project Settings | Quality and set Shadows to Disable Shadows (or select the default Fastest quality level)
  • Navigate to Edit | Project Settings | Player, open the Other Settings tab, and disable Static Batching, Dynamic Batching, and GPU Skinning if they are enabled

    Tip

    The Static Batching and GPU Skinning options are not available in Unity 4 Free Edition, and require an upgrade to Unity 4 Pro Edition.

Next, we'll create a Scene that contains a single Directional Light and eight meshes; four cubes, and four spheres, where each object has its own unique Material, position, rotation, and scale:

Materials and Shaders

If we observe the Batching value in the GameView's Stats popup, we see nine total batches (note that this value will be labeled Draw Calls in the Unity 4 Stats popup). Unless the Camera's Clear Flags setting is set to Don't Clear, then one batch will be consumed drawing the Camera background. This could be the Scene's Skybox or a single quad that fills the screen with all pixels colored as per the Camera's Background color property.

The next eight batches are used to draw our eight objects. In each case, the Draw Call involves preparing the rendering system using the Material's properties and asking the GPU to render the given mesh at its current position, rotation, and scale. The Material also defines which Shader is used, which controls the programmable parts of the graphics pipeline (vertex and fragment steps).

Note that if the Rendering Path setting under the Player Settings is set to Forward, then we can enable and disable the Directional Light in our Scene and the number of batches remains at nine. The first Directional Light in Forward rendering is effectively free at least in terms of Draw Calls. As soon as we add more Lights to our Scene, whether they are Directional, Point, Spot, or Area Lights, we cause all objects to be rendered with an additional "pass" through the Shader for each Light, up to the value of the Pixel Light Count value under the Quality Settings (lights with high brightness values are prioritized first).

Note

Lighting options can become a significant source of Draw Calls, and you will learn more about this system in Chapter 6, Dynamic Graphics.

As previously mentioned, we can theoretically minimize the number of Draw Calls by reducing how often we cause the system to change Render State information. So, part of the goal therefore is to reduce the amount of Materials we use. But, if we set all objects to use the same Material, we don't see any benefit and the number of batches remains at nine:

Materials and Shaders

This is because we're not actually reducing the number of Render State changes nor efficiently grouping mesh information. Without any form of batching, the rendering system is not smart enough to realize we're overwriting the exact same Render State values, and then asking it to render the same meshes, over and over again. This presents an opportunity to have the rendering process recognize these situations, render all of these meshes together as one object, and avoid unnecessary Draw Calls. This is basically how Dynamic Batching works to reduce our Draw Calls.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.218.69