BaseShader Manual

About

A BaseShader is the base class for shaders in Cinema 4D. Shaders are typically used with materials to define various surface properties. But shaders can also be used in other situations for example in combination with generator objects. BaseShader objects are not stored with the BaseDocument directly but must be inserted into the object that uses them.

BaseShader objects are an instance of Xbase.

// This example lets the user select an image file. If a file was selected
// a shader, material and texture tag are created that apply that image file
// to the given object.
Filename imageFile;
// open file selector dialog to select an image file
if (!imageFile.FileSelect(FILESELECTTYPE::IMAGES, FILESELECT::LOAD, "Select Image File"_s))
return maxon::OK;
// allocate elements
Material* material = Material::Alloc();
TextureTag* textureTag = TextureTag::Alloc();
// check for successful allocation
const Bool materialFailure = material == nullptr;
const Bool shaderFailure = bitmapShader == nullptr;
const Bool tagFailure = textureTag == nullptr;
if (materialFailure || shaderFailure || tagFailure)
{
BaseShader::Free(bitmapShader);
Material::Free(material);
TextureTag::Free(textureTag);
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
}
// start undo for the complete task
doc->StartUndo();
// configure the texture tag
const DescID projectionParam { TEXTURETAG_PROJECTION };
const Int32 projectionUVW = TEXTURETAG_PROJECTION_UVW;
textureTag->SetParameter(projectionParam, projectionUVW, DESCFLAGS_SET::NONE);
textureTag->SetMaterial(material);
object->InsertTag(textureTag);
doc->AddUndo(UNDOTYPE::NEWOBJ, textureTag);
// configure the bitmap shader and the material
material->InsertShader(bitmapShader);
// insert the material
doc->InsertMaterial(material);
doc->AddUndo(UNDOTYPE::NEWOBJ, material);
// finalize
doc->EndUndo();
void InsertShader(BaseShader *shader, BaseShader *pred=nullptr)
Definition: c4d_baselist.h:2571
Definition: c4d_basechannel.h:36
static BaseShader * Alloc(Int32 type)
static void Free(BaseShader *&ps)
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
Definition: lib_description.h:330
Manages file and path names.
Definition: c4d_file.h:94
Bool FileSelect(FILESELECTTYPE type, FILESELECT flags, const maxon::String &title, const maxon::String &force_suffix=maxon::String())
Definition: c4d_basematerial.h:241
static void Free(Material *&bl)
static Material * Alloc()
Definition: c4d_basetag.h:647
void SetMaterial(BaseMaterial *mat)
static TextureTag * Alloc()
static void Free(TextureTag *&bl)
maxon::Bool Bool
Definition: ge_sys_math.h:55
maxon::Int32 Int32
Definition: ge_sys_math.h:60
return OK
Definition: apibase.h:2663
@ LOAD
Load dialog.
@ IMAGES
Image files.
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define Xbitmap
Bitmap.
Definition: ge_prepass.h:1292
@ NEWOBJ
A new object, material, tag, or other classic API node instance has been inserted into the document....
@ MATERIAL_COLOR_SHADER
Definition: mmaterial.h:272
const char * doc
Definition: pyerrors.h:226
@ TEXTURETAG_PROJECTION
Definition: ttexture.h:10
@ TEXTURETAG_PROJECTION_UVW
Definition: ttexture.h:17
@ BITMAPSHADER_FILENAME
Definition: xbitmap.h:6

Access

Shaders are owned by the object that uses them. The shaders owned by a given object are organized in a list:

Shaders are typically organized in a list but can also be organized in a tree:

// This example loops through the shader list of the given material.
// Note that this example does not handle child or sub-shaders.
BaseShader* shader = material->GetFirstShader();
while (shader != nullptr)
{
ApplicationOutput("Shader: " + shader->GetName());
shader = shader->GetNext();
}
String GetName() const
Definition: c4d_baselist.h:2361
BaseShader * GetFirstShader() const
Definition: c4d_baselist.h:2543
BaseShader * GetNext(void)
Definition: c4d_basechannel.h:68
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210

Allocation/Deallocation

Shaders are created with the usual tools.

Newly created shaders are typically handed over to the object that uses them:

For a list of shader IDs see Shader Types.

