SOLVED RenderDocument produces different color

Hi,

I'm trying the RenderDocument python method to render my file. It works but for some reason it produces a different brightness/contrast compared when using the Render To Picture View command.

You can see the illustration of the problem below. I'm using Redshift when rendering but the problem still applies when just using Standard.
2023-01-11_13-53-28.gif

Here's the code I used:

import c4d


def main():
    rd = doc.GetActiveRenderData().GetClone().GetData()

    xRes = int(rd[c4d.RDATA_XRES])
    yRes = int(rd[c4d.RDATA_YRES])

    bmp = c4d.bitmaps.BaseBitmap()
    bmp.Init(x=xRes, y=yRes)

    res = c4d.documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)
    c4d.bitmaps.ShowBitmap(bmp)


if __name__ == '__main__':
    main()


Hello @bentraje,

Thank you for reaching out to us. Your question is missing a key piece of information, which color management mode your render document is in. I assume your render document is either in Basic mode and has Linear Workflow enabled, or you are in OCIO mode.

a4c9c1f3-6cef-4b8e-991b-af837093341e-image.png
Fig. I: The color management settings of document, press CTRL + D to open the Attribute Manager on them.

From this follow a few problems.

  1. There are known (and worked on bugs) with OCIO and SDR (8) and HDR (16+) bit depths and the render settings, the problem is quite complicated. In the end, this results in 8 bit images sometimes being treated as 16 bit images and then already pre-transformed 8 bit data being transformed again by the Picture Viewer.
  2. Your problem seems to be related to this, as neither the renderer nor the picture viewer do update the bitmap color profile of the render bitmap when you deviate from the default non-linear sRGB color management. Your script does not make any attempt to rectify this, resulting in different outputs.
  3. You currently lack the tools to cover all cases manually in Python, specifically you are unable to handle the OCIO case.
  4. There is also another bug with the PV causing a crash, when you try to invoke ShowBitmap without having opened the PV once first.

I will talk with the OCIO developer about (2.) as I we were already going to talk about (1.) next week. For (3.) we would have to fix BaseBitmap.SetColorProfile, I have created a task for that, but I am not sure when we will find the time to actually fix it.

Solutions

  1. We could fix RenderDocument. This could either happen en-passant by fixing problem (1.) which is tied to how the bitmaps of a render buffer are handled. Or we could fix the method itself, but this will probably take some time, as at least I would classify this of low priority since there are other ways to deal with this.
  2. Using the render queue or the Teams renderer module should rectify the problem, as you then do not have to manage the bitmap color profiles.
  3. Handle the color profile of the bitmap manually, you can however only do this partially due to being unable to set the OCIO transforms of a bitmap in Python. Find below an example for handling at least the Linear Workflow case.

Cheers,
Ferdinand

Result:

import c4d

doc: c4d.documents.BaseDocument # The active document.

def main():
    """
    """
    rd: c4d.BaseContainer = doc.GetActiveRenderData().GetClone().GetData()
    bmp: c4d.bitmaps.BaseBitmap = c4d.bitmaps.BaseBitmap()
    bmp.Init(int(rd[c4d.RDATA_XRES]), int(rd[c4d.RDATA_YRES]), 32)

    # #bmp currently has the default sRGB 1966-2.1 color profile, i.e., a profile for an SDR color 
    # space with a gamma of ~2.1. When the render document has either "Linear Workflow" or OCIO
    # enabled, this is not the correct render space.

    # Set the color profile to linear when the document in "Linear Workflow" mode.
    if (doc[c4d.DOCUMENT_COLOR_MANAGEMENT] == c4d.DOCUMENT_COLOR_MANAGEMENT_BASIC and
        doc[c4d.DOCUMENT_LINEARWORKFLOW]):
        bmp.SetColorProfile(c4d.bitmaps.ColorProfile.GetDefaultLinearRGB())
    # Set the OCIO color profiles when a document is in OCIO mode. This is currently not possible
    # in Python.
    elif doc[c4d.DOCUMENT_COLOR_MANAGEMENT] == c4d.DOCUMENT_COLOR_MANAGEMENT_OCIO:
        pass

    res: int = c4d.documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)
    if res == c4d.RENDERRESULT_OK:
        c4d.bitmaps.ShowBitmap(bmp)
    
if __name__ == '__main__':
    main()

@ferdinand

RE: Your question is missing a key piece of information, which color management mode your render document is in.

Ah gotcha. It's a known bug. Yea I was expecting it to work out of the box since I'm not modifying the document or render data. It's just the same as when running the Shift+R hot key.

Anyhow, your illustration code works as expected. Will close this thread now.