91 Generate shader for a transform from a source color space to a destination color space
92 for a given config and shader language.
94 Returns the shader code and the number of texture resources required.
99 return shaderCode, textureCount
104 processor = config.getProcessor(sourceColorSpace, destColorSpace)
106 print(
'Failed to generated code for transform: %s -> %s' % (sourceColorSpace, destColorSpace))
107 return shaderCode, textureCount
110 gpuProcessor = processor.getDefaultGPUProcessor()
112 shaderDesc = OCIO.GpuShaderDesc.CreateShaderDesc()
115 shaderDesc.setLanguage(language)
116 if shaderDesc.getLanguage() == language:
118 gpuProcessor.extractGpuShaderInfo(shaderDesc)
119 shaderCode = shaderDesc.getShaderText()
121 for t
in shaderDesc.getTextures():
125 shaderCode = shaderCode.replace(
126 "// Declaration of the OCIO shader function\n",
127 "// " + sourceColorSpace +
" to " + destColorSpace +
" function. Texture count: %d\n" % textureCount)
129 except OCIO.Exception
as err:
132 return shaderCode, textureCount
163 Scan through all the color spaces on the configs to check for texture resource usage.
164 Returns a set of color spaces that require texture resources.
166 testedSources = set()
167 textureSources = set()
169 config = OCIO.Config.CreateFromBuiltinConfig(c)
170 colorSpaces = config.getColorSpaces()
171 for colorSpace
in colorSpaces:
172 colorSpaceName = colorSpace.getName()
174 if colorSpaceName
in testedSources:
176 testedSources.add(colorSpaceName)
179 code, textureCount = self.
generateShaderCode(config, colorSpace.getName(), targetColorSpace, language)
181 print(
'- Transform "%s" to "%s" requires %d texture resources' % (colorSpace.getName(), targetColorSpace, textureCount))
182 textureSources.add(colorSpaceName)
184 return textureSources
208 Create a new definition in a document for a given color space transform.
209 Returns the definition.
213 nodeName = transformName.replace(
'mx_',
'ND_')
215 comment = doc.addChildOfCategory(
'comment')
216 docString =
' Color space %s to %s transform. Generated via OCIO. ' % (sourceColorSpace, targetColorSpace)
217 comment.setDocString(docString)
219 definition = doc.addNodeDef(nodeName,
'color4')
220 category = sourceColorSpace +
'_to_' + targetColorSpace
221 definition.setNodeString(category)
222 definition.setNodeGroup(
'colortransform')
223 definition.setDocString(docString)
224 definition.setVersionString(
'1.0')
226 defaultValueString =
'0.0 0.0 0.0 1.0'
227 defaultValue = mx.createValueFromStrings(defaultValueString,
'color4')
228 input = definition.addInput(inputName, type)
229 input.setValue(defaultValue)
230 output = definition.getOutput(
'out')
231 output.setAttribute(
'default',
'in')
248 Create a new implementation in a document for a given definition.
250 implName = transformName +
'_' + target
251 filename = transformName +
'.' + extension
252 implName = implName.replace(
'mx_',
'IM_')
255 impl = doc.getImplementation(implName)
257 print(
'Implementation already exists: %s' % implName)
260 comment = doc.addChildOfCategory(
'comment')
261 comment.setDocString(
' Color space %s to %s transform. Generated via OCIO for target: %s'
262 % (sourceColorSpace, targetColorSpace, target))
263 impl = doc.addImplementation(implName)
264 impl.setFile(filename)
265 impl.setFunction(transformName)
266 impl.setTarget(target)
267 impl.setNodeDef(definition)
271 def generateOCIO(self, config, definitionDoc, implDoc, sourceColorSpace = 'acescg', targetColorSpace = 'lin_rec709',
272 type='color4', IN_PIXEL_STRING = 'in'):
274 Generate a MaterialX definition and implementation for a given color space transform.
275 Returns the definition, implementation, source code, extension and target.
280 [
'genglsl',
'glsl', OCIO.GpuLanguage.GPU_LANGUAGE_GLSL_4_0]
286 for gen
in generationList:
291 code, textureCount = self.
generateShaderCode(config, sourceColorSpace, targetColorSpace, language)
295 print(
'- Skip generation for transform: "%s" to "%s" which requires %d texture resources' % (sourceColorSpace, targetColorSpace, textureCount))
303 IN_PIXEL_STRING, type)
310 return definition, transformName, code, extension, target
312 def generateOCIOGraph(self, config, sourceColorSpace = 'acescg', targetColorSpace = 'lin_rec709',
315 Generate a MaterialX nodegraph for a given color space transform.
316 @param config: The OCIO configuration.
317 @param sourceColorSpace: The source color space.
318 @param targetColorSpace: The destination color space.
319 @param type: The type of the transform.
320 Returns a MaterialX document containing a functional nodegraph and nodedef pair.
325 invalidTransforms = [ OCIO.TransformType.TRANSFORM_TYPE_LUT3D, OCIO.TransformType.TRANSFORM_TYPE_LUT1D,
326 OCIO.TransformType.TRANSFORM_TYPE_GRADING_PRIMARY ]
329 graphDoc = mx.createDocument()
330 outputType =
'color3'
331 xformName = sourceColorSpace +
'_to_' + targetColorSpace +
'_' + outputType
333 nd = graphDoc.addNodeDef(
'ND_' + xformName )
334 nd.setAttribute(
'node', xformName)
335 ndInput = nd.addInput(
'in',
'color3')
336 ndInput.setValue([0.0, 0.0, 0.0],
'color3')
337 docString = f
'Generated color space {sourceColorSpace} to {targetColorSpace} transform.'
338 result = f
'{groupTransform}'
340 result = result.replace(
'<',
'(')
341 result = result.replace(
'>',
')')
342 result = re.sub(
r'[\r\n]+',
'', result)
345 docString = docString +
'. OCIO Transforms: ' + result
346 nd.setDocString(docString)
348 ng = graphDoc.addNodeGraph(
'NG_' + xformName)
349 ng.setAttribute(
'nodedef', nd.getName())
350 convertNode = ng.addNode(
'convert',
'asVec',
'vector3')
351 converInput = convertNode.addInput(
'in',
'color3')
352 converInput.setInterfaceName(
'in')
355 if not groupTransform:
362 for i
in range(groupTransform.__len__()):
363 transform = groupTransform.__getitem__(i)
365 transformType = transform.getTransformType()
366 if transformType
in invalidTransforms:
367 print(f
'- Transform[{i}]: {transformType} contains an unsupported transform type')
371 if transformType == OCIO.TransformType.TRANSFORM_TYPE_MATRIX:
372 matrixNode = ng.addNode(
'transform', ng.createValidChildName(f
'matrixTransform'),
'vector3')
375 inInput = matrixNode.addInput(
'in',
'vector3')
377 inInput.setAttribute(
'nodename', previousNode)
380 inInput.setAttribute(
'nodename',
'asVec')
385 matInput = matrixNode.addInput(
'mat',
'matrix33')
386 matrixValue = transform.getMatrix()
388 matrixValue = matrixValue[0:3] + matrixValue[4:7] + matrixValue[8:11]
389 matrixValue =
', '.join([str(x)
for x
in matrixValue])
391 matInput.setAttribute(
'value', matrixValue)
394 offsetValue = transform.getOffset()
395 offsetValue =
', '.join([str(x)
for x
in offsetValue])
399 previousNode = matrixNode.getName()
402 elif transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT
or transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT_WITH_LINEAR:
404 hasOffset = (transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT_WITH_LINEAR)
407 exponentNode = ng.addNode(
'power', ng.createValidChildName(f
'exponent'),
'vector3')
408 exponentInput = exponentNode.addInput(
'in1',
'vector3')
410 exponentInput.setAttribute(
'nodename', previousNode)
413 exponentInput.setAttribute(
'nodename',
'asVec')
415 exponentInput.setValue([0.0, 0.0, 0.0],
'vector3')
417 exponentInput2 = exponentNode.addInput(
'in2',
'vector3')
418 exponentInput2Value =
None
420 exponentInput2Value = transform.getValue()
422 exponentInput2Value = transform.getGamma()
424 exponentInput2Value = exponentInput2Value[0:3]
425 exponentInput2.setValue(exponentInput2Value,
'float')
427 previousNode = exponentNode.getName()
431 offsetNode = ng.addNode(
'add', ng.createValidChildName(f
'offset'),
'vector3')
432 offsetInput2 = offsetNode.addInput(
'in2',
'vector3')
433 offsetInput2.setNodeName(exponentNode.getName())
434 offsetInput = offsetNode.addInput(
'in1',
'vector3')
435 offsetValue = transform.getOffset()
437 offsetValue = offsetValue[0:3]
438 offsetInput.setValue(offsetValue,
'vector3')
440 previousNode = offsetNode.getName()
443 print(f
'- Transform[{i}]: {transformType} support has not been implemented yet')
448 convertNode2 = ng.addNode(
'convert',
'asColor',
'color3')
449 converInput2 = convertNode2.addInput(
'in',
'vector3')
451 converInput2.setAttribute(
'nodename', previousNode)
455 converInput2.setAttribute(
'nodename',
'asVec')
457 out = ng.addOutput(ng.createValidChildName(
'out'),
'color3')
458 out.setAttribute(
'nodename',
'asColor')
464 Create a color3 variant of a color4 definition.
466 color4Name = definition.getName()
467 color3Name = color4Name.replace(
'color4',
'color3')
468 color3Def = definitionDoc.addNodeDef(color3Name)
469 color3Def.copyContentFrom(definition)
470 c3input = color3Def.getInput(IN_PIXEL_STRING)
471 c3input.setType(
'color3')
472 c3input.setValue([0.0, 0.0, 0.0],
'color3')
474 ngName = color3Def.getName().replace(
'ND_',
'NG_')
475 ng = definitionDoc.addNodeGraph(ngName)
476 c4instance = ng.addNodeInstance(definition)
477 c4instance.addInputsFromNodeDef()
478 c4instanceIn = c4instance.getInput(IN_PIXEL_STRING)
479 c3to4 = ng.addNode(
'convert',
'c3to4',
'color4')
480 c3to4Input = c3to4.addInput(
'in',
'color3')
481 c4to3 = ng.addNode(
'convert',
'c4to3',
'color3')
482 c4to3Input = c4to3.addInput(
'in',
'color4')
483 ngout = ng.addOutput(
'out',
'color3')
485 ng.setNodeDef(color3Def)
487 c4instanceIn.setNodeName(c3to4.getName())
488 c4to3Input.setNodeName(c4instance.getName())
489 ngout.setNodeName(c4to3.getName())
490 c3to4Input.setInterfaceName(IN_PIXEL_STRING)