Color And Texture Models


Adding Color and Textures to a Model

This tutorial describes how color works in gazebo. After reading you will know how to make objects in your simulation look more like their real-world counterparts.

About Ambient, Diffuse, Specular, and Emissive

At the end this section you'll know what parameters relate to color and how they work.

The color of an object is determined using a Blinn-Phong shading model. There are four components that control the color: ambient, diffuse, specular, and emissive. The OpenGL Programming guide chapter on Lighting has detailed information about how these work.

Component Values on Lights Versus Materials

The final color of an object depends both on the material and the lights shining on it. Values on lights represent the intensity of light emitted. Values on a material represent the percentage of light an object reflects. The same material may be different colors depending on the light that hits it.

For example, consider a material with a diffuse color of RGBA(1, 1, 0.5, 1.0). Under a white light it would look yellow. If exposed to a light emitting a diffuse RGBA(0 1 0 1) then it would appear green. If exposed to a light emitting a diffuse RGBA(1 0 0 1) then it would appear red. A light with diffuse RGBA(0 0 0.75 1) would make the object appear dark blue.

Ambient

Ambient light is the color of an object when no lights are pointing at it. It is completely uniform about the object. Ambient light is meant to approximate light that has been reflected so many times it is hard to tell where it came from.

Diffuse

This is the color of an object under a pure white light. It is calculated using the light's direction and the surface normal where the light hits. The part of an object with a normal antiparallel to a light source will be brightest from this component.

Specular

The Specular component is the color and intensity of a highlight from a specular reflection Higher values make an object appear more shiny. A polished metal surface would have a very large specular value, while a piece of paper would have almost none.

Emissive

The Emissive component can only be set on a material. Like ambient light, emissive adds uniform color to an object. It appears as if light was emitted from the object, though emissive light does not add light to other objects in the world.

Compination of components

Each of the four components adds color to an object. The final color of an object is the sum of all components. After summation, if any red, green, or blue value goes above 1.0 then it is set to 1.0.

Where Color Parameters Can Be Set

Specifying the color of an object means configuring both lights and the object's material. At the end of this section you'll know where color parameters for lights and models are, and how they can be tweaked.

Setting the Color Components of Lights

Light color can be specified in the world SDF file. Ambient light is set globally in <scene>. The amount of ambient light in the world is a design choice that is up to you. An indoor world may need a large global ambient light since every wall and surface is an opportunity to reflect light. A simulation of satellites may have almost no ambient light since most is radiated out into space.

The <diffuse> and <specular> tags on a <light> set the color of diffuse and specular components emitted. These tags require four floating point numbers (RGBA) between 0.0 and 1.0. The last number (alpha) has no affect on lights.

Lights do not have emissive or ambient components.

Setting the Color Components of Objects

The color components on objects can be set from SDF, an Ogre Material Script, or some types of meshes.

SDF

Every <visual> has a <material> tag that controls the color components of an object. Those tags are:

Ogre Material Script

If the components are set both using SDF and an Ogre Material Script, then the SDF values are used for ambient, diffuse and emissive. If both define specular then the final specular value is the addition of the Ogre Material Script and the SDF value.

Collada and OBJ meshes

If a visual uses a <mesh> and the mesh type is Collada (.dae) or Wavefront (.obj) then gazebo will try to get color values from those formats.

Collada color components for objects are taken from a <phong> (page 8-69) effect. If a collada mesh does not have any effects then in gazebo 7 it will be displayed as if it had an emissive value of RGBA(1 1 1 1). In gazebo 8+ it will be displayed with gray diffuse and ambient components, but no emissive or specular components.

Wavefront obj color values are taken from the object's material: Ka, Kd, Ks, and Ns. See this Wikipedia article for more info about OBJ files.

Note: OBJ materials may not display correctly in versions earlier than gazebo 8.

About Textures

Textures map an image onto a shape. They add detail to a model without adding geometry.

The color added by a texture is made visible by both ambient and diffuse light.

Setting the Texture of an Object

Ogre Material Scripts

Ogre Material Scripts have many options for applying a texture to an object. Read the Ogre Documentation for more information.

Collada

Collada files can apply textures to objects. How to create such a file is outside the scope of this tutorial. Blender is an open source modelling tool capable exporting to Collada.

Make sure the paths for textures given in <library_images> are relative to the collada file.

Example Adding Color and Textures to a Model

This example will walk through how to add color to a basic model.

Basic Files and Folders

Make a directory to contain files from this tutorial.

mkdir ~/color_tutorial

There are two parts to color: the model and the lights that light up a model.

Lights are specified in the world, so create a world with some light. Save the following as:

~/color_tutorial/lit_world.world

It has a bright white directional light with some ambient light.

