Nuke binary plugins 15.1.4
 
Loading...
Searching...
No Matches
DD::Image::MaterialOpI Class Reference

#include <MaterialOpI.h>

Inheritance diagram for DD::Image::MaterialOpI:
DD::Image::LightMaterialOpI DD::Image::ShaderOp DD::Image::LightOp DD::Image::CoShaderMaterialInterface DD::Image::SurfaceShaderOp DD::Image::ComplexLightOp

Classes

class  MaterialContext
 

Public Types

enum  {
  INPUT_TYPE_NONE , INPUT_TYPE_OP , INPUT_TYPE_MATERIALOP , INPUT_TYPE_IOP ,
  INPUT_TYPE_AXISOP , INPUT_TYPE_CAMERAOP , INPUT_TYPE_LIGHTOP
}
 
enum  {
  OUTPUT_TYPE_NONE , OUTPUT_TYPE_COSHADER , OUTPUT_TYPE_SURFACESHADER , OUTPUT_TYPE_LIGHTSHADER ,
  OUTPUT_TYPE_VOLUMESHADER
}
 

Public Member Functions

virtual OpgetOp ()
 Return the Op this interface is attached to. Should return 'this'.
 
virtual void setOverrideOp (Op *)
 
virtual void clearOverrideOp ()
 Disable any assigned override Op.
 
virtual OpgetOverrideOp () const
 Return the override Op used for shader property value updating.
 
virtual usg::TokenArray getAppliedApiSchemas () const
 Returns a list of API's this output shader must implement.
 
virtual const char * getOutputSchema () const
 
virtual int32_t getOutputType () const
 
bool isCoShader () const
 Convenience to check output type.
 
bool isSurfaceShader () const
 
bool isLightShader () const
 
bool isVolumeShader () const
 
virtual std::string getShaderNodeName (const usg::Token &target_renderer=usg::Token())
 
virtual int32_t connectionTypeForNodeInput (int32_t node_input) const
 
virtual usg::ShaderDesc * createShaderGraph (int32_t output_type, const MaterialContext &rtx, usg::ShaderDescGroup &shader_group)
 
virtual usg::ShaderDesc * createShaderGraphFromOp (Op *input_op, const MaterialContext &rtx, usg::ShaderDescGroup &shader_group)
 
virtual void updateShaderGraphOverrides (int32_t output_type, const MaterialContext &rtx, usg::ShaderDescGroup &shader_group)
 
virtual void updateShaderGraphFromOp (Op *input_op, const MaterialContext &rtx, usg::ShaderDescGroup &shader_group)
 

Static Public Member Functions

static std::string getNodeInstanceSuffix (DD::Image::Op *op)
 
static std::string buildName (const std::string &node_name, const char *schema_name)
 Convenience function builds a standard shader name with '<node_name>_<schema_name>'.
 
static std::string buildName (const usg::Token &target_renderer, const std::string &node_name, const char *schema_name)
 Convenience function builds a standard shader name with '<target_renderer>_<node_name>_<schema_name>'.
 
static int32_t getShaderTypeFromOp (Op *op)
 
static std::string getShaderNodeNameFromOp (const usg::Token &target_renderer, Op *op)
 
static const char * inputShaderTypeName (int32_t op_type)
 
static usg::ShaderDesc * createOpInterfaceShaderDesc (int32_t op_type, Op *op)
 
static usg::ShaderDesc * createOpInterfaceShaderDesc (Op *op)
 
static std::string buildAssetPath (Op *input_op)
 
static bool parseAssetPath (const std::string &path, std::string &nodePath, OutputContext &outputContext)
 
static OpretrieveOpFromAssetPath (const std::string &path)
 

Protected Member Functions

virtual bool overrideShaderDescInput (const char *knob_name, const MaterialContext &rtx, usg::ShaderDesc &shader_desc, const char *target_property_name, usg::Value::Type target_property_type_hint=usg::Value::Type::InvalidType)
 
virtual bool overrideShaderDescInput (const Channel &chan, const MaterialContext &rtx, usg::ShaderDesc &shader_desc, const char *target_property_name)
 
virtual bool overrideShaderDescInput (const Channel *chan_array, uint32_t num_channels, const MaterialContext &rtx, usg::ShaderDesc &shader_desc, const char *target_property_name)
 
virtual bool overrideShaderDescInput (const ChannelSet &channels, const MaterialContext &rtx, usg::ShaderDesc &shader_desc, const char *target_property_name)
 

Detailed Description

