Resolve Color Management DRT in OCIO?

We have footage in AP0 that we are reading into Nuke. The LUT is in DaVinci Intermediate, which we have in the OCIO config, however Davinci YRGB Color Managed also has a Display Transform that is similar to, but clearly different from the ACES Display Transform. Is there an OCIO color space for the Davinci YRGB Color Managed DRT? If not is there a LUT? Or could someone assist with the process of making either?

Thanks!

1 Like

Does it have to be OCIO? I can send you a pure Nuke nodes version

If you have Resolve installed somewhere, even the free version, it’s fairly quick to generate one. Just import any clip into the media pool, create a new timeline of it by rightclicking it. Then on the color page add a ColorSpaceTransform effect with DWG/Intermediate → Display space and leave the other settings at default. Then rightclick that clip’s thumbnail on the color page and Generate LUT → 33 or 65…

Then you could add that LUT into your OCIO config paried with the necessary pre transforms as a display/colorspace.

1 Like
set cut_paste_input [stack 0]
push $cut_paste_input
Group {
 name RCM
 label "Expected Input is Linear Davinci Wide Gamut and output DaResolve's Rec709 Gamma 2.4"
 selected true
 xpos -386
 ypos -115
}
 Input {
  inputs 0
  name Input1
  xpos 0
 }
 Group {
  name LogConvert_Davinci_Intermediate
  selected true
  xpos 0
  ypos 49
  disable true
  addUserKnob {20 Intermediate_tab l Intermediate}
  addUserKnob {4 operation M {log2lin lin2log}}
 }
  Input {
   inputs 0
   name Input
   xpos -40
   ypos -10
  }
  Dot {
   name Dot1
   xpos -6
   ypos 114
  }
set Nf878d400 [stack 0]
  Expression {
   expr0 r<=DI_LIN_CUT?r*DI_M:(log(r+DI_A)/log(2)+DI_B)*DI_C
   expr1 g<=DI_LIN_CUT?g*DI_M:(log(g+DI_A)/log(2)+DI_B)*DI_C
   expr2 b<=DI_LIN_CUT?b*DI_M:(log(b+DI_A)/log(2)+DI_B)*DI_C
   channel3 none
   name lin2log
   xpos 80
   ypos 110
   addUserKnob {20 Params}
   addUserKnob {7 DI_A}
   DI_A 0.0075
   addUserKnob {7 DI_B}
   DI_B 7
   addUserKnob {7 DI_C}
   DI_C 0.07329248
   addUserKnob {7 DI_M}
   DI_M 10.44426855
   addUserKnob {7 DI_LIN_CUT}
   DI_LIN_CUT 0.00262409
   addUserKnob {7 DI_LOG_CUT}
   DI_LOG_CUT 0.02740668
  }