<?xml version="1.0" ?>
<sdf version="1.6">
  <world name="default">
    <scene>
      <ambient>0.4 0.4 0.4 1</ambient>
      <background>0.25 0.25 0.25 1</background>
      <shadows>false</shadows>
    </scene>
    <light type="directional" name="some_light">
      <diffuse>0.7 0.7 0.7 0</diffuse>
      <specular>1 1 1 0</specular>
      <direction>-1 -1 -1</direction>
    </light>
  </world>
</sdf>

The next step is to create a model. Refer to this image to see where files below need to be saved. See the model structure tutorial for more information about these files.

The models folder itself must be in the environment variable GAZEBO_MODEL_PATH. This tutorial will assume you use the folder ~/color_tutorial/models.

export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/color_tutorial/models

Create directories for the model.

mkdir -p ~/color_tutorial/models/example_model/materials/scripts
mkdir -p ~/color_tutorial/models/example_model/materials/textures
mkdir -p ~/color_tutorial/models/example_model/meshes

Save this file as model.config.

<?xml version="1.0"?>

<model>
  <name>Example Model For Color Tutorial</name>
  <version>1.0</version>
  <sdf version="1.6">model.sdf</sdf>

  <author>
    <name>YOUR NAME HERE</name>
    <email>YOUR EMAIL HERE</email>
  </author>

  <description>
    Example of adding color to a model
  </description>

</model>

Save this file as model.sdf.

<?xml version="1.0"?>
<sdf version="1.6">
  <model name="Color Tutorial Model">
    <static>true</static>
    <link name="robot_link">
      <collision name="body_collision">
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
      </collision>
      <visual name="wheel1_visual">
        <pose>-0.2 0 -0.25 0 1.57079 0</pose>
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.02</length>
          </cylinder>
        </geometry>
      </visual>
      <visual name="wheel2_visual">
        <pose>0.2 0 -0.25 0 1.57079 0</pose>
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.02</length>
          </cylinder>
        </geometry>
      </visual>
      <visual name="power_led_visual">
        <pose>0.225 0.225 0.25 0 0 0</pose>
        <geometry>
          <sphere>
            <radius>0.003</radius>
          </sphere>
        </geometry>
      </visual>
      <visual name="body_visual">
        <geometry>
          <box>
            <size>0.5 0.5 0.5</size>
          </box>
        </geometry>
      </visual>
      <visual name="head_visual">
        <pose>0 0 0.25 0 0 -2.5</pose>
        <geometry>
          <sphere>
            <radius>0.25</radius>
          </sphere>
        </geometry>
      </visual>
    </link>
  </model>
</sdf>

Color Wheels and Power LED Using SDF

The wheels and power LED of this model wil be single uniform color, so they'll be set using SDF. Here is an example material that makes the wheels dark blue. Add it to both of the wheel <visual> tags.

        <material> <!-- Wheel material -->
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.2 1</diffuse>
          <specular>0 0 0 0</specular>
          <emissive>0 0 0 1</emissive>
        </material> <!-- End wheel material -->

The power LED is the source of its own light, so the emissive component will be used. Add this to the power_led <visual> to make it always be fully green.

        <material> <!-- LED material -->
          <ambient>0 0 0 1</ambient>
          <diffuse>0 0 0 1</diffuse>
          <specular>0 0 0 0</specular>
          <emissive>0 1 0 1</emissive>
        </material> <!-- End LED material -->

Color Body Using an Ogre Material Script

The body will be covered in a repeating texture.

Save this image as seamless_texture.png

Then save this file as repeated.material. It is an Ogre Material Script that repeats the texture over each face of the box.

material RepeatedTexture
{
  technique
  {
    pass
    {
      texture_unit
      {
        // Relative to the location of the material script
        texture ../textures/seamless_texture.png
        // Repeat the texture over the surface (4 per face)
        scale 0.5 0.5
      }
    }
  }
}

The result is a cube with each face having four copies of the seamless texture.

Color Head Using a Collada with a Texture

Save this image as head_texture.png.

Download and save this Collada file as head.dae.

This collada file references an image to use as a texture. We need to double check that the paths are what we want them to be.

Open head.dae with your favorite text editor and look for <library_images>.

 <library_images>
    <image id="head_texture_png" name="head_texture_png">
      <init_from>head_texture.png</init_from>
    </image>
  </library_images>

The model is referencing an image without any path information. It expects the png file to be in the same folder as head.dae, but we want to store the texture in another folder. Change the path in head.dae to reference the texture location relative to head.dae.

  <library_images>
    <image id="head_texture_png" name="head_texture_png">
      <init_from>../materials/textures/head_texture.png</init_from>
    </image>
  </library_images>

The final step is to open it up in gazebo

Open the Result in Gazebo

The environment variable GAZEBO_MODEL_PATH must be set to the path to the models folder you created. Set it and launch gazebo with the world you saved earlier.

export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/color_tutorial/models
gazebo --verbose ~/color_tutorial/lit_world.world

Insert the model you created into the world.