Interface class for abstracting Ops which create shaders.

These Ops are typically containers for shader parameters which are translated into actual shader implementations, usually by loading a translator plugin.

Note that the word 'material' in the class name is used generically here. Attaching the interface to an Op simply provides a mechanism to create shaders, it does not imply that the Op creates an entire 'Material' in the USD sense of the word.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
INPUT_TYPE_NONE 

Don't allow input to connect to anything.

INPUT_TYPE_OP 

Generic Op connection (can connect to any Op types)

INPUT_TYPE_MATERIALOP 

Shader input.

INPUT_TYPE_IOP 

Iop input as texture.

INPUT_TYPE_AXISOP 

AxisOp input.

INPUT_TYPE_CAMERAOP 

CameraOp input.

INPUT_TYPE_LIGHTOP 

LightOp input.

◆ anonymous enum

anonymous enum
Enumerator
OUTPUT_TYPE_NONE 

Invalid output, don't use (used for error cases)

OUTPUT_TYPE_COSHADER 

Output shader is a 'co-shader', providing values for another shader's input.

OUTPUT_TYPE_SURFACESHADER 

Output shader should provide final surface/displacement outputs.

OUTPUT_TYPE_LIGHTSHADER 

Output shader should provide final light shading outputs.

OUTPUT_TYPE_VOLUMESHADER 

Output shader should provide final volume shading outputs.

Member Function Documentation

◆ getOp()

virtual Op * DD::Image::MaterialOpI::getOp ( )
inlinevirtual

Return the Op this interface is attached to. Should return 'this'.

Reimplemented in DD::Image::ShaderOp, and DD::Image::CoShaderMaterialInterface.

Referenced by DD::Image::LightMaterialOpI::defineLightPrim(), and DD::Image::LightMaterialOpI::getShaderNodeName().

◆ setOverrideOp()

virtual void DD::Image::MaterialOpI::setOverrideOp ( Op )
inlinevirtual

Assign an optional override Op used for shader property value updating which may have a different time or view than the base Op the MaterialOpI is bound to.

Subclasses can return this override Op in getOp() so Knob sampling is performed on the override rather than the base Op.

Referenced by DD::Image::GeomOpEngine::importShaderOp().

◆ getOutputSchema()

virtual const char * DD::Image::MaterialOpI::getOutputSchema ( ) const
inlinevirtual

Return a Schema name to use when building the output shader. Must implement.

Referenced by DD::Image::LightMaterialOpI::defineLightPrim().

◆ getOutputType()

virtual int32_t DD::Image::MaterialOpI::getOutputType ( ) const
inlinevirtual

Return the type of the output Schema, used to determine Op interconnection compatibility. Must implement.

Referenced by DD::Image::GeomOpEngine::importShaderOp().

◆ getShaderNodeName()

std::string DD::Image::MaterialOpI::getShaderNodeName ( const usg::Token &  target_renderer = usg::Token())
virtual

Get a unique name for the output shader node(s) this shader interface produces. If this material outputs multiple shader nodes then this name should be used as the base for them.

These names are ultimately used to name the output ShaderPrims added to the stage and to find the same ShaderPrims later on when updating property values. So, they need to be uniquely named underneath the MaterialPrim with the assumption they will all live in a single 'pool' of shaders - ie there's no additional prim hierarchy structure underneath the MaterialPrim.)

The default name returned is the Op's node_name() with the schema name appended on the end. Since Nuke Node names are quaranteed to be unique this is a reliable way to identify the shader without resorting to something like UUIDs or hashing the Node pointer. For example the Nuke Node named 'Project3D5' will return the shader node name 'Project3D5_Project3DTexture' as 'Project3DTexture' is the output schema name for the Project3DShaderOp plugin.

If 'target_renderer' is not empty it is prepended to the name with an underscore '_' separator. So 'glslfx' target renderer will produce 'glslfx_Project3D5_Project3DTexture'.

Nested shader graph groups are not supported and all shader node names are assumed to be within the same group namespace - ie all the node names must be unique.

Note that these are node names not paths, so the names should not include any pathing characters like '/' or '.', and underscores '_' are recommended as a separator for compound names.

Reimplemented in DD::Image::LightMaterialOpI.

References DD::Image::Op::nodeName().

◆ connectionTypeForNodeInput()

virtual int32_t DD::Image::MaterialOpI::connectionTypeForNodeInput ( int32_t  node_input) const
inlinevirtual

Return the preferred input type enum for the Node input number. This is really only a hint as a subclass is allowed to perform whatever connection logic it wants.

