Assignment 12 – Materials

Materials are a high level way of customizing how a object looks. It serves as an encapsulation of the lower-level graphics details like shaders and uniforms. We can use different materials on the same mesh to make it look different.

A material is an asset and thus we have a human-readable material file. Mine looks like this:

return
{
	effectPath = "data/SquareEffectTransparent.effect",
	uniformData = 
	{

		{
			uniformName = "g_modifier_materialColor",
			values = {0.2,0.5,0.3},
			shaderType = "ShaderType_Frag",
		},

		{
			uniformName = "g_modifier_materialAlpha",
			values = {0.9},
			shaderType = "ShaderType_Frag",
		}


	}
}

The effect determines the shaders to use for this material. The uniformData table contains the various uniforms set by this material, their names, values and the type of shader they apply to.

At runtime uniform data is represented as a struct:

        struct sMaterialParameters
        {
            tUniformHandle uniformHandle;
            eShaderType shaderType;
            float values[4];
            uint8_t valueCountToSet;
        };

We have a accompanying material builder which builds this into a binary file. The binary looks like this:materialbinary

Data is written in this order:

  • Effect path size
  • Effect path (null terminated)
  • Number of uniforms
  • Array of sMaterialParameters
  • Array of
    • Length of Uniform name
    • Uniform name (null terminated)

I found that the built material binary is slightly different for Debug and Release configurations. In debug, uninitialized bytes were set to cc, in release they were set to 00. I think the cc is a way of the compiler to flag uninitialized memory to help us debug.

Also there are differences in OpenGL and Direct3D, mainly because the uniform handle in OpenGL is a 4 byte int while in D3D its a char *.

Finally, here is the screenshot with different materials applied to the same sphere mesh.

materialscreenshot

 


Download

Controls:

WASD: Move Camera

Arrows: Move box