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

Int32 channelId = CHANNEL_SPECULAR; /*or CHANNEL_SPECULARCOLOR, CHANNEL_REFLECTION*/

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.

c4d_material->RemoveReflectionAllLayers();

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->SetFloat(specDataID + REFLECTION_LAYER_MAIN_DISTRIBUTION, REFLECTION_DISTRIBUTION_SPECULAR_BLINN);
	materialData->SetInt32(specDataID + REFLECTION_LAYER_MAIN_ADDITIVE, REFLECTION_ADDITIVE_MODE_ADD);
	materialData->SetInt32(specDataID + REFLECTION_LAYER_MAIN_BLEND_MODE, MATERIAL_TEXTUREMIXING_ADD);
	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.

Advertisements