Currently the ShaderOp class respects this setting for the test_input() method, so if a subclass returns INPUT_TYPE_IOP then test_input() will return false for that input if the connection Op is not an Iop.

Base class returns INPUT_TYPE_OP, any connection type is ok.

◆ createShaderGraph()

virtual usg::ShaderDesc * DD::Image::MaterialOpI::createShaderGraph ( int32_t  output_type,
const MaterialContext rtx,
usg::ShaderDescGroup &  shader_group 
)
inlinevirtual

Allocate a series of ShaderDescs this Op and its input graph produces, and return the output connection point.

Each created ShaderDesc must be assigned a unique prim name inside the group that can be reliably retrieved in updateShaderGraphOverrides() when the shader overrides may get changed. To be reliably retrievable the shader names are usually tied to a Nuke Node name which is reliably unique. For example if there are multiple chained MergeShader nodes then the name of each shader in the group will typcially contain the name of the Nuke node for this reason. The getShaderNodeName() method will build a unique shader name for you based on the Op/Node this interface is attached to.

If you need to build an absolute prim path for the ShaderDesc use the ShaderDescGroup's 'material_prim_path' as the parent path.

Calling object takes ownership of all created allocations.

Reimplemented in DD::Image::CoShaderMaterialInterface.

Referenced by DD::Image::ShaderOp::createCoShaderInterfaceGraph(), createShaderGraphFromOp(), DD::Image::GeomOpEngine::importLightOp(), and DD::Image::GeomOpEngine::importShaderOp().

◆ createShaderGraphFromOp()

usg::ShaderDesc * DD::Image::MaterialOpI::createShaderGraphFromOp ( Op input_op,
const MaterialContext rtx,
usg::ShaderDescGroup &  shader_group 
)
virtual

Same as createShaderGraph() but automatically handles input Op as a MaterialOpI or a built-in interface shader.

By default if the input Op is not a MaterialOpI any created shader is added to the ShaderDescGroup with a default name but no output assignment is made.

If a ShaderDesc with the same name already exists the shader is not created or added. This commonly happens when a texture source is shared between several shaders.

References createShaderGraph(), DD::Image::Op::nodeName(), DD::Image::MaterialOpI::MaterialContext::target, DD::Image::MaterialOpI::MaterialContext::time, and DD::Image::Op::varyingOutputHash().

◆ updateShaderGraphOverrides()

virtual void DD::Image::MaterialOpI::updateShaderGraphOverrides ( int32_t  output_type,
const MaterialContext rtx,
usg::ShaderDescGroup &  shader_group 
)
inlinevirtual

Update the ShaderDescs this Op and its input graph produces.

To be updated properly the ShaderDescs in the ShaderDescGroup must have reliably reproducable names that tie the shader to a specific Nuke Node. For example if there are multiple chained MergeShader nodes then the name of each shader in the group will typcially contain the name of the Nuke node for this reason.

Subclasses implementing this method should look up the ShaderDesc it produces by name in the ShaderDescGroup using the ShaderDescGroup::getShaderNode() method, then assign the property overrides, also calling updateShaderGraphOverrides() on any MaterialOpI inputs.

Default implementation does nothing.

Reimplemented in DD::Image::CoShaderMaterialInterface.

Referenced by DD::Image::LightMaterialOpI::defineLightPrim(), DD::Image::GeomOpEngine::importLightOp(), DD::Image::GeomOpEngine::importShaderOp(), and DD::Image::ShaderOp::updateCoShaderInterfaceGraphOverrides().

◆ updateShaderGraphFromOp()

void DD::Image::MaterialOpI::updateShaderGraphFromOp ( Op input_op,
const MaterialContext rtx,
usg::ShaderDescGroup &  shader_group 
)
virtual

◆ getNodeInstanceSuffix()

std::string DD::Image::MaterialOpI::getNodeInstanceSuffix ( DD::Image::Op op)
static

Convenience function builds a suffix depending on if the op's node has clones. Return empty string if the node has no clones or else '_inst<instance index>'.

Referenced by DD::Image::GeomOpEngine::importShaderOp().

◆ getShaderTypeFromOp()

int32_t DD::Image::MaterialOpI::getShaderTypeFromOp ( Op op)
static

Return the type of the appropriate schema interface to use for the the provided Op. Returns INPUT_TYPE_NONE if no schema is appropriate.

