MaterialXOCIO 0.1.39.5
Utilities for using OCIO to generate MaterialX definitions and graphs
Loading...
Searching...
No Matches
core.py
1#!/usr/bin/env python
2'''
3Utilities to generate MaterialX color transform definitions using OCIO.
4
5The minimum requirement is OCIO version 2.2 which is packaged with
6"ACES Cg Config" and "ACES Studio Config" configurations.
7'''
8
9import PyOpenColorIO as OCIO
10import MaterialX as mx
11import re
12
14 '''
15 A class to generate MaterialX color transform definitions using OCIO.
16 '''
17
19 '''
20 Get the OCIO built in configurations.
21 Returnes a dictionary of color spaces and the default "ACES Cg Config".
22 '''
23 # Get the OCIO built in configs
24 registry = OCIO.BuiltinConfigRegistry().getBuiltinConfigs()
25
26 # Create a dictionary of configs
27 configs = {}
28 for item in registry:
29 # The short_name is the URI-style name.
30 # The ui_name is the name to use in a user interface.
31 short_name, ui_name, isRecommended, isDefault = item
32
33 # Don't present built-in configs to users if they are no longer recommended.
34 if isRecommended:
35 # Create a config using the Cg config
36 config = OCIO.Config.CreateFromBuiltinConfig(short_name)
37 colorSpaces = None
38 if config:
39 colorSpaces = config.getColorSpaces()
40
41 if colorSpaces:
42 configs[short_name] = [config, colorSpaces]
43
44 acesCgConfigPath = 'ocio://cg-config-v1.0.0_aces-v1.3_ocio-v2.1'
45 builtinCfgC = OCIO.Config.CreateFromFile(acesCgConfigPath)
46 print('Built-in config:', builtinCfgC.getName())
47 csnames = builtinCfgC.getColorSpaceNames()
48 print('- Number of color spaces: %d' % len(csnames))
49
50 return configs, builtinCfgC
51
52 def printConfigs(self, configs):
53 '''
54 Print the OCIO built in configurations as a markdown table.
55 @param configs: The OCIO configurations.
56 @return: A markdown string.
57 '''
58 title = '| Configuration | Color Space | Aliases |\n'
59 title = title + '| --- | --- | --- |\n'
60
61 rows = ''
62 for c in configs:
63 config = configs[c][0]
64 colorSpaces = configs[c][1]
65 for colorSpace in colorSpaces:
66 aliases = colorSpace.getAliases()
67 rows = rows + '| ' + c + ' | ' + colorSpace.getName() + ' | ' + ', '.join(aliases) + ' |\n'
68
69 return title + rows
70
71 def createTransformName(self, sourceSpace, targetSpace, typeName, prefix = 'mx_'):
72 '''
73 Create a transform name from a source and target color space and a type name.
74 @param sourceSpace: The source color space.
75 @param targetSpace: The target color space.
76 @param typeName: The type name.
77 @param prefix: The prefix for the transform name. Default is 'mx_'.
78 '''
79 transformFunctionName = prefix + mx.createValidName(sourceSpace) + "_to_" + mx.createValidName(targetSpace) + "_" + typeName
80 return transformFunctionName
81
82 def setShaderDescriptionParameters(self, shaderDesc, sourceSpace, targetSpace, typeName):
83 '''
84 Set parameters on a shader description for a given source and target color space and type name.
85 @param shaderDesc: The shader description.
86 @param sourceSpace: The source color space.
87 @param targetSpace: The target color space.
88 @param typeName: The type name.
89 '''
90 transformFunctionName = self.createTransformName(sourceSpace, targetSpace, typeName)
91 shaderDesc.setFunctionName(transformFunctionName)
92 shaderDesc.setResourcePrefix(transformFunctionName)
93
94 def generateShaderCode(self, config, sourceColorSpace, destColorSpace, language):
95 '''
96 Generate shader for a transform from a source color space to a destination color space
97 for a given config and shader language.
98
99 @param config: The OCIO configuration.
100 @param sourceColorSpace: The source color space.
101 @param destColorSpace: The destination color space.
102 @param language: The OCIO GPU language.
103 @return: A tuple containing the shader code and the number of texture resources required.
104
105 Returns the shader code and the number of texture resources required.
106 '''
107 shaderCode = ''
108 textureCount = 0
109 if not config:
110 return shaderCode, textureCount
111
112 # Create a processor for a pair of colorspaces
113 processor = None
114 try:
115 processor = config.getProcessor(sourceColorSpace, destColorSpace)
116 except:
117 print('Failed to generated code for transform: %s -> %s' % (sourceColorSpace, destColorSpace))
118 return shaderCode, textureCount
119
120 if processor:
121 gpuProcessor = processor.getDefaultGPUProcessor()
122 if gpuProcessor:
123 shaderDesc = OCIO.GpuShaderDesc.CreateShaderDesc()
124 if shaderDesc:
125 try:
126 shaderDesc.setLanguage(language)
127 if shaderDesc.getLanguage() == language:
128 self.setShaderDescriptionParameters(shaderDesc, sourceColorSpace, destColorSpace, "color4")
129 gpuProcessor.extractGpuShaderInfo(shaderDesc)
130 shaderCode = shaderDesc.getShaderText()
131
132 for t in shaderDesc.getTextures():
133 textureCount += 1
134
135 if shaderCode:
136 shaderCode = shaderCode.replace(
137 "// Declaration of the OCIO shader function\n",
138 "// " + sourceColorSpace + " to " + destColorSpace + " function. Texture count: %d\n" % textureCount)
139
140 except OCIO.Exception as err:
141 print(err)
142
143 return shaderCode, textureCount
144
145 def generateTransformGraph(self, config, sourceColorSpace, destColorSpace):
146 '''
147 Generate the group of transforms required to go from a source color space to a destination color space.
148 The group of transforms is output from an optimized OCIO processor.
149 @param config: The OCIO configuration.
150 @param sourceColorSpace: The source color space.
151 @param destColorSpace: The destination color space.
152 @return: The group of transforms.
153 '''
154 if not config:
155 return None
156
157 # Create a processor for a pair of colorspaces (namely to go to linear)
158 processor = None
159 groupTransform = None
160 try:
161 processor = config.getProcessor(sourceColorSpace, destColorSpace)
162 except:
163 #print('Failed to get processor for: %s -> %s' % (sourceColorSpace, destColorSpace))
164 return groupTransform
165
166 if processor:
167 processor = processor.getOptimizedProcessor(OCIO.OPTIMIZATION_ALL)
168 groupTransform = processor.createGroupTransform()
169
170 return groupTransform
171
172 def hasTextureResources(self, configs, targetColorSpace, language):
173 '''
174 Scan through all the color spaces on the configs to check for texture resource usage.
175 Returns a set of color spaces that require texture resources.
176
177 @param configs: The OCIO configurations.
178 @param targetColorSpace: The target color space.
179 @param language: The OCIO GPU language.
180 @return: A set of color spaces that require texture resources.
181 '''
182 testedSources = set()
183 textureSources = set()
184 for c in configs:
185 config = OCIO.Config.CreateFromBuiltinConfig(c)
186 colorSpaces = config.getColorSpaces()
187 for colorSpace in colorSpaces:
188 colorSpaceName = colorSpace.getName()
189 # Skip if the colorspace is already tested
190 if colorSpaceName in testedSources:
191 continue
192 testedSources.add(colorSpaceName)
193
194 # Test for texture resource usage
195 code, textureCount = self.generateShaderCode(config, colorSpace.getName(), targetColorSpace, language)
196 if textureCount:
197 print('- Transform "%s" to "%s" requires %d texture resources' % (colorSpace.getName(), targetColorSpace, textureCount))
198 textureSources.add(colorSpaceName)
199
200 return textureSources
201
202 def MSL(self, config, sourceColorSpace, targetColorSpace):
203 '''
204 Generate MSL shader code for a transform from a source color space to a destination color space
205 for a given config.
206 @param config: The OCIO configuration.
207 @param sourceColorSpace: The source color space.
208 @param targetColorSpace: The destination color space.
209 @return: The shader code.
210 '''
211 language = OCIO.GpuLanguage.GPU_LANGUAGE_MSL_2_0
212 code, textureCount = self.generateShaderCode(config, sourceColorSpace, targetColorSpace, language)
213 if code:
214 code = code.replace("// Declaration of the OCIO shader function\n", "// " + sourceColorSpace + " to " + targetColorSpace + " function\n")
215 code = '```c++\n' + code + '\n```\n'
216
217 def OSL(self, config, sourceColorSpace, targetColorSpace):
218 '''
219 Generate OSL shader code for a transform from a source color space to a destination color space
220 for a given config.
221 @param config: The OCIO configuration.
222 @param sourceColorSpace: The source color space.
223 @param targetColorSpace: The destination color space.
224 @return: The shader code.
225 '''
226 if OCIO.GpuLanguage.LANGUAGE_OSL_1:
227 language = OCIO.GpuLanguage.LANGUAGE_OSL_1
228 code, textureCount = self.generateShaderCode(config, sourceColorSpace, targetColorSpace, language)
229 if code:
230 # Bit of ugly patching to make the main function name consistent.
231 transformName = self.createTransformName(sourceColorSpace, targetColorSpace, 'color4')
232 code = code.replace('OSL_' + transformName, '__temp_name__')
233 code = code.replace(transformName, transformName + '_impl')
234 code = code.replace('__temp_name__', transformName)
235 code = code.replace("// Declaration of the OCIO shader function\n", "// " + sourceColorSpace + " to " + targetColorSpace + " function\n")
236 code = '```c++\n' + code + '\n```\n'
237
238 def generateMaterialXDefinition(self, doc, sourceColorSpace, targetColorSpace, inputName, type):
239 '''
240 Create a new definition in a document for a given color space transform.
241 Returns the definition.
242 '''
243 # Create a definition
244 transformName = self.createTransformName(sourceColorSpace, targetColorSpace, type)
245 nodeName = transformName.replace('mx_', 'ND_')
246
247 comment = doc.addChildOfCategory('comment')
248 docString = ' Color space %s to %s transform. Generated via OCIO. ' % (sourceColorSpace, targetColorSpace)
249 comment.setDocString(docString)
250
251 definition = doc.addNodeDef(nodeName, 'color4')
252 category = sourceColorSpace + '_to_' + targetColorSpace
253 definition.setNodeString(category)
254 definition.setNodeGroup('colortransform')
255 definition.setDocString(docString)
256 definition.setVersionString('1.0')
257
258 defaultValueString = '0.0 0.0 0.0 1.0'
259 defaultValue = mx.createValueFromStrings(defaultValueString, 'color4')
260 input = definition.addInput(inputName, type)
261 input.setValue(defaultValue)
262 output = definition.getOutput('out')
263 output.setAttribute('default', 'in')
264
265 return definition
266
267 def writeShaderCode(self, outputPath, code, transformName, extension, target):
268 '''
269 Write the shader code to a file.
270 @param outputPath: The output file path.
271 @param code: The shader code.
272 @param transformName: The transform name.
273 @param extension: The file extension.
274 @param target: The target language.
275 '''
276 # Write source code file
277 filename = outputPath / mx.FilePath(transformName + '.' + extension)
278 print('Write target[%s] source file %s' % (target,filename.asString()))
279 f = open(filename.asString(), 'w')
280 f.write(code)
281 f.close()
282
283 def createMaterialXImplementation(self, sourceColorSpace, targetColorSpace, doc, definition, transformName, extension, target):
284 '''
285 Create a new implementation in a document for a given definition.
286 @param sourceColorSpace: The source color space.
287 @param targetColorSpace: The target color space.
288 @param doc: The MaterialX document.
289 @param definition: The MaterialX definition.
290 @param transformName: The transform name.
291 @param extension: The file extension.
292 @param target: The target language.
293 '''
294 implName = transformName + '_' + target
295 filename = transformName + '.' + extension
296 implName = implName.replace('mx_', 'IM_')
297
298 # Check if implementation already exists
299 impl = doc.getImplementation(implName)
300 if impl:
301 print('Implementation already exists: %s' % implName)
302 return impl
303
304 comment = doc.addChildOfCategory('comment')
305 comment.setDocString(' Color space %s to %s transform. Generated via OCIO for target: %s'
306 % (sourceColorSpace, targetColorSpace, target))
307 impl = doc.addImplementation(implName)
308 impl.setFile(filename)
309 impl.setFunction(transformName)
310 impl.setTarget(target)
311 impl.setNodeDef(definition)
312
313 return impl
314
315 def generateOCIO(self, config, definitionDoc, implDoc, sourceColorSpace = 'acescg', targetColorSpace = 'lin_rec709',
316 type='color4', IN_PIXEL_STRING = 'in'):
317 '''
318 Generate a MaterialX definition and implementation for a given color space transform.
319 Returns the definition, implementation, source code, extension and target.
320 @param config: The OCIO configuration.
321 @param definitionDoc: The MaterialX document to add the definition to.
322 @param implDoc: The MaterialX document to add the implementation to.
323 @param sourceColorSpace: The source color space.
324 @param targetColorSpace: The destination color space.
325 @param type: The type of the transform.
326 @param IN_PIXEL_STRING: The input pixel string.
327 @return: A tuple containing the definition, transform name, source code, extension
328 '''
329
330 # List of MaterialX target language, source code extensions, and OCIO GPU languages
331 generationList = [
332 ['genglsl', 'glsl', OCIO.GpuLanguage.GPU_LANGUAGE_GLSL_4_0]
333 #, ['genmsl', 'metal', OCIO.GpuLanguage.GPU_LANGUAGE_MSL_2_0]
334 ]
335
336 definition = None
337 transformName = self.createTransformName(sourceColorSpace, targetColorSpace, type)
338 for gen in generationList:
339 target = gen[0]
340 extension = gen[1]
341 language = gen[2]
342
343 code, textureCount = self.generateShaderCode(config, sourceColorSpace, targetColorSpace, language)
344
345 # Skip if there are texture resources
346 if textureCount:
347 print('- Skip generation for transform: "%s" to "%s" which requires %d texture resources' % (sourceColorSpace, targetColorSpace, textureCount))
348 continue
349
350 if code:
351 # Create the definition once
352 if not definition:
353 # Create color4 variant
354 definition = self.generateMaterialXDefinition(definitionDoc, sourceColorSpace, targetColorSpace,
355 IN_PIXEL_STRING, type)
356 # Create color3 variant (nodegraph)
357 self.createColor3Variant(definition, definitionDoc, IN_PIXEL_STRING)
358
359 # Create the implementation
360 self.createMaterialXImplementation(sourceColorSpace, targetColorSpace, implDoc, definition, transformName, extension, target)
361
362 return definition, transformName, code, extension, target
363
364 def generateOCIOGraph(self, config, sourceColorSpace = 'acescg', targetColorSpace = 'lin_rec709',
365 type='color3'):
366 '''
367 Generate a MaterialX nodegraph for a given color space transform.
368 @param config: The OCIO configuration.
369 @param sourceColorSpace: The source color space.
370 @param targetColorSpace: The destination color space.
371 @param type: The type of the transform.
372 Returns a MaterialX document containing a functional nodegraph and nodedef pair.
373 '''
374 groupTransform = self.generateTransformGraph(config, sourceColorSpace, targetColorSpace)
375
376 # To add. Proper testing of unsupported transforms...
377 invalidTransforms = [ OCIO.TransformType.TRANSFORM_TYPE_LUT3D, OCIO.TransformType.TRANSFORM_TYPE_LUT1D,
378 OCIO.TransformType.TRANSFORM_TYPE_GRADING_PRIMARY ]
379
380 # Create a document, a nodedef and a functional graph.
381 graphDoc = mx.createDocument()
382 outputType = 'color3'
383 xformName = sourceColorSpace + '_to_' + targetColorSpace + '_' + outputType
384
385 nd = graphDoc.addNodeDef('ND_' + xformName )
386 nd.setAttribute('node', xformName)
387 ndInput = nd.addInput('in', 'color3')
388 ndInput.setValue([0.0, 0.0, 0.0], 'color3')
389 docString = f'Generated color space {sourceColorSpace} to {targetColorSpace} transform.'
390 result = f'{groupTransform}'
391 # Replace '<' and '>' with '()' and ')'
392 result = result.replace('<', '(')
393 result = result.replace('>', ')')
394 result = re.sub(r'[\r\n]+', '', result)
395
396 print(result)
397 docString = docString + '. OCIO Transforms: ' + result
398 nd.setDocString(docString)
399
400 ng = graphDoc.addNodeGraph('NG_' + xformName)
401 ng.setAttribute('nodedef', nd.getName())
402 convertNode = ng.addNode('convert', 'asVec', 'vector3')
403 converInput = convertNode.addInput('in', 'color3')
404 converInput.setInterfaceName('in')
405
406 #print(f'Transform from: {sourceColorSpace} to {targetColorSpace}')
407 if not groupTransform:
408 #print(f'No group transform found for the color space transform: {sourceColorSpace} to {targetColorSpace}')
409 return None
410 #print(f'Number of transforms: {groupTransform.__len__()}')
411 previousNode = None
412
413 # Iterate and create appropriate nodes and connections
414 for i in range(groupTransform.__len__()):
415 transform = groupTransform.__getitem__(i)
416 # Get type of transform
417 transformType = transform.getTransformType()
418 if transformType in invalidTransforms:
419 print(f'- Transform[{i}]: {transformType} contains an unsupported transform type')
420 continue
421
422 #print(f'- Transform[{i}]: {transformType}')
423 if transformType == OCIO.TransformType.TRANSFORM_TYPE_MATRIX:
424 matrixNode = ng.addNode('transform', ng.createValidChildName(f'matrixTransform'), 'vector3')
425
426 # Route output from previous node as input of current node
427 inInput = matrixNode.addInput('in', 'vector3')
428 if previousNode:
429 inInput.setAttribute('nodename', previousNode)
430 else:
431 #if i==0:
432 inInput.setAttribute('nodename', 'asVec')
433 #else:
434 # inInput.setValue([0.0, 0.0, 0.0], 'vector3')
435
436 # Set matrix value
437 matInput = matrixNode.addInput('mat', 'matrix33')
438 matrixValue = transform.getMatrix()
439 # Extract 3x3 matrix from 4x4 matrix
440 matrixValue = matrixValue[0:3] + matrixValue[4:7] + matrixValue[8:11]
441 matrixValue = ', '.join([str(x) for x in matrixValue])
442 #print(' - Matrix:', matrixValue)
443 matInput.setAttribute('value', matrixValue)
444
445 # Add offset value - TODO
446 offsetValue = transform.getOffset()
447 offsetValue = ', '.join([str(x) for x in offsetValue])
448 #print(' - Offset:', offsetValue)
449 # Add a add vector3 to graph
450
451 previousNode = matrixNode.getName()
452
453 # TODO: Handle other transform types
454 elif transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT or transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT_WITH_LINEAR:
455
456 hasOffset = (transformType == OCIO.TransformType.TRANSFORM_TYPE_EXPONENT_WITH_LINEAR)
457
458 #print(f'- Transform[{i}]: {transformType} support has not been implemented yet')
459 exponentNode = ng.addNode('power', ng.createValidChildName(f'exponent'), 'vector3')
460 exponentInput = exponentNode.addInput('in1', 'vector3')
461 if previousNode:
462 exponentInput.setAttribute('nodename', previousNode)
463 else:
464 if i==0:
465 exponentInput.setAttribute('nodename', 'asVec')
466 else:
467 exponentInput.setValue([0.0, 0.0, 0.0], 'vector3')
468
469 exponentInput2 = exponentNode.addInput('in2', 'vector3')
470 exponentInput2Value = None
471 if not hasOffset:
472 exponentInput2Value = transform.getValue()
473 else:
474 exponentInput2Value = transform.getGamma()
475 # Only want the first 3 values in the array
476 exponentInput2Value = exponentInput2Value[0:3]
477 exponentInput2.setValue(exponentInput2Value, 'float')
478
479 previousNode = exponentNode.getName()
480
481 if hasOffset:
482 # Add offset
483 offsetNode = ng.addNode('add', ng.createValidChildName(f'offset'), 'vector3')
484 offsetInput2 = offsetNode.addInput('in2', 'vector3')
485 offsetInput2.setNodeName(exponentNode.getName())
486 offsetInput = offsetNode.addInput('in1', 'vector3')
487 offsetValue = transform.getOffset()
488 # Only want the first 3 values in the array
489 offsetValue = offsetValue[0:3]
490 offsetInput.setValue(offsetValue, 'vector3')
491
492 previousNode = offsetNode.getName()
493
494 else:
495 print(f'- Transform[{i}]: {transformType} support has not been implemented yet')
496 continue
497
498
499 # Create an output for the last node if any
500 convertNode2 = ng.addNode('convert', 'asColor', 'color3')
501 converInput2 = convertNode2.addInput('in', 'vector3')
502 if previousNode:
503 converInput2.setAttribute('nodename', previousNode)
504 else:
505 # Pass-through
506 #print('No transforms applied. Transform is a pass-through.')
507 converInput2.setAttribute('nodename', 'asVec')
508
509 out = ng.addOutput(ng.createValidChildName('out'), 'color3')
510 out.setAttribute('nodename', 'asColor')
511
512 return graphDoc
513
514 def createColor3Variant(self, definition, definitionDoc, IN_PIXEL_STRING = 'in'):
515 '''
516 Create a color3 variant of a color4 definition.
517 @param definition: The color4 definition.
518 @param definitionDoc: The MaterialX document.
519 @param IN_PIXEL_STRING: The input pixel string.
520 '''
521 color4Name = definition.getName()
522 color3Name = color4Name.replace('color4', 'color3')
523 color3Def = definitionDoc.addNodeDef(color3Name)
524 color3Def.copyContentFrom(definition)
525 c3input = color3Def.getInput(IN_PIXEL_STRING)
526 c3input.setType('color3')
527 c3input.setValue([0.0, 0.0, 0.0], 'color3')
528
529 ngName = color3Def.getName().replace('ND_', 'NG_')
530 ng = definitionDoc.addNodeGraph(ngName)
531 c4instance = ng.addNodeInstance(definition)
532 c4instance.addInputsFromNodeDef()
533 c4instanceIn = c4instance.getInput(IN_PIXEL_STRING)
534 c3to4 = ng.addNode('convert', 'c3to4', 'color4')
535 c3to4Input = c3to4.addInput('in', 'color3')
536 c4to3 = ng.addNode('convert', 'c4to3', 'color3')
537 c4to3Input = c4to3.addInput('in', 'color4')
538 ngout = ng.addOutput('out', 'color3')
539 #ngin = ng.addInput('in', 'color3')
540 ng.setNodeDef(color3Def)
541
542 c4instanceIn.setNodeName(c3to4.getName())
543 c4to3Input.setNodeName(c4instance.getName())
544 ngout.setNodeName(c4to3.getName())
545 c3to4Input.setInterfaceName(IN_PIXEL_STRING)
A class to generate MaterialX color transform definitions using OCIO.
Definition core.py:13
createMaterialXImplementation(self, sourceColorSpace, targetColorSpace, doc, definition, transformName, extension, target)
Create a new implementation in a document for a given definition.
Definition core.py:283
generateOCIO(self, config, definitionDoc, implDoc, sourceColorSpace='acescg', targetColorSpace='lin_rec709', type='color4', IN_PIXEL_STRING='in')
Generate a MaterialX definition and implementation for a given color space transform.
Definition core.py:316
generateOCIOGraph(self, config, sourceColorSpace='acescg', targetColorSpace='lin_rec709', type='color3')
Generate a MaterialX nodegraph for a given color space transform.
Definition core.py:365
printConfigs(self, configs)
Print the OCIO built in configurations as a markdown table.
Definition core.py:52
generateTransformGraph(self, config, sourceColorSpace, destColorSpace)
Generate the group of transforms required to go from a source color space to a destination color spac...
Definition core.py:145
generateShaderCode(self, config, sourceColorSpace, destColorSpace, language)
Generate shader for a transform from a source color space to a destination color space for a given co...
Definition core.py:94
OSL(self, config, sourceColorSpace, targetColorSpace)
Generate OSL shader code for a transform from a source color space to a destination color space for a...
Definition core.py:217
getBuiltinConfigs(self)
Get the OCIO built in configurations.
Definition core.py:18
setShaderDescriptionParameters(self, shaderDesc, sourceSpace, targetSpace, typeName)
Set parameters on a shader description for a given source and target color space and type name.
Definition core.py:82
MSL(self, config, sourceColorSpace, targetColorSpace)
Generate MSL shader code for a transform from a source color space to a destination color space for a...
Definition core.py:202
createColor3Variant(self, definition, definitionDoc, IN_PIXEL_STRING='in')
Create a color3 variant of a color4 definition.
Definition core.py:514
generateMaterialXDefinition(self, doc, sourceColorSpace, targetColorSpace, inputName, type)
Create a new definition in a document for a given color space transform.
Definition core.py:238
createTransformName(self, sourceSpace, targetSpace, typeName, prefix='mx_')
Create a transform name from a source and target color space and a type name.
Definition core.py:71
writeShaderCode(self, outputPath, code, transformName, extension, target)
Write the shader code to a file.
Definition core.py:267
hasTextureResources(self, configs, targetColorSpace, language)
Scan through all the color spaces on the configs to check for texture resource usage.
Definition core.py:172