Gazebo Rendering

API Reference

7.4.2
Custom shaders

This example shows how use custom shaders in gz-rendering to change the appearance of objects in the scene. It demonstrates two uses of shaders: The first is setting shaders for a camera and the other is setting shaders for an object in the scene.

Compile and run the example

Clone the source code, create a build directory and use cmake and make to compile the code:

git clone https://github.com/gazebosim/gz-rendering
cd gz-rendering/examples/custom_shaders
mkdir build
cd build
cmake ..
make
./custom_shaders

You'll see:

Image saved: depth.png
Image saved: regular.png

The depth.png shows result of setting shaders for a camera: This example shades objects in the scene based on their depth values

The regular.png shows result of setting shaders for a visual: This example changes the box visual in the scene to a flat green color

Code

In the first lines of the custom_shaders.cc file there are some constants defined with the name of the shaders that the program will use:

"depth_vertex_shader.glsl";
"depth_fragment_shader.glsl";
const std::string vertex_shader_file = "vertex_shader.glsl";
const std::string fragment_shader_file = "fragment_shader.glsl";

Construct absolute path to the shaders. Here the RESOURCE_PATH variable points to the media directory where the two sets of shaders are located:

// path to look for vertex and fragment shaders
std::string depth_vertex_shader_path = gz::common::joinPaths(
RESOURCE_PATH, depth_vertex_shader_file);
std::string depth_fragment_shader_path = gz::common::joinPaths(
RESOURCE_PATH, depth_fragment_shader_file);

The first set of shaders are applied to the camera:

// create shader material
gz::rendering::MaterialPtr depthMat = scene->CreateMaterial();
depthMat->SetVertexShader(depth_vertex_shader_path);
depthMat->SetFragmentShader(depth_fragment_shader_path);
// apply shader to camera
depthCamera->SetMaterial(depthMat);

The second set of shaders are applied to the visual's material:

// create shader material
gz::rendering::MaterialPtr shader = _scene->CreateMaterial();
shader->SetVertexShader(vertex_shader_path);
shader->SetFragmentShader(fragment_shader_path);
// create box visual and apply shader
gz::rendering::VisualPtr box = _scene->CreateVisual();
box->AddGeometry(_scene->CreateBox());
box->SetOrigin(0.0, 0.5, 0.0);
box->SetLocalPosition(3, 0, 0);
box->SetLocalRotation(GZ_PI / 4, 0, GZ_PI / 3);
box->SetLocalScale(1, 2.5, 1);
box->SetMaterial(shader);