C4D Programming

Developing plugins and scripts for CINEMA 4D

Category: C++ specific

Cinema 4D R16 Reflectance channel’s API

by jfyelle

In Cinema 4D R16, We replaced specular and reflection by a new channel called reflectance. This channel allows layered materials which can be used to do more realistic materials such as car paints, human skin, etc. In this post, you’ll find how to make the best out of the new feature.

@Can Amerak

@Can Amerak

A layered material is different from the old specular and reflection channels in one important way. It is now possible to do specular AND reflection on the same layer. This means it is may not be possible to find out the specular or the reflection layers in the material. In consequence, we cannot give a specific layer index where specular or reflection may be found.

This paradigm change means exporting consistent looking materials via your favorite interop format will only work if a material has one layer for specular and one layer for reflection.

Who is concerned

R15 .C4D files coming to R16 have their specular and reflection automatically converted to the new reflectance layer. Any plugin dealing with the specular / reflection channels such as material plugins or interop filters need to properly support the new feature.

Header file

The reflectance API is located in header file c4d_reflection.h
#include “c4d_reflection.h”

Accessing the Specular, reflection channels

Because the accesses were remapped, accessing the specular or reflection channels the old way will work for extracting or modifying the information


if (c4d_material->GetChannelState(channelId))
	BaseChannel* channel;
	BaseContainer channel_data;

	Float spec_width, spec_height;
	channel = c4d_material->GetChannel(channelId);
	if (channel)
		channel_data = c4d_material->GetData();

		Float spec_width = channel_data.GetFloat(MATERIAL_SPECULAR_WIDTH);
		Float spec_height = channel_data.GetFloat(MATERIAL_SPECULAR_HEIGHT);

Creating a reflectance channel or layers

Creating specular and reflection won’t work alas. For this, you will need to get your hands dirty and create a reflectance channel using the new API.
We gain access to the reflectance channel through the material data.

//Given a Material* c4d_material
BaseContainer* materialData = c4d_material->GetDataInstance();

As the reflection channel come initialised with one basic specular layer. If you want to control exactly what you are doing, you may want to delete all layers and start fresh.


Adding a layer is simple. You would add a layer for specular (comprising specular and specular color) and another layer for reflection. Setting the data in the layer is pretty straight forward except for a couple details. See below.

ReflectionLayer* layer = c4d_material->AddReflectionLayer();

if (reflLayer != nullptr)
	lLayer->name = “Foobar”;

	Int32 refDataID = lLayer->GetDataID();

	materialData->SetVector(specDataID + REFLECTION_LAYER_COLOR_COLOR, specular_color);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_COLOR_BRIGHTNESS, specular_factor);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_REFLECTION, 0.0);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_ROUGHNESS, somevalue);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_SPECULAR, somevalue);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_BUMP, 1.0);

Notice how we use the specDataID layer offset to assign the various layer parameters. The ID to access the default specular channel is 0x04. We do not know for sure if a specific layer is the main reflection or specular layer. This knowledge is lost with the possibilities opened by this layer system. The parameter names should be very close to what you see in the user interface. As the vocabulary varies across 3D products and feature, I believe playing with the parameters will help you figure out the fastest what you actually control in the material.

Don’t forget to kick the can when you are done

If you re-initialized the reflectance, you will need one extra step. Once done setting the reflection layer, notify the reflectance system you imported data in or your work will be remapped automatically.

reflectanceData->SetBool(REFLECTION_LAYER_IMPORTED, true);

Hoping this helps. Let me know of any question or details, as we are working the reflectance documentation in.


Compiling 64 Bit plugins in Visual C++ Express

by .

Many people, especially developers who write free plugins, or hobbyists, use only the free Visual C++ 2010 Express for their Windows builds. However, that version of C++ does not support 64 Bit builds.

There is an easy solution for this, and many people already know it. But since the questions comes up from time to time, here is how to get Visual C++ 2010 Express to build for 64 Bit, too.
Read the rest of this entry »

Initializing member variables in the constructor

by .

As you might know, it is good practice to leave no variables uninitialized. If you wrote a struct or class, all its members should have a defined initial state, which is usually set in the struct’s or class’s constructor.
Read the rest of this entry »

Function parameters as references

by .

Performance can be increased by using references instead of copying values as function arguments.
Read the rest of this entry »

Goes without saying: Crash safety

by .

CINEMA 4D is known for its stability. While other 3D packages sometimes tend to randomly crash on you several times a day, CINEMA 4D runs stable and does not crash very often.

When you develop plugins for CINEMA 4D, you want to add functionality without making the whole application instable.
Read the rest of this entry »

Pages: 1 2 3 4