These base Op types are currently supported: Op: INPUT_TYPE_OP ( generic Op* access ) Iop: INPUT_TYPE_IOP ( Iop* usually for texture access ) AxisOp: INPUT_TYPE_AXISOP, ( AxisOp* ) CameraOp: INPUT_TYPE_CAMERAOP ( CameraOp* ) LightOp: INPUT_TYPE_LIGHTOP ( LightOp* )

Shader Ops (INPUT_TYPE_MATERIALOP) are handled by testing for the presence of a MaterialOpI interface on the Op.

References DD::Image::ShaderOp::asMaterialOp(), DD::Image::Op::axisOp(), DD::Image::Op::cameraOp(), DD::Image::Op::iop(), DD::Image::Iop::isBlackIop(), and DD::Image::Op::lightOp().

◆ getShaderNodeNameFromOp()

std::string DD::Image::MaterialOpI::getShaderNodeNameFromOp ( const usg::Token &  target_renderer,
Op op 
)
static

Build or return the unique shader node name to use for the input Op.

If the Op is a MaterialOpI then MaterialOpI::getShaderNodeName() is returned, otherwise a name is built from the input Op's node name plus the schema type that the Op creates.

If 'target_renderer' is not empty it is prepended to the name with an underscore '_' separator.

References DD::Image::Op::nodeName().

◆ inputShaderTypeName()

const char * DD::Image::MaterialOpI::inputShaderTypeName ( int32_t  op_type)
static

Returns the built-in shader Schema name for input 'op_type'.

The built-in Op interface ShaderSchemas are: 'NukeOpInterface' INPUT_TYPE_OP ( generic Op* access ) 'NukeIopInterface' INPUT_TYPE_IOP ( Iop* usually for texture access ) 'NukeAxisOpInterface' INPUT_TYPE_AXISOP, ( AxisOp* ) 'NukeCameraOpInterface' INPUT_TYPE_CAMERAOP ( CameraOp* ) 'NukeLightOpInterface' INPUT_TYPE_LIGHTOP ( LightOp* )

◆ createOpInterfaceShaderDesc() [1/2]

usg::ShaderDesc * DD::Image::MaterialOpI::createOpInterfaceShaderDesc ( int32_t  op_type,
Op op 
)
static

Create an Op interface ShaderDesc from the provided interface type, setting its referencing properties from the Op.

The Op's absolute Node path (its Op::node_name()) and OutputContext are used for this as those uniquely identify an allocated Op. These properties are then used to reaquire the Op* when consumers like Hydra or SlrShaders need to evaluate values from the Op via the shader interface.

◆ createOpInterfaceShaderDesc() [2/2]

usg::ShaderDesc * DD::Image::MaterialOpI::createOpInterfaceShaderDesc ( Op op)
static

Create an Op interface ShaderDesc from the provided Op, setting its referencing properties.

The ShaderSchema name to create is retrieved via inputShaderTypeName() using the Op* type and passed to the createOpInterfaceShaderDesc(op_type, op) method.

◆ buildAssetPath()

std::string DD::Image::MaterialOpI::buildAssetPath ( Op input_op)
static

Creates a path representing the op, typically put into a shader 'file' input property.

The path includes the node path and instance(clone), OutputContext(frame, view, gsv hash, proxy info) and follows this syntax: /NkRoot/<node-path>:<frame-num>:<view-name>:0x<gsv-hash>:<proxy-info>:0x<op-hash>.<opclass-ext>

<opclass-ext> is specialized to the Op type - ie Iop, AxisOp, CameraOp, LightOp, or just Op, depending on the shader plugin that needs to be created by the USD plugin system.

<frame-num> is a Nuke script frame index (not a time) and can be floating point allowing access to fractional frame samples.

Note that this path is FAKE and only used as a way to communicate the Op pointer through the USD system. NodeI::findOp() is used to retrieve the correct matching Op instance, so this is why the node path + instance, view, frame, gsv-hash and proxy-info are provided to uniquely identify a specific Op*.

Also note the path MUST be an absolute path (starting with '/') otherwise USD will fail to parse the path correctly!

If a ShaderSchema declares an AssetPath input (see NukeIopInterface schema for an example) that path is resolved by USD by checking for a matching plugin that's been registered to handle the extension (ex. '.nkiop' for NukeIopInterface.)

References DD::Image::OutputContext::gsvScopeId(), DD::Image::Op::hash(), DD::Image::Op::nodeFullPath(), and DD::Image::Op::outputContext().

◆ parseAssetPath()

bool DD::Image::MaterialOpI::parseAssetPath ( const std::string &  path,
std::string &  nodePath,
OutputContext outputContext 
)
static