push $Nf878d400
  Expression {
   expr0 r<=DI_LOG_CUT?r/DI_M:pow(2.0,(r/DI_C)-DI_B)-DI_A
   expr1 g<=DI_LOG_CUT?g/DI_M:pow(2.0,(g/DI_C)-DI_B)-DI_A
   expr2 b<=DI_LOG_CUT?b/DI_M:pow(2.0,(b/DI_C)-DI_B)-DI_A
   channel3 none
   name log2lin
   xpos -160
   ypos 110
   addUserKnob {20 Params}
   addUserKnob {7 DI_A}
   DI_A 0.0075
   addUserKnob {7 DI_B}
   DI_B 7
   addUserKnob {7 DI_C}
   DI_C 0.07329248
   addUserKnob {7 DI_M}
   DI_M 10.44426855
   addUserKnob {7 DI_LIN_CUT}
   DI_LIN_CUT 0.00262409
   addUserKnob {7 DI_LOG_CUT}
   DI_LOG_CUT 0.02740668
  }
  Switch {
   inputs 2
   which {{parent.operation}}
   name Operation
   xpos -40
   ypos 190
  }
  Output {
   name Output1
   xpos -40
   ypos 310
  }
 end_group
 Expression {
  expr0 invert?(s0*r/(s1-r))**(1/n):s1*r**n/(r**n+s0)
  expr1 invert?(s0*g/(s1-g))**(1/n):s1*g**n/(g**n+s0)
  expr2 invert?(s0*b/(s1-b))**(1/n):s1*b**n/(b**n+s0)
  name NakaRush
  xpos 0
  ypos 122
  addUserKnob {20 User}
  addUserKnob {7 n R 1 10}
  n 1
  addUserKnob {7 g0}
  g0 0.09
  addUserKnob {7 g1}
  g1 0.09
  addUserKnob {7 m0}
  m0 100
  addUserKnob {7 m1}
  m1 1
  addUserKnob {7 s0}
  s0 {{(g0**n)*(s1-g1)/g1}}
  addUserKnob {7 s1}
  s1 {{m1*g1*(g0**n-m0**n)/(m1*g0**n-g1*m0**n)}}
  addUserKnob {6 invert +STARTLINE}
 }
 Group {
  name GamutConvert
  tile_color 0xcc804eff
  label "DaVinci Wide Gamut to Rec709"
  xpos 0
  ypos 167
  addUserKnob {20 Params}
  addUserKnob {35 presets_src l src M {"gamut/ACES AP0" "knobs this \{src_name \"ACES AP0\" src \"0.7347 0.2653 0.0 1.0 0.0001 -0.077 0.32168 0.33767\"\}" "gamut/ACES AP1" "knobs this \{src_name \"ACES AP1\" src \"0.713 0.293 0.165 0.83 0.128 0.044 0.32168 0.33767\"\}" "gamut/Filmlight E-Gamut" "knobs this \{src_name \"Filmlight E-Gamut\" src \"0.8 0.3177 0.18 0.9 0.065 -0.0805 0.3127 0.329\"\}" "gamut/DaVinci Wide Gamut" "knobs this \{src_name \"DaVinci Wide Gamut\" src \"0.8 0.313 0.1682 0.9877 0.079 -0.1155 0.3127 0.329\"\}" gamut/Rec709 "knobs this \{src_name \"Rec709\" src \"0.64 0.33 0.3 0.6 0.15 0.06 0.3127 0.329\"\}" gamut/Rec2020 "knobs this \{src_name \"Rec2020\" src \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" gamut/P3D60 "knobs this \{src_name \"P3D60\" src \"0.68 0.32 0.265 0.69 0.15 0.06 0.321626 0.337737\"\}" gamut/P3D65 "knobs this \{src_name \"P3D65\" src \"0.68 0.32 0.265 0.69 0.15 0.06 0.3127 0.329\"\}" gamut/P3DCI "knobs this \{src_name \"P3DCI\" src \"0.68 0.32 0.265 0.69 0.15 0.06 0.314 0.351\"\}" "gamut/Arri Wide Gamut" "knobs this \{src_name \"Arri Wide Gamut\" src \"0.684 0.313 0.221 0.848 0.0861 -0.102 0.3127 0.329\"\}" "gamut/Arri Wide Gamut 4" "knobs this \{src_name \"Arri Wide Gamut 4\" src \"0.7347 0.2653 0.1424 0.8576 0.0991 -0.0308 0.3127 0.329\"\}" "gamut/RED Wide Gamut RGB" "knobs this \{src_name \"RED Wide Gamut RGB\" src \"0.780308 0.304253 0.121595 1.493994 0.095612 -0.084589 0.3127 0.329\"\}" "gamut/GoPro Protune Native" "knobs this \{src_name \"GoPro Protune Native\" src \"0.69848046 0.19302645 0.32955538 1.02459662 0.10844263 -0.03467857 0.3127 0.329\"\}" "gamut/Canon Cinema Gamut" "knobs this \{src_name \"Canon Cinema Gamut\" src \"0.74 0.27 0.17 1.14 0.08 -0.1 0.3127 0.329\"\}" "gamut/Sony SGamut3" "knobs this \{src_name \"Sony SGamut3\" src \"0.73 0.28 0.14 0.855 0.1 -0.05 0.3127 0.329\"\}" "gamut/Sony SGamut3.Cine" "knobs this \{src_name \"Sony SGamut3.Cine\" src \"0.766 0.275 0.225 0.8 0.089 -0.087 0.3127 0.329\"\}" "gamut/Panasonic V-Gamut" "knobs this \{src_name \"Panasonic V-Gamut\" src \"0.73 0.28 0.165 0.84 0.1 -0.03 0.3127 0.329\"\}" "gamut/DJI D-Gamut" "knobs this \{src_name \"DJI D-Gamut\" src \"0.71 0.31 0.21 0.88 0.09 -0.08 0.3127 0.329\"\}" "gamut/Fujifilm F-Gamut" "knobs this \{src_name \"Fujifilm F-Gamut\" src \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" "gamut/Nikon N-Gamut" "knobs this \{src_name \"Nikon N-Gamut\" src \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" "gamut/Blackmagic Wide Gamut" "knobs this \{src_name \"Blackmagic Wide Gamut\" src \"0.7177215 0.3171181 0.228041 0.861569 0.1005841 -0.0820452 0.3127 0.329\"\}" "gamut/Adobe RGB" "knobs this \{src_name \"Adobe RGB\" src \"0.64 0.33 0.21 0.71 0.15 0.06 0.3127 0.329\"\}" "gamut/Adobe WideGamutRGB" "knobs this \{src_name \"Adobe WideGamutRGB\" src \"0.7347 0.2653 0.1152 0.8264 0.1566 0.0177 0.3457 0.3585\"\}" gamut/ProPhotoRGB "knobs this \{src_name \"ProPhotoRGB\" src \"0.734699 0.265301 0.159597 0.840403 0.036598 0.000105 0.345704 0.358540\"\}"}}
  addUserKnob {1 src_name l "" -STARTLINE}
  src_name "DaVinci Wide Gamut"
  addUserKnob {1 src l " " t "source gamut chromaticities: rgbw"}
  src "0.8 0.313 0.1682 0.9877 0.079 -0.1155 0.3127 0.329"
  addUserKnob {35 presets_dst l dst M {gamut/XYZ "knobs this \{dst_name \"XYZ\" dst \"\"\}" "gamut/XYZ D65" "knobs this \{dst_name \"XYZ D65\" dst \"1 0 0 1 0 0 0.3127 0.329\"\}" "gamut/ACES AP0" "knobs this \{dst_name \"ACES AP0\" dst \"0.7347 0.2653 0.0 1.0 0.0001 -0.077 0.32168 0.33767\"\}" "gamut/ACES AP1" "knobs this \{dst_name \"ACES AP1\" dst \"0.713 0.293 0.165 0.83 0.128 0.044 0.32168 0.33767\"\}" "gamut/Filmlight E-Gamut" "knobs this \{dst_name \"Filmlight E-Gamut\" dst \"0.8 0.3177 0.18 0.9 0.065 -0.0805 0.3127 0.329\"\}" "gamut/DaVinci Wide Gamut" "knobs this \{dst_name \"DaVinci Wide Gamut\" dst \"0.8 0.313 0.1682 0.9877 0.079 -0.1155 0.3127 0.329\"\}" gamut/Rec709 "knobs this \{dst_name \"Rec709\" dst \"0.64 0.33 0.3 0.6 0.15 0.06 0.3127 0.329\"\}" gamut/Rec2020 "knobs this \{dst_name \"Rec2020\" dst \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" gamut/P3D60 "knobs this \{dst_name \"P3D60\" dst \"0.68 0.32 0.265 0.69 0.15 0.06 0.321626 0.337737\"\}" gamut/P3D65 "knobs this \{dst_name \"P3D65\" dst \"0.68 0.32 0.265 0.69 0.15 0.06 0.3127 0.329\"\}" gamut/P3DCI "knobs this \{dst_name \"P3DCI\" dst \"0.68 0.32 0.265 0.69 0.15 0.06 0.314 0.351\"\}" "gamut/Arri Wide Gamut" "knobs this \{dst_name \"Arri Wide Gamut\" dst \"0.684 0.313 0.221 0.848 0.0861 -0.102 0.3127 0.329\"\}" "gamut/Arri Wide Gamut 4" "knobs this \{dst_name \"Arri Wide Gamut 4\" dst \"0.7347 0.2653 0.1424 0.8576 0.0991 -0.0308 0.3127 0.329\"\}" "gamut/RED Wide Gamut RGB" "knobs this \{dst_name \"RED Wide Gamut RGB\" dst \"0.780308 0.304253 0.121595 1.493994 0.095612 -0.084589 0.3127 0.329\"\}" "gamut/GoPro Protune Native" "knobs this \{dst_name \"GoPro Protune Native\" dst \"0.69848046 0.19302645 0.32955538 1.02459662 0.10844263 -0.03467857 0.3127 0.329\"\}" "gamut/Canon Cinema Gamut" "knobs this \{dst_name \"Canon Cinema Gamut\" dst \"0.74 0.27 0.17 1.14 0.08 -0.1 0.3127 0.329\"\}" "gamut/Sony SGamut3" "knobs this \{dst_name \"Sony SGamut3\" dst \"0.73 0.28 0.14 0.855 0.1 -0.05 0.3127 0.329\"\}" "gamut/Sony SGamut3.Cine" "knobs this \{dst_name \"Sony SGamut3.Cine\" dst \"0.766 0.275 0.225 0.8 0.089 -0.087 0.3127 0.329\"\}" "gamut/Panasonic V-Gamut" "knobs this \{dst_name \"Panasonic V-Gamut\" dst \"0.73 0.28 0.165 0.84 0.1 -0.03 0.3127 0.329\"\}" "gamut/DJI D-Gamut" "knobs this \{dst_name \"DJI D-Gamut\" dst \"0.71 0.31 0.21 0.88 0.09 -0.08 0.3127 0.329\"\}" "gamut/Fujifilm F-Gamut" "knobs this \{dst_name \"Fujifilm F-Gamut\" dst \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" "gamut/Nikon N-Gamut" "knobs this \{dst_name \"Nikon N-Gamut\" dst \"0.708 0.292 0.17 0.797 0.131 0.046 0.3127 0.329\"\}" "gamut/Blackmagic Wide Gamut" "knobs this \{dst_name \"Blackmagic Wide Gamut\" dst \"0.7177215 0.3171181 0.228041 0.861569 0.1005841 -0.0820452 0.3127 0.329\"\}" "gamut/Adobe RGB" "knobs this \{dst_name \"Adobe RGB\" dst \"0.64 0.33 0.21 0.71 0.15 0.06 0.3127 0.329\"\}" "gamut/Adobe WideGamutRGB" "knobs this \{dst_name \"Adobe WideGamutRGB\" dst \"0.7347 0.2653 0.1152 0.8264 0.1566 0.0177 0.3457 0.3585\"\}" gamut/ProPhotoRGB "knobs this \{dst_name \"ProPhotoRGB\" dst \"0.734699 0.265301 0.159597 0.840403 0.036598 0.000105 0.345704 0.358540\"\}"}}
  addUserKnob {1 dst_name l "" -STARTLINE}
  dst_name Rec709
  addUserKnob {1 dst l " " t "destination gamut chromaticities: rgbw"}
  dst "0.64 0.33 0.3 0.6 0.15 0.06 0.3127 0.329"
  addUserKnob {83 cat M {bradford cat02 none}}
  cat cat02
  addUserKnob {26 ""}
  addUserKnob {6 invert t "invert matrix direction" +STARTLINE}
  addUserKnob {22 calc l Calculate t "Calculate a 3x3 matrix to convert from source gamut to destination gamut, with chromatic adaptation transform if whitepoints are different." -STARTLINE T "import nuke\n\ndef matmul(m0, m1):\n  # multiply two square matrices\n  return \[\[sum(a*b for a,b in zip(r, c)) for c in zip(*m1)] for r in m0]\n\ndef vdot(m, v):\n  # multiply AxA matrix by Ax1 vector\n  return \[sum(x*y for x,y in zip(r,v)) for r in m]\n\ndef transpose(m):\n  # transpose matrix m by swapping rows and cols\n  return \[list(r) for r in zip(*m)]\n\ndef zeros(l):\n  # create square matrix of size l\n  return \[\[0.0]*l for i in range(l)]\n\ndef diag(m, v):\n  # set diagonal row of matrix m to vector v or float v\n  if isinstance(v, float): \n    v = \[v]*len(m)\n  for p in range(len(m)):\n    m\[p]\[p] = v\[p]\n  return m\n\ndef identity(l):\n  # return identity matrix of size l\n  return diag(zeros(3), 1.0)\n\ndef det(m):\n  # calculate determinant of 3x3 matrix m\n  return m\[0]\[0]*(m\[1]\[1]*m\[2]\[2]-m\[2]\[1]*m\[1]\[2])-m\[0]\[1]*(m\[1]\[0]*m\[2]\[2]-m\[1]\[2]*m\[2]\[0])+m\[0]\[2]*(m\[1]\[0]*m\[2]\[1]-m\[1]\[1]*m\[2]\[0])\n\ndef inv(m):\n  # invert 3x3 matrix m\n  d = det(m)\n  if d == 0.0:\n    return m\n  i = zeros(3)\n  i\[0]\[0] = (m\[1]\[1]*m\[2]\[2]-m\[2]\[1]*m\[1]\[2])/d\n  i\[0]\[1] = (m\[0]\[2]*m\[2]\[1]-m\[0]\[1]*m\[2]\[2])/d\n  i\[0]\[2] = (m\[0]\[1]*m\[1]\[2]-m\[0]\[2]*m\[1]\[1])/d\n  i\[1]\[0] = (m\[1]\[2]*m\[2]\[0]-m\[1]\[0]*m\[2]\[2])/d\n  i\[1]\[1] = (m\[0]\[0]*m\[2]\[2]-m\[0]\[2]*m\[2]\[0])/d\n  i\[1]\[2] = (m\[1]\[0]*m\[0]\[2]-m\[0]\[0]*m\[1]\[2])/d\n  i\[2]\[0] = (m\[1]\[0]*m\[2]\[1]-m\[2]\[0]*m\[1]\[1])/d\n  i\[2]\[1] = (m\[2]\[0]*m\[0]\[1]-m\[0]\[0]*m\[2]\[1])/d\n  i\[2]\[2] = (m\[0]\[0]*m\[1]\[1]-m\[1]\[0]*m\[0]\[1])/d\n  return i\n\ndef flatten(l):\n  # flatten multidimensional list into one dimensional list\n  return sum(l, \[])\n\ndef npm(ch):\n  # Calculate the Normalized Primaries Matrix for the specified chromaticities\n  # Adapted from SMPTE Recommended Practice - Derivation of Basic Television Color Equations\n  # http://doi.org/10.5594/S9781614821915\n  if len(ch) == 8: # handle flat list\n    ch = \[\[ch\[0], ch\[1]], \[ch\[2], ch\[3]], \[ch\[4], ch\[5]], \[ch\[6], ch\[7]]]\n  for c in ch:\n    c.append(1.0-c\[0]-c\[1]) \n  P = transpose(\[ch\[0], ch\[1], ch\[2]])\n  W = \[ch\[3]\[0] / ch\[3]\[1], 1.0, ch\[3]\[2] / ch\[3]\[1]]\n  C = vdot(inv(P), W)\n  C = diag(zeros(3), C)\n  return matmul(P, C)\n\ndef cat(ws, wd, method='bradford'):\n  # Calculate a von Kries style chromatic adaptation transform matrix given xy chromaticities for src and dst white\n  # Source: Mark D. Fairchild - 2013 - Color Appearance Models Third Edition p. 181-186\n  # Source: Bruce Lindbloom - Chromatic Adaptation - http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html\n  if ws == wd: # src and dst are equal, nothing to do\n    return identity(3)\n  if method == 'bradford':\n    mcat = \[\[0.8951, 0.2664, -0.1614], \[-0.7502, 1.7135, 0.0367], \[0.0389, -0.0685, 1.0296]]\n  elif method == 'cat02':\n    mcat = \[\[0.7328, 0.4296, -0.1624], \[-0.7036, 1.6975, 0.0061], \[0.003, 0.0136, 0.9834]]\n  else:\n    mcat = identity(3)\n  \n  def xy_to_XYZ(xy):\n    # convert xy chromaticity to XYZ tristimulus with Y=1.0\n    return \[xy\[0]/xy\[1], 1.0, (1.0-xy\[0]-xy\[1])/xy\[1]]\n  \n  sXYZ = xy_to_XYZ(ws)\n  dXYZ = xy_to_XYZ(wd)\n  \n  s_cone_mtx = vdot(mcat, sXYZ)\n  d_cone_mtx = vdot(mcat, dXYZ)\n  \n  smat = diag(zeros(3), \[a/b for a,b in zip(d_cone_mtx, s_cone_mtx)])\n  nmtx = matmul(inv(mcat), smat)\n  return matmul(nmtx, mcat)\n\ndef wp(ch):\n  # return whitepoint of chromaticities array\n  return ch\[-2:]\n\ndef is_xyz(ch):\n  # test if ch is XYZ\n  prims = ch\[:-2]\n  return True if prims == \[1, 0, 0, 1, 0, 0] else False\n\ndef calc_mtx(ch0, ch1, method='bradford'):\n  # calculate 3x3 matrix to convert gamut ch0 to ch1, with cat\n  if not ch1:\n    return npm(ch0)\n  rgb0_to_xyz = identity(3) if is_xyz(ch0) else npm(ch0)\n  rgb1_to_xyz = identity(3) if is_xyz(ch1) else npm(ch1)\n  xyz_to_cat = cat(wp(ch0), wp(ch1), method=method)\n  rgb0_to_cat = matmul(xyz_to_cat, rgb0_to_xyz)\n  rgb0_to_rgb1 = matmul(inv(rgb1_to_xyz), rgb0_to_cat)\n  return rgb0_to_rgb1\n\n\n\nnode = nuke.thisNode()\n\ndef get_ch(k):\n  # get chromaticities from knob name k\n  ch_str = node\[k].getValue()\n  if ' ' in ch_str:\n    chs = ch_str.split(' ')\n    if not len(chs) == 8:\n      print('Error: need 8 space-separated float xy coordinates for RGBW')\n      return None\n    else:\n      ch = list()\n      for c in chs:\n        try:\n          ch.append(float(c))\n        except ValueError:\n          print('Error: could not convert \{0\} to float'.format(c))\n          return None\n      return ch\n  else:\n    return None\n\ndef print_mtx(mtx):\n  label = node\['label'].getValue()\n  \n  # round to 12 digits of precision\n  mtx_str = \[format(round(v, 12), '.12g') for v in flatten(mtx)]\n  \n  # print some useful representations of the matrix\n  # an ocio matrixtransform\n  mtx_str_pad = mtx_str\[0:3]+\['0']+mtx_str\[3:6]+\['0']+mtx_str\[6:9]+\['0']*4+\['1']\n  mtx_string = ', '.join(map(str, mtx_str_pad))\n  ocio_matrixtransform_string = '!<MatrixTransform> \{\{matrix: \[\{0\}]\}\}'.format(mtx_string)\n  print('\{0\} - OCIO MatrixTransform\\n\{1\}\\n'.format(label, ocio_matrixtransform_string))\n  \n  # an spimtx file\n  spimtx_string = '\{0\} 0\\n\{1\} 0\\n\{2\} 0'.format(\n    ' '.join(mtx_str\[0:3]),\n    ' '.join(mtx_str\[3:6]),\n    ' '.join(mtx_str\[6:9]),\n  )\n  print('\{0\}.spimtx\\n\{1\}\\n'.format(label, spimtx_string))\n\ndef reset():\n  # reset matrix\n  node\['matrix'].setValue(flatten(identity(3)))\n  \ndef calc():\n  # gather node info\n  src_ch = get_ch('src')\n  if not src_ch:\n    reset()\n    return\n  dst_ch = get_ch('dst')\n  cat_method = node\['cat'].value()\n  mtx = calc_mtx(src_ch, dst_ch, method=cat_method)\n  if node\['invert'].getValue():\n    mtx = inv(mtx)\n  node\['matrix'].setValue(flatten(mtx))\n  label = '\{1\} to \{0\}' if node\['invert'].getValue() else '\{0\} to \{1\}'\n  label = label.format(node\['src_name'].getValue(), node\['dst_name'].getValue())\n  node\['label'].setValue(label)\n  if node\['print_mtx'].getValue():\n    print_mtx(mtx)\n    \ncalc()"}
  addUserKnob {6 print_mtx l print t "print a few useful representations of the matrix ni the script editor, for OCIO MatrixTransforms, spimtx files, etc" -STARTLINE}
  addUserKnob {41 matrix T ColorMatrix.matrix}
  addUserKnob {22 create_colormatrix l "Create ColorMatrix" t "create ColorMatrix node using calculated 3x3 matrix" -STARTLINE T "from __future__ import with_statement\nnode = nuke.thisNode()\nwith nuke.root():\n    nukescripts.clear_selection_recursive()\n    m = nuke.createNode('ColorMatrix')\n    m.setXYpos(node.xpos()-120, node.ypos())\n    m\['matrix'].setValue(node\['matrix'].getValue())\n    m\['label'].setValue(node\['label'].getValue())"}
 }
  Input {
   inputs 0
   name Input
   xpos -40
   ypos 206
  }
  ColorMatrix {
   matrix {
       {1.898614899 -0.7921761834 -0.1064387159}
       {-0.1689487865 1.488975754 -0.3200269676}
       {-0.1215391606 -0.3156758531 1.437215014}
     }
   name ColorMatrix
   xpos -40
   ypos 255
  }
  Output {
   name Output
   xpos -40
   ypos 302
  }
 end_group
 Group {
  name GamutCompressCLin
  help "<b>Chromaticity Linear Gamut Compression</b>\n\nCompress gamut in a straight line from source chromaticity towards achromatic, according to the quadratic compression function which compresses out of gamut chroma value x0 to the gamut boundary, distributed over a range from t0 to 1."
  xpos 0
  ypos 221
  addUserKnob {20 Params}
  addUserKnob {41 t0 t "threshold chroma value to begin compression. 0 is achromatic, 1 is gamut boundary. " T Expression.t0}
  addUserKnob {41 x0 t "out of gamut chroma value to compress to the gamut boundary." T Expression.x0}
  addUserKnob {41 invert T Expression.invert}
 }
  Input {
   inputs 0
   name Input
   xpos -480
   ypos -442
  }
  Expression {
   temp_name0 m
   temp_expr0 max(r,g,b)
   temp_name1 c
   temp_expr1 m==0?0:(m-min(r,g,b))/m
   temp_name2 f
   temp_expr2 c==0?0:(c<t0?c:invert?pow((oy-c)/s,2)+ox:s*sqrt(c-ox)+oy)/c
   expr0 m*(1-f)+r*f
   expr1 m*(1-f)+g*f
   expr2 m*(1-f)+b*f
   maskChannelMask rgba.red
   name Expression
   xpos -480
   ypos -394
   addUserKnob {20 Params_tab l Params}
   addUserKnob {7 t0 l threshold}
   t0 0.8
   addUserKnob {7 x0 l distance R 1 2}
   x0 1.4
   addUserKnob {7 y0 R 0 2}
   y0 1
   addUserKnob {7 s}
   s {{(y0-t0)/sqrt(x0-y0)}}
   addUserKnob {7 ox R -2 2}
   ox {{t0-s*s/4}}
   addUserKnob {7 oy R -2 2}
   oy {{t0-s*sqrt(s*s/4)}}
   addUserKnob {6 invert +STARTLINE}
  }
  Output {
   name Output
   xpos -480
   ypos -346
  }
 end_group
 Colorspace {
  colorspace_out rec709
  name Colorspace1
  xpos 0
  ypos 269
 }
 Output {
  name Output1
  xpos 0
  ypos 320
 }
end_group

3 Likes

YES PLEASE! Pure Nuke nodes would be super!

Thanks, I think I got this to work too. What I did is what you say above, but the key in my case was adding another ColorSpace Transform with the input set to AP0 as I had an EXR sequence rather than camera raw.

@jpzambrano9 nice! Would you mind talking us through what’s going on in the ```
“NakaRush” node? I think I’m following on the rest.

Is just a regular per channel sigmoid, Resolve’s CST has the option to change something they call “adaptation”, the default of “9” maps 0.09 scene linear to 0.09 display linear, and 100 scene linear to be 1. This is the same process Resolve uses for their “Davinci Tone mapping”, and finally ,in Resolve when you check the “forward ootf” and gamma 2.4 in reality is just the Rec709 invEOTF

2 Likes