// This example creates a noise shader and assigns it to the given material.
BaseShader* const noiseShader = BaseShader::Alloc(Xnoise);
if (noiseShader == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
material->InsertShader(noiseShader);
#define Xnoise
Noise.
Definition: ge_prepass.h:1328
@ MATERIAL_BUMP_SHADER
Definition: mmaterial.h:278

Read-Only Properties

Note
Also supported shaders may be baked into a texture, depending on the used material channel and shader context.

Sampling a Shader

A shader returns a color value for a given point. This point can be a point in world or object space or a set of UV-coordinates. A shader is sampled this way typically in the rendering pipeline.

A shader has to be initiated:

After the shader has been initiated these functions can be used:

In the end the resources of the shader must be released:

Warning
Without properly initiated InitRenderStruct::vd argument it is not safe to sample a shader multi-threaded.

A shader can sipmply be baked into a BaseBitmap using:

// This example bakes the given BaseShader into the given BaseBitmap
// and displays the result in the Picture Viewer window.
const InitRenderStruct irs { doc };
const maxon::Int32 colorProfile = irs.document_colorprofile;
const maxon::Bool linearWorkflow = irs.linear_workflow;
const maxon::Bool alpha = false;
const maxon::Bool hdr = true;
const maxon::Int xmin = 0;
const maxon::Int ymin = 0;
const maxon::Int xmax = sizeX - 1;
const maxon::Int ymax = sizeY - 1;
// bake shader
const Bool bakeResult = shader->BakeShaderIntoBaseBitmap(bitmap, *doc, parentThread, alpha, colorProfile, linearWorkflow, hdr, xmin, xmax, ymin, ymax);
if (bakeResult == false)
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
// show result
ShowBitmap(bitmap);
Bool ShowBitmap(const Filename &fn)
Bool BakeShaderIntoBaseBitmap(BaseBitmap &outBmp, BaseDocument &doc, BaseThread *parentThread, Bool doAlpha, Int32 colorSpace, Bool linearworkflow, Bool useHDR, Int xmin, Int xmax, Int ymin, Int ymax)
Definition: c4d_basechannel.h:205
Definition: c4d_shader.h:298
Int64 Int
signed 32/64 bit int, size depends on the platform
Definition: apibase.h:190
bool Bool
boolean type, possible values are only false/true, 8 bit
Definition: apibase.h:183
int32_t Int32
32 bit signed integer datatype.
Definition: apibase.h:178
// This example samples the given shader in UV space.
// init the shader
// check if linear workflow is enabled
if (irs.linear_workflow)
const INITRENDERRESULT res = shader->InitRender(irs);
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// sample the shader in UV space
ChannelData channelData;
channelData.off = 0;
channelData.scale = 0;
channelData.t = doc->GetTime().Get();
channelData.texflag = CALC_TEXINFO(0, CHANNEL_COLOR);
channelData.d = Vector { 1, 1, 1 };
channelData.n = Vector { 0, 1, 0 };
channelData.vd = nullptr; // VolumeData is nullptr
for (Int32 y = 0; y < height; ++y)
{
for (Int32 x = 0; x < width; ++x)
{
// generate UV coordinates
const Float64 xFloat = (Float64)x;
const Float64 yFloat = (Float64)y;
const Float64 u = xFloat / widthFloat;
const Float64 v = yFloat / heightFloat;
channelData.p.x = u;
channelData.p.y = v;
channelData.p.z = 0.0f;
const Vector color = shader->Sample(&channelData);
const Vector transformedColor = TransformColor(color, transform).Clamp01();
// write into the given BaseBitmap
const Int32 r = SAFEINT32(transformedColor.x * COLORTOINT_MULTIPLIER);
const Int32 g = SAFEINT32(transformedColor.y * COLORTOINT_MULTIPLIER);
const Int32 b = SAFEINT32(transformedColor.z * COLORTOINT_MULTIPLIER);
bitmap->SetPixel(x, y, r, g, b);
}
}
// free shader resources
shader->FreeRender();
PyObject PyObject * v
Definition: abstract.h:297
Int32 CALC_TEXINFO(Int32 texflag, Int32 channel)
Definition: c4d_shader.h:53
Vector64 TransformColor(const Vector64 &input, COLORSPACETRANSFORMATION colortransformation)
static const Float COLORTOINT_MULTIPLIER
Constant to convert from vectors color components to integers.
Definition: c4d_tools.h:25
INITRENDERRESULT InitRender(const InitRenderStruct &is)
Definition: c4d_basechannel.h:105
void FreeRender(void)
Frees all resources used by this shader that were allocated by calling InitRender().
Definition: c4d_basechannel.h:110
Vector Sample(ChannelData *cd)
Definition: c4d_basechannel.h:123
PyObject * x
Definition: bytesobject.h:38
Py_UCS4 * res
Definition: unicodeobject.h:1113
maxon::Float64 Float64
Definition: ge_sys_math.h:67
#define CHANNEL_COLOR
The color channel of a material.
Definition: c4d_shader.h:95
COLORSPACETRANSFORMATION
Definition: ge_prepass.h:495
@ LINEAR_TO_SRGB
Linear to sRGB color space transformation.
INITRENDERRESULT
Definition: ge_prepass.h:405
@ OK
Everything is OK, there was no error.
Int32 SAFEINT32(Float32 x)
Definition: apibasemath.h:266
const char const char grammar * g
Definition: parsetok.h:52
unsigned long Py_ssize_t width
Definition: pycore_traceback.h:88
Definition: c4d_shader.h:1099
Vector n
[READ ONLY] The surface normal.
Definition: c4d_shader.h:1112
Float scale
[READ ONLY] The MIP blur offset.
Definition: c4d_shader.h:1117
Float t
[READ ONLY] The current time in seconds.
Definition: c4d_shader.h:1114
Vector d
[READ ONLY] The MIP sample radius in UVW coordinates.
Definition: c4d_shader.h:1113
Int32 texflag
[READ ONLY] The texture flags: TEX
Definition: c4d_shader.h:1115
VolumeData * vd
[READ ONLY] The volume information, can be nullptr.
Definition: c4d_shader.h:1116
Float off
Definition: c4d_shader.h:1117
Vector p
[READ ONLY] The texture position in UVW coordinates.
Definition: c4d_shader.h:1111
T y
Definition: vec.h:35
constexpr Unstrided Clamp01() const
Returns a vector that is clamped to the range [0.0 .. 1.0].
Definition: vec.h:449
T x
Definition: vec.h:34
T z
Definition: vec.h:36

Compare

Two BaseShader elements can be compared with:

Note
The comparison is mostly based on the shader's BaseContainer. Other internal data may not be compared.

Further Reading