color space of MODATA_COLOR
-
Hi,
Could you please help me found the way to get the color space of the MODATA_COLOR retrieved from a object by C++ SDK?
I'd like to check if its color space could be changed to non-linear color space by some settings.
It seems the MODATA_COLOR remains in a linear color space regardless of settings in Scene Settings -> Project -> COLOR MANAGEMENT.Thanks!
-
Hello @BruceC,
Thank you for reaching out to us. I am struggling with your question, since it is missing the version of Cinema 4D you are targeting and I find some points you are making a bit suprising.
-
Since 2025, Cinema 4D is permanently using OCIO as a color management system. The default render space profile is ACEScg which is a linear color space. Before in 2024 and earlier, when still "basic" color management was around, the default was also "linear workflow", i.e., the computational space was linear sRGB then.
-
All computations happen in the computational color space (render space in OCIO). There are some isolated exceptions to this, NodeData::Init is a big one in 2025, but the general rule applies. In the context of MoGraph exceptions can also apply, for example when you source your particle colors from a vertex color tag (which does not yet have a color profile), you can run into inconsistencies.
-
There is no function with which you could retrieve the color space of a color, as this would counter the idea of linear workflow/OCIO. All computations happen in the computational color space (LF), the render space (OCIO). The computational color spaces are:
- Basic - No Linear Workflow: sRGB 2.1
- Basic - Linear Workflow: linear sRGB, i.e., sRGB 1.0
- OCIO (as of 2025 the only option): The render space, by default ACEScg which is a color space with a gamma of 1.0.
I also checked an older 2024.2 version, and I could not spot anything out of the ordinary there with
MODATA_COLOR
(I just printed some particle color values using different color management settings).What might here be your implicit question, is that nothing happens when you switch a scene. I.e., you have a scene that has been created with Basic color management with linear workflow turned off, and you now turn linear workflow on. This just changes in which color space scene color data is interpreted, it does not convert scene colors. For OCIO later then we created the scene color conversion functionality, which among other places is accessible as SceneColorConverter in the API. But as a render engine you should usually not have to run this, as this will alter the physical data of a document, i.e., is something usually only the user should do. What also might trip you, is that you are misusing our colour picker (which is by default picking colors in sRGB 2.1).
But I am getting very speculative here. Please provide the Cinema 4D version you are targeting, and a code example and concrete scenario where your problems occur.
Cheers,
Ferdinand -
-
Thank you very much for the detailed explanation, @ferdinand.
Sorry for not making the initial question clear.I actually need to support multiple C4D versions: from R21 to latest R2025.
I have noticed that the new R2025 changed the color management system settings under Scene Settings -> Project -> COLOR MANAGEMENT.
I also played the COLOR MANAGEMENT settings in both R2025 and R2024, it seems all possible options use linear color space for calculations. But my concern is if there are options that could make it use non-linear color space for calculation, and if it leads to changing an object's MODATA_COLOR data values.The below is the code snippet used to get the MODATA_COLOR data.
BaseObject *op = xxx; BaseTag *tag = op->GetTag(ID_MOTAGDATA); if (tag) { GetMoDataMessage msg_data; if (tag->Message(MSG_GET_MODATA, &msg_data) && msg_data.modata) { MDArray<Vector> colors = md->GetVectorArray(MODATA_COLOR); ............... } }
The colors data got in the above code snippet will be used to set a customized texture object's input image. And the customized texture object's color space matters.
I found that I will have the expected result if only linear color space is used in the customized texture object in a test scene.
In R2024, I always found "The Application uses Linear Space for Calculations." in Basic COLOR MANAGEMENT regardless of the settings.
In R2025, I found different information (e.g. "Calculations happen in linear sRGB space.", "Calculations happen in ACES2065-1 space.") in COLOR MANAGEMENT according to the settings. And all of them seems to be linear color spaces in the scene I used.
But I don't know if the MODATA_COLOR data got above will always in linear color space. And I couldn't enumerate all possible COLOR MANAGEMENT settings to check.
So I'd like to find out if there is a way to get the color space of the MODATA_COLOR data, so the correct color space could be set in the customized texture object.Thank you!
-
Hello @BruceC,
Thank you for providing more details. I have a better sense now of what you are trying to do, I am however still not sure about some details. Let me first state some facts and then ask you two questions at the end.
Answers
I have noticed that the new R2025 changed the color management system settings under Scene Settings -> Project -> COLOR MANAGEMENT.
Yes, that is true. As stated above, the legacy "Basic" color management has been removed with 2025. Cinema now always uses OCIO. What has also changed with 2025.0.0 is the color picker.
in both R2025 and R2024, it seems all possible options use linear color space for calculations
That is not entirely true, see the list I made in my first posting. In Cinema 4D versions before 2025.0.0, when you had "Basic" color management enabled and linear workflow disabled, your computational space was sRGB 2.1. But since LWF was the default in Basic mode for a long time, it is very unlikely to encounter that in the wild.
In R2024, I always found "The Application uses Linear Space for Calculations." in Basic COLOR MANAGEMENT regardless of the settings. In R2025, I found different information (e.g. "Calculations happen in linear sRGB space.", "Calculations happen in ACES2065-1 space.")
I am not sure where you found that information, but it is not correct (please let me know when the user docs publish such incorrect information). 2024 supported both OCIO and Basic color management, but even if we go back to for example S26 where only Basic existed, Cinema 4D could use a non-linear computational color space when the user did disable linear workflow.
In 2025, the OCIO render space can be technically anything since the whole purpose of OCIO is that the user can configure the three principal color spaces (render, display, view transform). ACES20265-1 is also not a working space (more or less OCIO/ACES slang for a computational space) but an input space, i.e., it is meant to bring in texture data. Setting it as the working space is quite unusual.
As already stated above, Cinema 4D is and always has used the default ACES working space ACEScg as its OCIO render space profile (fancy way of saying all data is assumed to be ACEScg when computations happen). As also stated above, there are some minor exceptions to this such as NodeData::Init where colors are interpreted as sRGB 2.2 (or more concretely - Cinema 4D will apply an sRGB-2.2->render-space transform to all colors set in NodeData::Init). See ACES: Encodings for details on the purpose of ACES color spaces.
But I don't know if the MODATA_COLOR data got above will always in linear color space. And I couldn't enumerate all possible COLOR MANAGEMENT settings to check. So I'd like to find out if there is a way to get the color space of the MODATA_COLOR data, so the correct color space could be set in the customized texture object.
MODATA_COLOR
will be in the color space I listed in my first posting under point 3. And as I said, there is no way "to find out" in what color space a color is, as this is not explicit metadata attached to a color. It would also contradict the idea of linear workflow and OCIO of having a unified computational color space.I would also recommend having a look at:
- Color Managment Manual: Explains core concepts of color management and how they are represented in our API.
- OpenColorIO Manual: Explains the basics of OCIO and how it is realized in our API.
Questions
Okay, now let's get to the questions. While I have a bit more concrete idea of what you are trying to do, there are still some question marks for me. You seem to try to write MoGraph color data into a 'customized texture object'.
- What is that 'customized texture object' concretely? I assume the texture node in the material/shader system of your render engine?
- What leads you to the assumption that your colors are wrong?
- How are you writing the data into the texture, and how is your render engine interpreting its input space?
Let's unfold a few more things here. Modern color management divides an application into at least three color spaces, an input space (that is how textures and color choices from the user come in), a computational space (render space in OCIO) to which all these input colors are converted to for rendering, and finally an output space, i.e., the color profile used by bitmap outputs of the app.
The in- and output spaces are other than the computational space usually not unified. I.e., the user could use both an old sRGB 2.1 PNG, a sRGB 1.0 HDR, and a fancy PSD in ACES2065-1 in his or her project. The same goes for the output space, the user could render the same document to different output spaces.
So, when you have some scene data, which is in the computational space of the scene, and you want to write that data into a texture, you will have to transform that color to the color space of the texture. When you are using
cinema::BaseBitmap
as your bitmap type, there are dedicated color profiles attached to the bitmap for input (image), render, display, and view transform under which the bitmap shall be used.In the end I am also guessing here a bit, since this heavily depends on how you render engine implements bitmaps, color management, and its rendering pipeline.
Cheers,
FredinandPS: Check the OCIO manual for color conversions. When you want to define your procedural texture in a fancy color space like for example 'ACES2065-1', you will need an ICC profile of that space. Not all OCIO/ACES color spaces are representable as ICC profiles (no clue if that applies here).
-
Hi @ferdinand. Thank you very much for the detailed explanation.
Let me try to answer your questions first.
What is that 'customized texture object' concretely? I assume the texture node in the material/shader system of your render engine?
yes, that's true.
What leads you to the assumption that your colors are wrong?
How are you writing the data into the texture, and how is your render engine interpreting its input space?The colors are used as input texture for a gradient map node in our render engine. So the color is not directly used for a object's color.
The final rendered image from our render engine should match C4D viewport, so that's how I tell if the result is correct.In R2024, I always found "The Application uses Linear Space for Calculations."
Sorry, as you said this is not true. If I untick "Linear Workflow" checkbox, I will actuall see "The Application uses sRGB Space for Calculations."
I thought MODATA_COLOR is in computational color space which is controlled by the settings in Scene Settings -> Project -> COLOR MANAGEMENT, that's why I thought I can get the MODATA_COLOR's color space by an API.
However, the colors values I got from MODATA_COLOR remain the same no matter if "Linear Workflow" checkbox is ticked or not.
So this means my thought was wrong, otherwise the values of MODATA_COLOR will change if I ticke/untick the "Linear Workflow" checkbox.Does this mean that MODATA_COLOR's value won't be affected by any scene level color space settings?
It seems the color I got from MODATA_COLOR is always linear no matter if "Linear Workflow" checkbox is ticked.
No matter if "Linear Workflow" checkbox is ticked I can get the expected result in below two ways:- If I set the image buffer of our render engine's texture node directly use the MODATA_COLOR's color values, and set the texture node's color space as linear srgb, then I will have the same image as the viewport.
- I can also call BasicTransformColor() with COLORSPACETRANSFORMATION::LINEAR_TO_SRGB before setting the image buffer, and also set the texture node's color space as srgb, then I will also have the same image as the viewport.
Although the two way work, I'm not sure if some settings can change the MODATA_COLOR's values I get, so I asked the original question.
-
Hey @BruceC,
I think I understand now what your problem is and what you mean by 'MODATA_COLOR is always linear'.
@BruceC said:
I thought MODATA_COLOR is in computational color space which is controlled by the settings in Scene Settings Project -> COLOR MANAGEMENT, that's why I thought I can get the MODATA_COLOR's color space by an API. However, the colors values I got from MODATA_COLOR remain the same no matter if "Linear Workflow" checkbox is ticked or not [...]
Does this mean that MODATA_COLOR's value won't be affected by any scene level color space settings? It seems the color I got from MODATA_COLOR is always linear no matter if "Linear Workflow" checkbox is ticked.
The major misconception seems to be here what changing color management settings does in Cinema 4D (pre-2025 at least). As pointed out in my first answer, changing these settings does not (always) entail scene colors to be converted:
@ferdinand said:
What might here be your implicit question, is that nothing happens when you switch a scene. I.e., you have a scene that has been created with Basic color management with linear workflow turned off, and you now turn linear workflow on. This just changes in which color space scene color data is interpreted, it does not convert scene colors. For OCIO later then we created the scene color conversion functionality, which among other places is accessible as
SceneColorConverter
in the API.When you toggle a scene between linear workflow on and off, literally nothing will happen to all the color parameters in it. What will change, is how Cinema 4D will bring colors in and out of that scene, i.e., what color value is written when the user picks a color in sRGB-2.1 space in a color picker, how a texture is converted before rendering, and how the final render data is then converted into an output bitmap.
Existing colors stored in a scene, are then just reinterpreted as colors in that new color space. Reinterpreted Iin the sense as that when they or their byproducts must be converted into other color spaces for display or file output, they will be treated as colors of that newly set color space (although their numerical values have been defined for a different space before). I.e., they effectively become different colors. That is not the most sensible thing from a modern OCIO perspective, but that is how 'Basic' mode worked.
With 2024 we then introduced OCIO, which had the same behavior, changing to OCIO or the render space in OCIO would not automatically entail a scene color conversion. But we added the option to do that (the backend is the mentioned
SceneColorConverter
). With 2025 this now has changed and all render space changes also always entail a value conversion.
So, this is first of all not bound to
MODATA_COLOR
and would apply to all color values in a scene. And when the scene is in Basic + NO LWF mode and your render texture uses an sRGB-1.0 profile, you would have to convert that color from sRGB-2.1 to sRGB-1.0, when the scene is in OCIO mode, you would have to convert from render space to sRGB-1.0. And when then scene is in Basic + LWF mode, you would not have to do anything at all.To my knowledge there is currently no exception in the MoGraph code which would always treat
MODATA_COLOR
as linear (if anything there could be an extra transform applied, but I am not ware of any in that case). When you still encounter a mismatch between your render engine output and our viewport, please reach out to us. It would then probably easier if you just show me.Cheers,
Ferdinand -
Thank you very much, @ferdinand
I think I start understanding it now.
The MODATA_COLOR values existing in the scene won't get changed by the scene's color space settings, instead, they could be interpreted differently when scene's color space setting changes.
In the scene I'm testing, the MODATA_COLOR comes from a Linear Field (doesn't necessarily be Linear Filed, it could be other Filed types, like Box Filed, Capsule Filed) of Plain effector's Fields setting. The MODATA_COLOR values are not real colors, they are used to find the texture for each instance from a Multi Shader's setting.
So I think in this case, it could be safely assume the data is linear values?
If this is true, is there is a way to find if a MODATA_COLOR from a Field? So I can make sure MODATA_COLOR from Field are treated as linear values.Thanks!
-
Hi @ferdinand, thanks for all you help.
I think a cloner's MODATA_COLOR should be interpreted if the cloner uses Multi Shader. Is my understanding correct? -
Hey @BruceC,
So I think in this case, it could be safely assume the data is linear values?
Normally, there should be no assumptions, the data should just be what the color management says. But I now replicated your field driving colors setup, and I too stumbled upon something which I cannot explain, at least at the moment.
-
Thank you very much, @ferdinand
Yeah, in the video you attached, it looks to me that Linear workflow doesn't affect the final render result.I have got the approval to attach this simple test scene that demonstrates the problem I'm experiencing. The setting is a bit different with your scene.
The scene attached uses Multi Shader. My understanding is that the MODATA_COLOR from the effector field is used to find which texture defined in the Multi Shader should be applied to each cloned instance. (so the MODATA_COLOR values are more like texture indexes). So the MODATA_COLOR values are not really used as colors in the viewport, and shouldn't be treated as gamma-corrected values regardless of the scene's color space.
Please let me know if my understanding is correct. Thanks again! -
Hey @BruceC,
thank you for the scene. Just as an FYI, you can always share data confidentially with us via
sdk_support(at)maxon(dot)net
. In general, we encourage all users, including Maxon Registered Developers, to discuss problems in public, so that the whole community can benefit. But for sensitive topics there is of course always the option to switch to mail.Regarding your scene file:
- Could you please share the exact version you are using for testing. As I said, I am aware that you want to target multiple versions, but for bug reporting we should have a precise version, so that I can look at that exact version.
- Please also provide a bullet-point step-by-step bug report as lined out before. See Support Procedures: Reporting Bugs and Crashes for details. Our insistence on these bug reports might seem a 'unnecessary' from the user side, but they really make a world of difference, when you try to debug something as complex as Cinema 4D.
Cheers,
FerdinandPS: I am a bit busy with the new C++ SDK at the moment, I will probably only get to having a closer look at this by the 27th.
PPS: What I forgot to mention, is that it could also be the Picture Viewer itself which is here interfering (i.e., the actual bitmap saved to disk is okay, the PV is just displaying it incorrectly. We had a few issues with the PV and OCIO over time). -
Thanks, @ferdinand
- I think it's easier to reproduce this problem with C4D 2024 (say 2024.5.1).
- I don't think this is a bug with C4D. It's a problem with our plugin about how to use C4D MODATA_COLOR from the effector field for Multi Shader in our Render Engine. The viewport always has the expected correct result, it's our plugin who doesn't produce the expected result.
With more and more thinking and testing, I began to believe that in the scene attached the MODATA_COLOR from the effector field is used to find which texture defined in the Multi Shader should be applied to each cloned instance. (so the MODATA_COLOR values are more like texture indexes). So the MODATA_COLOR values are not really used as colors in the viewport, and shouldn't be treated as gamma-corrected values regardless of the scene's color space.
If my above understanding is correct, I think our plugin just need to treat the MODATA_COLOR values in this particular case the same way as C4D viewport. Currently, our plugin convert the MODATA_COLOR values from linear to srgb based on the scene's color space, which I think is incorrect, because I think the MODATA_COLOR values are not real colors in this case.
-
Hey @BruceC,
Thank you for the added information, but I will still need that step by step bug report. Without it, I will not touch a debugger or a scene file. There are a plethora of reasons why this could go wrong. I am still very much in the dark at what you are looking exactly (e.g., are you using our Picture Viewer to view render results, or do you use your render engines one. What are your rendering and how, etc., pp.).
As I told you, applying a manual transform is not intended. It might be what you have to do as a work-around for older versions which we won't (hot)fix anymore, but there is no default answer here for you. But for all of that I first need a reliable bug/issue report which I can reproduce, and then other than you look at with a debug version of Cinema 4D. As I said, feel free to use your render engine, and please be precise in the reproduction steps. If you want to, you can also use our beta program bug tracker instead (since you are an MRD).
Cheers,
Ferdinand