Convert colors with the color profiles provided by the OpenColorIO (OCIO) configuration of a scene.
Overview
Cinema 4D implements color management primarily with International Color Consortium (ICC) color profiles and the OpenColorIO (OCIO) standard. OCIO implements a color management pipeline for digital content creation applications to decouple the color representation requirements of color computations from the requirements of displaying colors on hardware-devices. This allows for a lossless transfer of color data between different applications while giving artists always the ability to view their artwork with the colors the final consumer will see. OCIO achieves this by defining color spaces by purpose so that they can be applied selectively to color data. The three abstract color spaces defined by the OCIO standard are:
- The Render Space is the color space the application does operate in. All color data is converted to this space before processing and the application does carry out all computations in this space. This is usually a linear color space. For Cinema 4D documents in OCIO mode this is by default the ACEScg space.
- The Display Space is a space to convert colors from the Render Space to a color representation which is suited for displaying these colors on a screen. This is usually a non-linear color space. For Cinema 4D documents in OCIO mode this is by default the sRGB space.
- The View Transform is a transform which is applied after the display space and is meant to emulate the final look of color data on a consumer device. This could for example emulate the look of a movie-screen on the display of an artist. For Cinema 4D documents in OCIO mode this is by default the ACES 1.0 SDR-video space.
- Cinema 4D adds to this a special transform which is only applied to thumbnails, the Thumbnail View Transform.
Each application in a color management pipeline assigns a color profile to each of these abstract color spaces to suite its specific needs. Applications communicate the possible choices for each space with the help of OCIO configuration files, allowing for a persistent color previewing experience along the pipeline without having to bake hardware dependent information into outputs (Fig. I).
Technical Overview
Cinema 4D currently does provide only shallow public access to its OCIO API, with the consequence that high level OCIO concepts such as an OCIO configuration or an OCIO processor are not represented by dedicated types in the public API. There are however multiple entry points which provide access to the most important functionalities of OCIO.
OCIO is bound intrinsically to a scene in form of BaseDocument, a scene can either have OCIO enabled or not, and also stores the currently active color profiles for the principal OCIO spaces. These settings are expressed as the parameters:
- Note
- There are two exception to the rule of OCIO color spaces being intrinsically bound to a document: The type BaseBitmap and VideoPostData. With the methods BaseBitmap::GetColorProfile and SetColorProfile, the three OCIO transforms render, display, and view can be overwritten on a per bitmap basis. This can be useful when a bitmap should ignore the OCIO display and view transforms in the Picture Viewer of Cinema 4D. Similarly, VideoPostData::GetColorProfileInfo allows for overriding color profile information in an upcoming rendering.
These parameters can be read and written with BaseDocument::GetParameter and SetParameter. Due to the fact that the values of OCIO color spaces and transforms depend on the loaded OCIO configuration, the values written to the parameters must be retrieved with the following functions:
Additionally, the following methods exist:
- CopyLinearWorkflow: Copies the color management settings from one document to another.
- GetOcioConfigPath: Returns the OCIO configuration path used by Cinema 4D.
- UpdateOcioColorSpaces: Propagates changes made to the OCIO settings of a document to the bound OCIO color spaces.
- GetOcioProfiles: Returns the color profiles for the currently active OCIO settings.
To convert colors between OCIO color space representations, the type OcioConverter must be used, providing the methods:
The transform paths are defined by the enumeration COLORSPACETRANSFORMATION. Note that a path can contain multiple transforms, as the path is always carried out in a sensible manner, e.g., OCIO_RENDERING_TO_VIEW will contain the display transform, as the OCIO transform chain is render->display->view
. The available paths are:
Related Topics
Examples
The examples shown here are all part of the OCIO Plugin in the SDK. Once the SDK has been compiled and installed, the plugin can be found under the menu entry Extensions\Example.image\C++ SDK: OCIO Examples
.
Color Convert Scenes
Convert all colors contained in a document or contained in a set of elements in a document to a new OCIO Render space.
{
{
doc->UpdateOcioColorSpaces();
}
doc->GetActiveOcioColorSpacesNames(renderSpaceName, _, _, _);
if (!converter)
return maxon::OutOfMemoryError(
converter->Init(
doc,
"sRGB"_cs,
"scene-linear Rec.709-sRGB"_cs, renderSpaceName)
iferr_return;
}
void EventAdd(EVENT eventflag=EVENT::NONE)
Definition: ge_autoptr.h:37
Definition: c4d_basecontainer.h:47
Int32 GetInt32(Int32 id, Int32 preset=0) const
Definition: c4d_basecontainer.h:303
void SetInt32(Int32 id, Int32 l)
Definition: c4d_basecontainer.h:505
Definition: c4d_basedocument.h:498
Definition: c4d_gedata.h:83
Definition: string.h:1490
Definition: hashmap.h:2956
PyObject PyObject * result
Definition: abstract.h:43
@ DOCUMENT_COLOR_MANAGEMENT
Definition: ddoc.h:152
@ DOCUMENT_COLOR_MANAGEMENT_OCIO_CONVERTED
Definition: ddoc.h:156
@ DOCUMENT_COLOR_MANAGEMENT_OCIO
Definition: ddoc.h:154
return OK
Definition: apibase.h:2690
#define MAXON_FUNCTIONNAME
This macro returns the function name of the current member or global function.
Definition: objectbase.h:2860
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210
const char * doc
Definition: pyerrors.h:226
#define iferr_scope
Definition: resultbase.h:1384
#define iferr_return
Definition: resultbase.h:1519
Copy Color Management Settings
Copy all color management settings from one document to another.
This does not entail any scene element color space conversions, one must instead use SceneColorConverter as demonstrated in the example Color Convert Scenes .
{
newDoc->SetName(
doc->GetName() +
"(Copy)");
doc->GetName(), newDoc->GetName());
}
void Free()
Calls TYPE::Free(ptr) with the internal pointer and sets it to nullptr.
Definition: ge_autoptr.h:128
static void CopyLinearWorkflow(const BaseDocument *src, BaseDocument *dst, Bool isMaterialPreview)
Read and Write OCIO Settings
Read and write the OCIO color management settings stored in a document.
{
{
doc->UpdateOcioColorSpaces();
}
{
}
"OCIO configuration does not contain a 'ACES2065 - 1' render space."_s);
doc->UpdateOcioColorSpaces();
}
PyObject PyObject const char const char char ** s
Definition: bytesobject.h:60
Definition: lib_description.h:330
@ DOCUMENT_OCIO_RENDER_COLORSPACE
Definition: ddoc.h:143
#define NOTOK
Definition: ge_sys_math.h:267
int32_t Int32
32 bit signed integer datatype.
Definition: apibase.h:176
#define MAXON_UNLIKELY(...)
Definition: compilerdetection.h:404
Convert Colors
Convert colors along OCIO conversion paths defined by the OCIO color spaces associated with a document.
{
{
doc->UpdateOcioColorSpaces();
}
if (!converter)
return maxon::NullptrError(
}
Class which transforms colors from one OCIO color space to another.
Definition: c4d_shader.h:212
static maxon::Result< OcioConverter * > Init(const BaseDocument *doc, Int32 overrideViewTransform=-1)
Definition: c4d_shader.h:233
Vector64 TransformColor(const Vector64 &v, COLORSPACETRANSFORMATION colorSpaceTransformation) const
Definition: c4d_shader.h:244
@ OCIO_RENDERING_TO_DISPLAY
Rendering to display color space transformation.
@ OCIO_RENDERING_TO_VIEW
Rendering to view color space transformation.
@ OCIO_SRGB_TO_RENDERING
sRGB to Rendering color space transformation.
@ OCIO_VIEW_TO_RENDERING
View to rendering color space transformation.
A vector consisting of three components X, Y and Z.
Definition: vec.h:21
Convert Colors Arbitrarily
Convert colors from and to OCIO color spaces using arbitrary in- and output spaces.
{
{
doc->UpdateOcioColorSpaces();
}
return maxon::IoError(
const maxon::ColorProfile linearRgbSpaceProfile = maxon::ColorSpaces::RGBspace(
).GetDefaultLinearColorProfile();
maxon::ColorProfile renderSpaceProfile, _;
doc->GetOcioProfiles(renderSpaceProfile, _, _, _);
doc->GetActiveOcioColorSpacesNames(renderSpaceName, __, __, __);
const maxon::PixelFormat rgbFormat = maxon::PixelFormats::RGB::F32();
if (!(srgb2014Profile.CheckCompatiblePixelFormat(rgbFormat) ||
linearRgbSpaceProfile.CheckCompatiblePixelFormat(rgbFormat) ||
renderSpaceProfile.CheckCompatiblePixelFormat(rgbFormat)))
return maxon::UnexpectedError(
rgbFormat, srgb2014Profile, rgbFormat, linearRgbSpaceProfile,
rgbFormat, linearRgbSpaceProfile, rgbFormat, renderSpaceProfile,
(
const maxon::Pix*)&inputBuffer.r, maxon::PixelFormats::RGB::F32());
(
maxon::Pix*)&outputBuffer.r, maxon::PixelFormats::RGB::F32());
preConverter.Convert(inputBufferHandler, outputBufferHandler, 1)
iferr_return;
srgb2014Profile, colorData, linearRgbSpaceProfile, outputBuffer);
inputBuffer = outputBuffer;
ocioConverter.Convert(inputBufferHandler, outputBufferHandler, 1)
iferr_return;
srgb2014Profile, colorData, renderSpaceName, outputBuffer);
}
static MAXON_METHOD Result< ColorProfileConvert > Init(const PixelFormat &srcPixelFormat, const ColorProfile &srcProfile, const PixelFormat &dstPixelFormat, const ColorProfile &dstProfile, COLORCONVERSIONINTENT intent, COLORCONVERSIONFLAGS flags)
static MAXON_METHOD Result< ColorProfile > OpenProfileFromFile(const Url &fn)
Definition: string.h:1235
ImageBufferTemplate< PixelConstBuffer > ImageConstBuffer
Definition: gfx_image_pixelformat.h:185
UChar Pix
unspecified pixel format depth.
Definition: gfx_image_imagechannel.h:17
ImageBufferTemplate< PixelMutableBuffer > ImageMutableBuffer
Definition: gfx_image_pixelformat.h:186
@ NONEXISTENT
Url doesn't exist.
A color consisting of three components R, G and B.
Definition: col.h:16
Several functions use this helper structure to pass the image data to functions.
Definition: gfx_image_pixelformat.h:521
Get and Set Color Parameters
Read and write color parameters in an OCIO document either in the native Render space of the document or other spaces.
{
{
doc->UpdateOcioColorSpaces();
}
doc->GetActiveOcioColorSpacesNames(renderSpace, _, viewTransform, _);
if (!converter)
const Vector color { 1, 0, 0 };
m1->
SetName(
"Material (Render Space)"_s);
m3->
SetName(
"Material (View Transform)"_s);
}
void SetName(const maxon::String &name)
Definition: c4d_baselist.h:2387
Definition: c4d_basematerial.h:28
static BaseMaterial * Alloc(Int32 type)
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
const Vector & GetVector() const
Definition: c4d_gedata.h:451
@ DOCUMENT_DEFAULTMATERIAL_COLOR
Definition: ddoc.h:67
@ OCIO_RENDERING_TO_SRGB
Rendering to sRGB color space transformation.
#define Mmaterial
Standard material.
Definition: ge_prepass.h:998
@ MATERIAL_COLOR_COLOR
Definition: mmaterial.h:56
Manage Bitmap OCIO Color Profiles
Read and write the OCIO color spaces associated with BaseBitmap instances to change or nullify parts of an OCIO conversion path for them.
This makes it for example possible to disable the Display and View transform for a singular bitmap when displayed in the Picture Viewer.
{
{
doc->UpdateOcioColorSpaces();
}
const maxon::Id assetId(
"file_9748feafc2c00be8");
const maxon::AssetDescription asset = repository.FindLatestAsset(
clone = bitmap->GetClone();
clone->SetColorProfile(profile,
BaseBitmap::COLORPROFILE_INDEX_DISPLAYSPACE);
clone->SetColorProfile(profile,
BaseBitmap::COLORPROFILE_INDEX_VIEW_TRANSFORM);
}
maxon::Url MaxonConvert(const Filename &fn, MAXONCONVERTMODE convertMode)
Bool ShowBitmap(const Filename &fn)
Definition: c4d_basebitmap.h:428
static void Free(BaseBitmap *&bm)
Definition: c4d_basebitmap.h:156
static MAXON_METHOD const UpdatableAssetRepositoryRef & GetUserPrefsRepository()
static MAXON_METHOD Result< Url > GetAssetUrl(const AssetDescription &asset, Bool isLatest)
Definition: apibaseid.h:253
OK
Ok.
Definition: ge_prepass.h:0
IMAGERESULT
Definition: ge_prepass.h:3914
The maxon namespace contains all declarations of the MAXON API.
Definition: autoweight.h:14
@ LATEST
Set this flag to obtain only the latest version of the asset.
const char const char const char * file
Definition: object.h:439
OCIO Aware Render
Realizes a renderer which manipulates the OCIO profiles of an upcoming rendering.
void OcioAwareRenderer::GetColorProfileInfo(
{
return;
if (data->
GetBool(ID_OVERWRITE_OCIO_DISPLAY_SPACE))
info.displayColorSpace =
info.renderingColorSpace;
if (data->
GetBool(ID_OVERWRITE_OCIO_VIEW_TRANSFORM))
info.viewColorSpace =
info.renderingColorSpace;
}
{
{
};
if (!rgbaBuffer)
if (rgbaBuffer->
GetBt() != 32)
nodeData->
GetBool(ID_PRETRANSFORM_OCIO_OUTPUT))
{
if (!converter)
}
const
Int32 height = rgbaBuffer->GetBh();
const
Int32 bytesPerPixel = rgbaBuffer->GetCpp();
{
lineBuffer[ix*bytesPerPixel+0] = (
Float32)color.x;
lineBuffer[ix*bytesPerPixel+1] = (
Float32)color.y;
lineBuffer[ix*bytesPerPixel+2] = (
Float32)color.z;
}
for (
Int32 iy = 0; iy < height; iy++)
}
Vector64 TransformColor(const Vector64 &input, COLORSPACETRANSFORMATION colortransformation)
Vector GetVector(Int32 id, const Vector &preset=Vector()) const
Definition: c4d_basecontainer.h:371
Bool GetBool(Int32 id, Bool preset=false) const
Definition: c4d_basecontainer.h:295
const BaseContainer * GetDataInstance() const
Definition: c4d_baselist.h:2346
Bool TestBreak()
Definition: c4d_thread.h:39
Definition: c4d_videopost.h:24
VPBuffer * GetBuffer(Int32 id, Int32 subid) const
A rendering bitmap buffer. Represents internally the same class as MultipassBitmap,...
Definition: c4d_tools.h:2469
Int32 GetBt() const
Definition: c4d_tools.h:2531
Bool SetLine(Int32 x, Int32 y, Int32 cnt, void *data, Int32 bitdepth, Bool dithering) const
for(i=0;i< length;i++)
Definition: unicodeobject.h:61
#define NewMemClear(T, cnt)
Definition: defaultallocator.h:204
OCIO_SRGB_TO_RENDERING
sRGB to Rendering color space transformation.
Definition: ge_prepass.h:16
OUTOFMEMORY
Not enough memory.
Definition: ge_prepass.h:1
maxon::Float32 Float32
Definition: ge_sys_math.h:68
maxon::Int32 Int32
Definition: ge_sys_math.h:60
COLORSPACETRANSFORMATION
Definition: ge_prepass.h:498
RENDERRESULT
Definition: ge_prepass.h:422
@ USERBREAK
User stopped the processing.
@ OUTOFMEMORY
Not enough memory.
@ FAILED
Generic error if a rendering has failed due to missing license or similar.
@ OK
Function was successful.
@ FRAME
Called when the renderer prepares to render a frame.
#define VPBUFFER_RGBA
RGB and alpha multipass channel.
Definition: c4d_videopostdata.h:116
void DeleteMem(T *&p)
Definition: defaultallocator.h:257
unsigned long Py_ssize_t width
Definition: pycore_traceback.h:88
_Py_clock_info_t * info
Definition: pytime.h:197
#define iferr_scope_handler
Definition: resultbase.h:1402
Bool open
true if it is an opening call. See also VideoPostData::Execute.
Definition: c4d_videopostdata.h:87
Render * render
The current render.
Definition: c4d_videopostdata.h:102
VIDEOPOSTCALL vp
the VideoPost call: VIDEOPOSTCALL
Definition: c4d_videopostdata.h:86
RENDERRESULT * error
The render result error: RENDERRESULT May be nullptr.
Definition: c4d_videopostdata.h:90
BaseDocument * doc
The active document.
Definition: c4d_videopostdata.h:92
BaseThread * thread
The executing thread. Use thread->TestBreak() to check for a user break.
Definition: c4d_videopostdata.h:94
Stores overwriteable color profiles associated with an upcoming rendering.
Definition: c4d_videopostdata.h:375
Definition: c4d_tools.h:2548