ROP Structure

ROPs are the core of the RayTK library. A ROP is essentially some chunks of GLSL code, and some metadata.

A ROP is a COMP that generates a Definition, which is output as a DAT table.

ROP Definitions

Inside each ROP there’s an opDefinition component.

It includes settings that define the properties of the ROP.

OpDefinition Settings

  • General settings
    • Enable: Whether the ROP should be used or bypassed. Typically this is bound to a parameter of the same name on the ROP itself.
    • Useruntimebypass: Whether the Enable parameter (if it exists) should be handled like any other runtime parameter, or, when this is false, switching off the Enable parameter totally excludes the OP from the scene, just passing through the first input definition.
    • Hostop: Reference to the parent ROP. This should always be .. to refer to the parent comp.
    • Paramsop: Optional reference to an operator that holds the ROP’s parameters. This should be blank except in the rare case of operators that support adding custom parameters like customOp.
    • Name: Globally unique name for the ROP, based on its path. This should always be an expression that pulls its value from inside the opDefinition.
    • Style: Optional setting that controls how the ROP’s viewer image appears. In nearly all cases this should be blank.
    • Librarynames: List of either names of globally available shared shader libraries (raytkCombine) and/or references to DATs inside the ROP that are injected into the shader (deduplicated to avoid conflicts if multiple ROP instances provide equivalent libraries).
    • Typespec: Reference to the typeSpec component that defines the data types used by the ROP. See below.
    • Inputdefs: Optional list of additional ROP definition tables to be included as inputs. This is used for cases where there are more than 8 inputs, or when there are inputs that have special handling.
    • Disableinspect: Whether the ROP supports the Inspect feature to launch the Inspector tool.
  • Code blocks (references to DATs that contain blocks of glsl code)
    • Opglobals: Global declarations, such as variables that are shared across multiple calls of the ROP’s main function code. This is not commonly used.
    • Initcode: Executable code that is called once at the beginning of the shader execution. This can be used to initialize global variables. It is not commonly used.
    • Functemplate: Required declaration of the ROP’s primary function. It can also include additional functions or other declarations that are specific to this particular instance of this type of ROP.
    • Materialcode: Optional executable code that materials use to produce colors when rendering. This is only used for material operators (e.g. modularMat, basicMat), and it’s typically just a call to a secondary function that’s defined in the Functemplate.
  • Tables (references to tables that specify one or more items that belong to the ROP).
    • Macrotable: Compiler macros which produce #defines in the generated shader.
    • Buffertable: Uniform arrays and/or samplerBuffers which pass arrays of values into the shader.
    • Texturetable: TOP inputs that are fed into the shader and referenced with sampler* uniforms.
    • Variabletable: Definitions of variables that the operator can provide to other operators. See Variables.
    • Referencetable: Definitions of references to variables from other operators. This is only used by variableReference.
    • Tagtable: Tags that indicate whether this operator uses certain renderer features like shadows or lights or surface color attributes.
    • Generatedmacrotables : Optional list of additional DATs handled like Macrotable. This is typically used for tables that are generated by helper components inside the ROP.
    • Paramgrouptable: Definitions of parameters that are passed into the shader as either uniforms, macros, or specialization constants.
    • Callbacks: Python functions which can be called on certain events like the initial creation of the ROP.
  • Metadata (mostly used for the palette and other tools)
    • Help: Optional DAT that contains help text. This is stripped out in the build process and moved to the documentation site.
    • Helpurl: Link to the page on the documentation site for this ROP.
    • Displaycategory: Category where the ROP is listed in the palette.
    • Shortcuts: Keyboard shortcuts for the palette search box.
    • Keywords: Keywords that are used when searching for ROPs in the palette.

Generated Definition tables

The opDefinition component produces a definition table row with the main properties of the ROP, added to the combined rows of the attached inputs of the ROP.

