Setting up materials

Lighting can add certain dynamics into your 3D scene or game, which can make it more immersive. Everything you see is a light that reflects from surfaces. Some part of the visible light is absorbed by the material on a surface. The rest of the visible light spectrum defines the material color. You can say that the surface material reacts with the light in a certain way. Therefore, OpenGL attributes light processing into parts—material and lighting.

OpenGL tries to approximate light distribution and reflection by five material attributes, which are as follows:

  • GL_DIFFUSE: This specifies the color of the surface and is mostly the attribute you will want to use
  • GL_AMBIENT: This affects all vertices equally and often simulates ambient light
  • GL_SPECULAR: This is the color of the highlight
  • GL_EMISSION: This is the emitted light color, which can be used for surfaces that emit light, such as lamps or LEDs
  • GL_SHININESS: This specifies the size of the highlighted area; smaller values are often used for metal surface simulation

Getting ready

Material settings are applied only when lighting is enabled. You can enable lighting with this line:

gl.Enable(gl_enum.GL_LIGHTING)

Otherwise, scene objects will use the vertex color defined by the gl.Color function. The recipe will assume that your scene contains white omnidirectional light. This light can simulate the light bulb.

How to do it…

Materials are applied to polygons in a similar fashion as vertex colors. They can be used on the front side or the back side of the polygons. You can set the material properties with the gl.Materialf and gl.Materialfv functions. The following code will set up the material for the front side of the polygons:

local m_diffuse =  {0.8, 0.0, 0.0, 1.0}
local m_ambient =  {0.0, 0.0, 0.5, 1.0}
local m_specular = {1.0, 1.0, 1.0, 1.0}
local m_emission = {0.0, 0.0, 0.0, 1.0}
local m_shininess = 50
local m_side = gl_enum.GL_FRONT

gl.Materialfv(m_side, gl_enum.GL_DIFFUSE, m_diffuse)
gl.Materialfv(m_side, gl_enum.GL_AMBIENT, m_ambient)
gl.Materialfv(m_side, gl_enum.GL_SPECULAR, m_specular)
gl.Materialfv(m_side, gl_enum.GL_EMISSION, m_emission)

gl.Materialf(m_side, gl_enum.GL_SHININESS, m_shininess)

This example will set a bright red material for all polygons that are rendered after this code. You can see the result in the following screenshot:

How to do it…

Notice that the gl.Materialfv function accepts the Lua table, whereas gl.Materialf accepts a number.

How it works…

OpenGL uses material values and light parameters to determine the final vertex color. The vertex color is a composition of the global ambient color, local ambient color, diffuse color, specular color, and emission color. Each component is basically a result of the multiplication of a light component, a material component, and a normal vector.

There's more…

Setting material attributes every time is fairly expensive. What's more, the gl.Color function doesn't work with the material and you can't include the material color in a vertex buffer. Fortunately, you can use the gl.ColorMaterial function that binds gl.Color to the material color attribute. The following example will bind the gl.Color function to the GL_DIFFUSE attribute:

local r,g,b,a = 1.0, 1.0, 1.0, 1.0
gl.ColorMaterial(gl_enum.GL_FRONT, gl_enum.GL_DIFFUSE)
gl.Enable(gl_enum.GL_COLOR_MATERIAL)
gl.Color4f(r, g, b, a)

Note that the material's diffuse color also has the alpha channel, which can be used to apply object transparency. Other material attributes don't use the alpha channel!

See also

  • The Setting up lighting recipe
..................Content has been hidden....................

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