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.
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.
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 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.
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.
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.
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.
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.
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.
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.
The color components on objects can be set from SDF, an Ogre Material Script, or some types of meshes.
Every <visual> has a <material> tag that controls the color components of an object. Those tags are:
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.
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.
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.
Ogre Material Scripts have many options for applying a texture to an object. Read the Ogre Documentation for more information.
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.
This example will walk through how to add color to a basic model.
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>
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 -->
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.
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
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.