There are several categories of information about a ROP, produced by the opDefinition:

  • Inline definition table fields
    • These are included in the row that’s output by the ROP.
    • They’re also included in the full definition table within the opDefinition, along with additional fields.
    • They are the core propreties of the ROP, along with paths to other OPs that contain other categories of information.
    • name: globally unique name for the ROP, based on the path.
    • path: path to the ROP.
    • opType: identifies the type of ROP, and is derived from the path of the clone master used to create a ROP.
    • coordType: the type of coordinates that the ROP’s function accepts.
    • returnType: the type of value the that the ROP’s function returns.
    • contextType: the type of context that the ROP’s function expects along with the coordinates.
    • tags: indicators that the OP uses certain features like shadows or surface colors.
    • definitionPath: path to the DAT that contains the full table of ROP properties.
  • Local definition table fields
    • These are only included within a single-ROP table inside the opDefinition.
    • opVersion: version of that particular type of ROP.
    • toolkitVersion: version of the toolkit. This is used for validation.
    • paramSource: path to the CHOP that holds the values of runtime parameters.
    • constantParamSource: path to the CHOP that holds the values of specialization constant parameters. These are processed separately from runtime parameters to avoid unnecessary cooking.
    • paramVectors: path to a CHOP with the runtime parameters, rearranged into 4 vector channels. This will eventually be used to avoid having to reorder all the parameters in shaderBuilder.
    • libraryNames: names of common shared GLSL libraries and/or paths to ROP-local libraries.
  • RopState
    • This is a structured object stored as JSON in a DAT inside the opDefinition.
    • It holds prepared blocks of code.
    • It also holds more complex data like lists.
    • The shaderBuilder loads the object from the JSON while generating shader code and supporting tables.
  • Value CHOPs
    • These hold the current values of the ROP’s parameters.
    • The shaderBuilder combines the channels from these for all ROPs in the scene to pass in as uniforms and/or specialization constants.
    • The values for specialization constants are stored in a separate CHOP than those used as runtime parameters, so that changes to runtime parameters don’t cause things related to specialization constants to cook.

ROP Functions and GLSL Types

Each ROP has a main function that it contributes to the shader. All of these functions take in two parameters: coordinates, and context, and return a single value.

ReturnT sphere1(CoordT p, ContextT ctx) {
  return createSdf(length(p));
}

Coordinate types

  • vec3: 3D coordinates, such as a position along a ray as it is marching along through space.
  • vec2: 2D coordinates, such as screen-space UV coordinates, texture coordinates, or positions used for 2D SDFs.
  • float: 1D coordinates, which can be used for things like looking up how much to apply an effect based on distance from some point, or how to blend between two values.

Context types

Each ROP function takes a second parameter that is used to pass along additional information about the context in which the function is being called. ROPs often don’t make use of this, but they need to pass it along when calling other ROPs since they might need it.

  • Context: This is the most common type, which is used when evaluating an SDF during raymarching. It contains fields like iteration, which is used in cases like the reflect ROP so its input can do something different depending on which side of the reflection plane it’s on.
  • LightContext: Used by light ROPs to pass along information about the surface that it is being applied to and the normal direction.
  • MaterialContext: Used by materials to pass along information about the surface that it is being applied to, the light that’s being used, and where the ray that hit it came from.
  • CameraContext: Used by cameras to pass along information like the output resolution.
  • RayContext: Used by ray modifiers that bend or alter rays.

Return types

Each ROP function produces a single return value.

  • Sdf: The result of a signed distance function (SDF), representing what the closest shape is and how far it is from the ray position. It also contains information like which material to use.
  • float: A single numeric value. This can be used for value fields that determine how much of something to apply based on a position in space.
  • vec4: 4 numeric values. This can be used for vector fields or colors.
  • Ray: A position in 3D space and a direction. Cameras return one of these for each pixel in the ouput.
  • Light: Information about how much color is provided by a light to a surface.