Parses a Node path string to extract its node name and output context.

The syntax matching presumes the path was created via buildAssetPath(), and must be an absolute path starting with '/NkRoot/', although it can contain a leading URI token like 'nkop:' or 'raw:' which will be ignored.

Important note - the contructed outputContext must match the OutputContext of the Op passed to buildAssetPath() otherwise the incorrect Op may be retrieved leading to anomalous texture behavior in Hydra and ScanlineRender.

Returns false on any failure.

References DD::Image::end(), DD::Image::ProxyContext::set(), and DD::Image::OutputContext::setGsvScope().

◆ retrieveOpFromAssetPath()

Op * DD::Image::MaterialOpI::retrieveOpFromAssetPath ( const std::string &  path)
static

Uses parseAssetPath() to extract the Op path info then calls Op::retrieveOp() to get the Op*.

See parseAssetPath() for info on possible problems related to Op retrieval due to incorrect texture asset path encodings.

Return null on failure, either due to parsing or an Op* retrieval problem.

References DD::Image::Op::hash().

◆ overrideShaderDescInput() [1/4]

bool DD::Image::MaterialOpI::overrideShaderDescInput ( const char *  knob_name,
const MaterialContext rtx,
usg::ShaderDesc &  shader_desc,
const char *  target_property_name,
usg::Value::Type  target_property_type_hint = usg::Value::Type::InvalidType 
)
protectedvirtual

Copy the value from a local Op Knob to the ShaderDesc which will assign or clear local input overrides. If Knob::not_default() is false the override is applied, otherwise the override is cleared.

'target_property_type_hint' is used to indicate the preferred output value type from Knobs that support them, such as Enumeration_knob which can either return the integer index or the string of the current selection, and Boolean_knob which can return either a boolean or int type. This is not done automatically so that Ops can better manage the conversion of knob values to shader overrides. For example pass in usg::Value::Type::String for an Enumeration_knob's string value and usg::Value::Type::Int for a Boolean_knob's integer value. Or if the Op has a Double_knob and it's writing to a shader float then pass usg::Value::Type::Float.

If greater control is required, such as splitting an 4-component AColor_knob into separate color & opacity destinations, a plugin should directly call the ShaderDesc::overrideInput() & ShaderDesc::clearInputOverride() methods.

These are virtual to allow subclasses to manage custom translation of property names, etc.

Returns true if the override was applied successfully.

Reimplemented in DD::Image::LightMaterialOpI.

References DD::Image::MaterialOpI::MaterialContext::frame, DD::Image::Knob::getAuthoring(), DD::Image::Authoring::getMode(), DD::Image::Knob::isAnimated(), DD::Image::Op::knob(), DD::Image::Op::nodeName(), DD::Image::Knob::not_default(), DD::Image::root_real_fps, DD::Image::MaterialOpI::MaterialContext::time, and DD::Image::MaterialOpI::MaterialContext::view.

Referenced by DD::Image::LightMaterialOpI::overrideShaderDescInput().

◆ overrideShaderDescInput() [2/4]

bool DD::Image::MaterialOpI::overrideShaderDescInput ( const Channel chan,
const MaterialContext rtx,
usg::ShaderDesc &  shader_desc,
const char *  target_property_name 
)
protectedvirtual

Specialization for Channel-source override which is translated/aliased to an int32_t.

Reimplemented in DD::Image::LightMaterialOpI.

◆ overrideShaderDescInput() [3/4]

bool DD::Image::MaterialOpI::overrideShaderDescInput ( const Channel chan_array,
uint32_t  num_channels,
const MaterialContext rtx,
usg::ShaderDesc &  shader_desc,
const char *  target_property_name 
)
protectedvirtual

Specialization for ChannelArray-source override which is translated/aliased to an int32_t array.

Reimplemented in DD::Image::LightMaterialOpI.

◆ overrideShaderDescInput() [4/4]

bool DD::Image::MaterialOpI::overrideShaderDescInput ( const ChannelSet channels,
const MaterialContext rtx,
usg::ShaderDesc &  shader_desc,
const char *  target_property_name 
)
protectedvirtual

Specialization for ChannelSet-source override which is translated/aliased to an int32_t array.

Reimplemented in DD::Image::LightMaterialOpI.

References DD::Image::ChannelSet::all(), and DD::Image::ChannelSet::size().



©2024 The Foundry Visionmongers, Ltd. All Rights Reserved.
www.foundry.com