diff --git a/.gitignore b/.gitignore index f2d3d5dccd..0cc9f65cde 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ build dist .DS_Store +.cache + +# temporary addition while we're iterating on building the specification from source +documents/SpecificationBuild + diff --git a/CMakeLists.txt b/CMakeLists.txt index 32770e0b57..3fd575fcc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,9 @@ project(MaterialX VERSION ${MATERIALX_LIBRARY_VERSION}) option(MATERIALX_BUILD_PYTHON "Build the MaterialX Python package from C++ bindings. Requires Python 3.9 or greater." OFF) option(MATERIALX_BUILD_VIEWER "Build the MaterialX Viewer." OFF) option(MATERIALX_BUILD_GRAPH_EDITOR "Build the MaterialX Graph Editor." OFF) -option(MATERIALX_BUILD_DOCS "Create HTML documentation using Doxygen. Requires that Doxygen be installed." OFF) +option(MATERIALX_BUILD_DOCS "(deprecated) use MATERIALX_BUILD_DOXYGEN_DOCS." OFF) +option(MATERIALX_BUILD_DOXYGEN_DOCS "Create HTML documentation using Doxygen. Requires that Doxygen be installed." OFF) +option(MATERIALX_BUILD_SPECIFICATION_DOCS "Create Specification documentation, using the data library templates." OFF) option(MATERIALX_BUILD_GEN_GLSL "Build the GLSL shader generator back-end." ON) option(MATERIALX_BUILD_GEN_OSL "Build the OSL shader generator back-end." ON) @@ -51,6 +53,8 @@ option(MATERIALX_BUILD_BENCHMARK_TESTS "Build benchmark tests." OFF) option(MATERIALX_BUILD_SHARED_LIBS "Build MaterialX libraries as shared rather than static." OFF) option(MATERIALX_BUILD_DATA_LIBRARY "Build generated products from the MaterialX data library." OFF) +option(MATERIALX_BUILD_EXPAND_TEMPLATE_ELEMS "Process the data library files at build time to expand any template elements." ON) +option(MATERIALX_BUILD_BAKE_NAMED_VALUES "Process the data library files at build time to bake out the named values." ON) option(MATERIALX_BUILD_MONOLITHIC "Build a single monolithic MaterialX library." OFF) option(MATERIALX_BUILD_USE_CCACHE "Enable the use of ccache to speed up build time, if present." ON) option(MATERIALX_PYTHON_LTO "Enable link-time optimizations for MaterialX Python." ON) @@ -68,6 +72,10 @@ if (MATERIALX_BUILD_IOS) set(CMAKE_SYSTEM_NAME iOS) endif() +list(APPEND CMAKE_MODULE_PATH + ${PROJECT_SOURCE_DIR}/cmake/macros) +include(Public) + # Apple ecosystem cross-compilation # https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-visionos-or-watchos set(MATERIALX_BUILD_APPLE_EMBEDDED OFF) @@ -107,6 +115,11 @@ if (MATERIALX_BUILD_JS) set(MATERIALX_BUILD_TESTS OFF) endif() +# to maintain legacy cmake argument +if (MATERIALX_BUILD_DOCS) + set(MATERIALX_BUILD_DOXYGEN_DOCS ON) +endif() + # All hardware shading languages currently depend on the GLSL shader generator. if(MATERIALX_BUILD_GEN_MSL) set(MATERIALX_BUILD_GEN_GLSL ON) @@ -437,6 +450,16 @@ else() set(BUILD_SHARED_LIBS "OFF") endif() +# If we're baking the named "Constant:" entries - then we have to also expand any +# template elements +if (MATERIALX_BUILD_BAKE_NAMED_VALUES) + set(MATERIALX_BUILD_EXPAND_TEMPLATE_ELEMS ON) +endif() + +if (MATERIALX_BUILD_EXPAND_TEMPLATE_ELEMS OR MATERIALX_BUILD_BAKE_NAMED_VALUES) + set(MATERIALX_BUILD_DATA_LIBRARY ON) +endif() + # Build a monolithic target - needs to be added before the other build targets that may be included. if (MATERIALX_BUILD_MONOLITHIC) set(MATERIALX_MONOLITHIC_TARGET MaterialX) @@ -446,6 +469,32 @@ endif() # Add core subdirectories add_subdirectory(source/MaterialXCore) add_subdirectory(source/MaterialXFormat) +if (MATERIALX_BUILD_EXPAND_TEMPLATE_ELEMS OR MATERIALX_BUILD_BAKE_NAMED_VALUES) + if (CMAKE_CROSSCOMPILING) + set(_MaterialXBuildLibrary "${CMAKE_BINARY_DIR}/BUILD_TOOLS/MaterialXBuildLibrary") + + add_custom_command( + OUTPUT ${_MaterialXBuildLibrary} + COMMAND ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_BINARY_DIR}/BUILD_TOOLS + -DMATERIALX_MAJOR_VERSION=${MATERIALX_MAJOR_VERSION} + -DMATERIALX_MINOR_VERSION=${MATERIALX_MINOR_VERSION} + -DMATERIALX_BUILD_VERSION=${MATERIALX_BUILD_VERSION} + -DMATERIALX_NAMESPACE=${MATERIALX_NAMESPACE} + -DMATERIALX_BUILD_BAKE_NAMED_VALUES=ON + -B"BUILD_TOOLS" + -H"${CMAKE_SOURCE_DIR}/source/MaterialXBuildTools" + COMMAND ${CMAKE_COMMAND} --build BUILD_TOOLS + DEPENDS MaterialXCore MaterialXFormat + ) + add_custom_target(MaterialXBuildLibrary ALL + DEPENDS ${_MaterialXBuildLibrary}) + else() + set(_MaterialXBuildLibrary MaterialXBuildLibrary) + add_subdirectory(source/MaterialXBuildTools/buildLibrary) + endif() +endif() # Add shader generation subdirectories add_subdirectory(source/MaterialXGenShader) @@ -467,6 +516,7 @@ if(MATERIALX_BUILD_GEN_GLSL OR MATERIALX_BUILD_GEN_OSL OR MATERIALX_BUILD_GEN_MD add_subdirectory(source/MaterialXGenMsl) endif() add_subdirectory(libraries) + add_subdirectory(templates) endif() # Add rendering and viewer subdirectories @@ -511,8 +561,11 @@ if(MATERIALX_BUILD_PYTHON) add_subdirectory(python) endif() -if(MATERIALX_BUILD_DOCS) +if(MATERIALX_BUILD_DOXYGEN_DOCS OR MATERIALX_BUILD_SPECIFICATION_DOCS) add_subdirectory(documents) + if (MATERIALX_BUILD_SPECIFICATION_DOCS) + add_subdirectory(source/MaterialXBuildTools/buildDocs) + endif() endif() if(MATERIALX_BUILD_JS) diff --git a/cmake/macros/Public.cmake b/cmake/macros/Public.cmake new file mode 100644 index 0000000000..4ac9d55dfc --- /dev/null +++ b/cmake/macros/Public.cmake @@ -0,0 +1,127 @@ +# Shared functions need to be extracted to allow them to be shared with the subproject +# in source/MaterialXBuildTools + +function(assign_source_group prefix) + foreach(_source IN ITEMS ${ARGN}) + if(IS_ABSOLUTE "${_source}") + file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}") + else() + set(_source_rel "${_source}") + endif() + get_filename_component(_source_path "${_source_rel}" PATH) + string(REPLACE "/" "\\" _source_path_msvc "${_source_path}") + source_group("${prefix}\\${_source_path_msvc}" FILES "${_source}") + endforeach() +endfunction(assign_source_group) + +function(mx_add_library MATERIALX_MODULE_NAME) + set(options ADD_OBJECTIVE_C_CODE) + set(oneValueArgs EXPORT_DEFINE) + set(multiValueArgs + SOURCE_FILES + HEADER_FILES + INLINED_FILES + MTLX_MODULES) + cmake_parse_arguments(args + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN}) + + if (APPLE AND args_ADD_OBJECTIVE_C_CODE) + file(GLOB_RECURSE materialx_source_oc "${CMAKE_CURRENT_SOURCE_DIR}/*.m*") + set_source_files_properties(${materialx_source_oc} PROPERTIES + COMPILE_FLAGS "-x objective-c++") + set(args_SOURCE_FILES ${args_SOURCE_FILES} ${materialx_source_oc}) + endif() + + assign_source_group("Source Files" ${args_SOURCE_FILES}) + assign_source_group("Source Files" ${args_INLINED_FILES}) + assign_source_group("Header Files" ${args_HEADER_FILES}) + + if (NOT MATERIALX_BUILD_MONOLITHIC) + set(TARGET_NAME ${MATERIALX_MODULE_NAME}) + add_library(${TARGET_NAME}) + + # Create version resource + if(MATERIALX_BUILD_SHARED_LIBS AND MSVC) + configure_file(${PROJECT_SOURCE_DIR}/cmake/modules/MaterialXVersion.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + target_sources(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + endif() + + target_link_libraries(${TARGET_NAME} + PUBLIC + ${args_MTLX_MODULES} + ${CMAKE_DL_LIBS}) + + target_include_directories(${TARGET_NAME} + PUBLIC + $ + $ + PRIVATE + ${EXTERNAL_INCLUDE_DIRS}) + + set_target_properties( + ${TARGET_NAME} PROPERTIES + OUTPUT_NAME ${MATERIALX_MODULE_NAME}${MATERIALX_LIBNAME_SUFFIX} + COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS}" + LINK_FLAGS "${EXTERNAL_LINK_FLAGS}" + INSTALL_RPATH "${MATERIALX_SAME_DIR_RPATH}" + VERSION "${MATERIALX_LIBRARY_VERSION}" + SOVERSION "${MATERIALX_MAJOR_VERSION}") + else() + set(TARGET_NAME ${MATERIALX_MONOLITHIC_TARGET}) + add_library(${MATERIALX_MODULE_NAME} ALIAS ${MATERIALX_MONOLITHIC_TARGET}) + + # Store the aliased MaterialX modules name to create CMake export aliases later. + set_property(GLOBAL APPEND PROPERTY MATERIALX_MODULES ${MATERIALX_MODULE_NAME}) + endif() + + set_target_properties(${TARGET_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) + set_target_properties(${TARGET_NAME} PROPERTIES CMAKE_VISIBILITY_INLINES_HIDDEN 1) + + target_sources(${TARGET_NAME} + PRIVATE + ${args_SOURCE_FILES} + PUBLIC + FILE_SET + mxHeaders + TYPE + HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR}/.. + FILES + ${args_HEADER_FILES} + ${args_INLINED_FILES}) + + target_include_directories(${TARGET_NAME} PUBLIC + $) + + target_compile_definitions(${TARGET_NAME} PRIVATE "-D${args_EXPORT_DEFINE}") + + if(NOT SKBUILD) + if(NOT MATERIALX_BUILD_MONOLITHIC) + install(TARGETS ${MATERIALX_MODULE_NAME} + EXPORT MaterialX + ARCHIVE DESTINATION ${MATERIALX_INSTALL_LIB_PATH} + LIBRARY DESTINATION ${MATERIALX_INSTALL_LIB_PATH} + RUNTIME DESTINATION ${MATERIALX_INSTALL_BIN_PATH} + FILE_SET mxHeaders DESTINATION ${MATERIALX_INSTALL_INCLUDE_PATH}) + endif() + + if(MSVC) + if(MATERIALX_BUILD_SHARED_LIBS) + install(FILES $ + DESTINATION ${MATERIALX_INSTALL_BIN_PATH} OPTIONAL) + else() + install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$/$.pdb" + DESTINATION ${MATERIALX_INSTALL_LIB_PATH} OPTIONAL) + endif() + endif() + endif() + + # Pass TARGET_NAME back to call site, so the caller can modify the build target. + set(TARGET_NAME ${TARGET_NAME} PARENT_SCOPE) +endfunction() + diff --git a/documents/CMakeLists.txt b/documents/CMakeLists.txt index 6284540d4b..8c4499c228 100644 --- a/documents/CMakeLists.txt +++ b/documents/CMakeLists.txt @@ -1,45 +1,81 @@ -set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) -set(DOXYGEN_HTML_OUTPUT_DIR ${DOXYGEN_OUTPUT_DIR}/html) -set(DOXYGEN_INPUT_LIST ${CMAKE_CURRENT_BINARY_DIR}/MainPage.md) - -set(MATERIALX_DOXYGEN_SOURCE_FOLDERS - ${PROJECT_SOURCE_DIR}/source/MaterialXCore - ${PROJECT_SOURCE_DIR}/source/MaterialXFormat - ${PROJECT_SOURCE_DIR}/source/MaterialXGenShader - ${PROJECT_SOURCE_DIR}/source/MaterialXGenShader/Nodes - ${PROJECT_SOURCE_DIR}/source/MaterialXGenGlsl - ${PROJECT_SOURCE_DIR}/source/MaterialXGenGlsl/Nodes - ${PROJECT_SOURCE_DIR}/source/MaterialXGenOsl - ${PROJECT_SOURCE_DIR}/source/MaterialXGenMdl - ${PROJECT_SOURCE_DIR}/source/MaterialXRender - ${PROJECT_SOURCE_DIR}/source/MaterialXRenderHw - ${PROJECT_SOURCE_DIR}/source/MaterialXRenderGlsl - ${PROJECT_SOURCE_DIR}/source/MaterialXRenderOsl) - -find_package(Doxygen REQUIRED) - -foreach(FOLDER ${MATERIALX_DOXYGEN_SOURCE_FOLDERS}) - file(GLOB FOLDER_HEADERS ${FOLDER}/*.h) - list(APPEND DOXYGEN_INPUT_LIST ${FOLDER_HEADERS}) -endforeach() - -string (REPLACE ";" " " DOXYGEN_INPUT_STR "${DOXYGEN_INPUT_LIST}") - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - -add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/MainPage.md - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/DeveloperGuide/MainPage.md ${CMAKE_CURRENT_BINARY_DIR} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/DeveloperGuide/MainPage.md) - -add_custom_command(OUTPUT ${DOXYGEN_HTML_OUTPUT_DIR}/index.html - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/DoxygenAwesome ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Images ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${DOXYGEN_INPUT_LIST} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile - COMMENT "Generating HTML documentation: ${DOXYGEN_HTML_OUTPUT_DIR}/index.html") -add_custom_target(MaterialXDocs ALL DEPENDS ${DOXYGEN_HTML_OUTPUT_DIR}/index.html) - -install(DIRECTORY ${DOXYGEN_HTML_OUTPUT_DIR} - DESTINATION "documents" MESSAGE_NEVER) + +if (MATERIALX_BUILD_DOXYGEN_DOCS) + + set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + set(DOXYGEN_HTML_OUTPUT_DIR ${DOXYGEN_OUTPUT_DIR}/html) + set(DOXYGEN_INPUT_LIST ${CMAKE_CURRENT_BINARY_DIR}/MainPage.md) + + set(MATERIALX_DOXYGEN_SOURCE_FOLDERS + ${PROJECT_SOURCE_DIR}/source/MaterialXCore + ${PROJECT_SOURCE_DIR}/source/MaterialXFormat + ${PROJECT_SOURCE_DIR}/source/MaterialXGenShader + ${PROJECT_SOURCE_DIR}/source/MaterialXGenShader/Nodes + ${PROJECT_SOURCE_DIR}/source/MaterialXGenGlsl + ${PROJECT_SOURCE_DIR}/source/MaterialXGenGlsl/Nodes + ${PROJECT_SOURCE_DIR}/source/MaterialXGenOsl + ${PROJECT_SOURCE_DIR}/source/MaterialXGenMdl + ${PROJECT_SOURCE_DIR}/source/MaterialXRender + ${PROJECT_SOURCE_DIR}/source/MaterialXRenderHw + ${PROJECT_SOURCE_DIR}/source/MaterialXRenderGlsl + ${PROJECT_SOURCE_DIR}/source/MaterialXRenderOsl) + + find_package(Doxygen REQUIRED) + + foreach(FOLDER ${MATERIALX_DOXYGEN_SOURCE_FOLDERS}) + file(GLOB FOLDER_HEADERS ${FOLDER}/*.h) + list(APPEND DOXYGEN_INPUT_LIST ${FOLDER_HEADERS}) + endforeach() + + string (REPLACE ";" " " DOXYGEN_INPUT_STR "${DOXYGEN_INPUT_LIST}") + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/MainPage.md + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/DeveloperGuide/MainPage.md ${CMAKE_CURRENT_BINARY_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/DeveloperGuide/MainPage.md) + + add_custom_command(OUTPUT ${DOXYGEN_HTML_OUTPUT_DIR}/index.html + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/DoxygenAwesome ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Images ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${DOXYGEN_INPUT_LIST} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + COMMENT "Generating HTML documentation: ${DOXYGEN_HTML_OUTPUT_DIR}/index.html") + add_custom_target(MaterialXDocs ALL DEPENDS ${DOXYGEN_HTML_OUTPUT_DIR}/index.html) + + install(DIRECTORY ${DOXYGEN_HTML_OUTPUT_DIR} + DESTINATION "documents" MESSAGE_NEVER) +endif() + + +if (MATERIALX_BUILD_SPECIFICATION_DOCS) + set(MATERIALX_DATA_LIBRARY_TEMPLATE_DIR ${PROJECT_SOURCE_DIR}/templates) + set(MATERIALX_SPECIFICATION_TEMPLATE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/SpecificationTemplates) + #Ulitmately we may decide to move this directly to ${CMAKE_CURRENT_SOURCE_DIR}/Specification + set(MATERIALX_SPECIFICATION_DEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/SpecificationBuild) + + set(DOCS_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/nodes) + set(NODE_MD_MANIFEST ${DOCS_OUTPUT_DIR}/_manifest.txt) + + file(GLOB_RECURSE MATERIALX_DATA_LIBRARY_MTLX_SOURCE_FILES + LIST_DIRECTORIES false + ${MATERIALX_DATA_LIBRARY_TEMPLATE_DIR}/*.mtlx) + + file(GLOB_RECURSE MATERIALX_MD_SOURCE_FILES + LIST_DIRECTORIES false + ${MATERIALX_SPECIFICATION_TEMPLATE_SOURCE_DIR}/*.template.md) + + add_custom_command( + OUTPUT ${NODE_MD_MANIFEST} + COMMAND ${CMAKE_COMMAND} -E make_directory ${DOCS_OUTPUT_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${MATERIALX_SPECIFICATION_DEST_DIR} + COMMAND MaterialXBuildDocs --sourceLibraryRoot ${MATERIALX_DATA_LIBRARY_TEMPLATE_DIR} --destDocRoot ${DOCS_OUTPUT_DIR} --sourceMDRoot ${MATERIALX_SPECIFICATION_TEMPLATE_SOURCE_DIR} --destMDRoot ${MATERIALX_SPECIFICATION_DEST_DIR} --manifestFile ${NODE_MD_MANIFEST} + DEPENDS ${MATERIALX_DATA_LIBRARY_MTLX_SOURCE_FILES} ${MATERIALX_MD_SOURCE_FILES} MaterialXBuildDocs + ) + + add_custom_target(MaterialXBuildSpecificationDocs ALL + DEPENDS ${NODE_MD_MANIFEST}) + +endif() + diff --git a/documents/SpecificationTemplates/MaterialX.StandardNodes.template.md b/documents/SpecificationTemplates/MaterialX.StandardNodes.template.md new file mode 100644 index 0000000000..d4c74962f9 --- /dev/null +++ b/documents/SpecificationTemplates/MaterialX.StandardNodes.template.md @@ -0,0 +1,1328 @@ + + + +# MaterialX Standard Nodes + +**Version 1.39** +Doug Smythe - Industrial Light & Magic +Jonathan Stone - Lucasfilm Advanced Development Group +March 15, 2025 + + +# Introduction + +The MaterialX Specification defines a content schema to describe materials, image processing and shading networks and how the nodes in those networks access textural and geometric information, in a platform- and shading-language-independent manner. + +This document describes a specific set of **Standard Nodes** that can be used to read and process image and geometric attribute data, as well as create new image data procedurally. These "stdlib" nodes are an essential core part of all MaterialX implementations. Additional nodes are described in companion documents [**MaterialX Physically Based Shading Nodes**](./MaterialX.PBRSpec.md) and [**MaterialX NPR Shading Nodes**](./MaterialX.NPRSpec.md). + +In the descriptions below, a node with an "(NG)" annotation indicates a node that is implemented using a nodegraph in the MaterialX distribution, while unannotated nodes are implemented natively in the various renderer shading languages. + + +## Table of Contents + +**[Introduction](#introduction)** + +**[Standard Source Nodes](#standard-source-nodes)** + [Texture Nodes](#texture-nodes) + [Procedural Nodes](#procedural-nodes) + [Noise Nodes](#noise-nodes) + [Shape Nodes](#shape-nodes) + [Geometric Nodes](#geometric-nodes) + [Application Nodes](#application-nodes) + +**[Standard Operator Nodes](#standard-operator-nodes)** + [Math Nodes](#math-nodes) + [Logical Operator Nodes](#logical-operator-nodes) + [Adjustment Nodes](#adjustment-nodes) + [Compositing Nodes](#compositing-nodes) + [Conditional Nodes](#conditional-nodes) + [Channel Nodes](#channel-nodes) + [Convolution Nodes](#convolution-nodes) + +**[Standard Shader Nodes](#standard-shader-nodes)** + +
+ + +# Standard Source Nodes + +Source nodes use external data and/or procedural functions to form an output; they do not have any required inputs. Each source node must define its output type. + +This section defines the Source Nodes that all MaterialX implementations are expected to support. Standard Source Nodes are grouped into the following classifications: [Texture Nodes](#texture-nodes), [Procedural Nodes](#procedural-nodes), [Noise Nodes](#noise-nodes), [Shape Nodes](#shape-nodes), [Geometric Nodes](#geometric-nodes) and [Application Nodes](#application-nodes). + + +## Texture Nodes + +Texture nodes are used to read filtered image data from image or texture map files for processing within a node graph. + +```xml + + + + + + + + +``` + +Standard Texture nodes: + + + +### `image` + +Samples data from a single image, or from a layer within a multi-layer image. When used in the context of rendering a geometry, the image is mapped onto the geometry based on geometry UV coordinates, with the lower-left corner of an image mapping to the (0,0) UV coordinate (or to the fractional (0,0) UV coordinate for tiled images). + +The type of the <image> node determines the number of channels output, which may be less than the number of channels in the image file, outputting the first N channels from the image file. So a `float` <image> would return the Red channel of an RGB image, and a `color3` <image> would return the RGB channels of an RGBA image. If the type of the <image> node has more channels than the referenced image file, then the output will contain zero values in all channels beyond the N channels of the image file. + +The `file` input can include one or more substitutions to change the file name that is accessed, as described in the [Filename Substitutions](./MaterialX.Specification.md#filename-substitutions) section in the main Specification document. The `filtertype` input supports options `closest` (nearest-neighbor single-sample), `linear`, and `cubic`. + +@MX_TABLE_image@ + + + +### `tiledimage` +Samples data from a single image, with provisions for tiling and offsetting the image across uv space. + +The `file` input can include one or more substitutions to change the file name that is accessed, as described in the [Filename Substitutions](./MaterialX.Specification.md#filename-substitutions) section in the main Specification document. + +@MX_TABLE_tiledimage@ + + + +### `latlongimage` +Samples an equiangular map along a view direction with adjustable latitudinal offset. + +The `file` input can include one or more substitutions to change the file name that is accessed, as described in the [Filename Substitutions](./MaterialX.Specification.md#filename-substitutions) section in the main Specification document. + +@MX_TABLE_latlongimage@ + + + +### `triplanarprojection` +Samples data from three images (or layers within multi-layer images), and projects a tiled representation of the images along each of the three respective coordinate axes, computing a weighted blend of the three samples using the geometric normal. + +@MX_TABLE_triplanarprojection@ + + + + +The following values are supported by `uaddressmode` and `vaddressmode` inputs of [image](#node-image) nodes: + +* “constant”: Texture coordinates outside the 0-1 range return the value of the node's `default` input. +* “clamp”: Texture coordinates are clamped to the 0-1 range before sampling the image. +* “periodic”: Texture coordinates outside the 0-1 range "wrap around", effectively being processed by a modulo 1 operation before sampling the image. +* "mirror": Texture coordinates outside the 0-1 range will be mirrored back into the 0-1 range, e.g. u=-0.01 will return the u=0.01 texture coordinate value, and u=1.01 will return the u=0.99 texture coordinate value. + + +Texture nodes using `file*` inputs also support the following inputs to handle boundary conditions for image file frame ranges for all `file*` inputs: + +* `framerange` (uniform string): a string "_minframe_-_maxframe_", e.g. "10-99", to specify the range of frames that the image file is allowed to have, usually the range of image files on disk. Default is unbounded. +* `frameoffset` (integer): a number that is added to the current frame number to get the image file frame number. E.g. if `frameoffset` is 25, then processing frame 100 will result in reading frame 125 from the imagefile sequence. Default is no frame offset. +* `frameendaction` (uniform string): what to do when the resolved image frame number is outside the `framerange` range: + * "constant": Return the value of the node's `default` input (default action) + * "clamp": Hold the minframe image for all frames before _minframe_ and hold the maxframe image for all frames after _maxframe_ + * "periodic": Frame numbers "wrap around", so after the _maxframe_ it will start again at _minframe_ (and similar before _minframe_ wrapping back around to _maxframe_) + * "mirror": Frame numbers "mirror" or "ping-pong" at the endpoints of framerange, so a read of the frame after _maxframe_ will return the image from frame _maxframe_-1, and a read of the frame before _minframe_ will return the image from frame _minframe_+1. + +Arbitrary frame number expressions and speed changes are not supported. + + + +## Procedural Nodes + +Procedural nodes are used to generate value data programmatically. + +```xml + + + + + + + +``` + +Standard Procedural nodes: + + + +### `constant` +Outputs a constant value. + +@MX_TABLE_constant@ + + + + +### `ramplr` +A left-to-right linear value ramp + +@MX_TABLE_ramplr@ + + + +### `ramptb` +A top-to-bottom linear value ramp. + +@MX_TABLE_ramptb@ + + + +### `ramp4` +A 4-corner bilinear value ramp. + +@MX_TABLE_ramp4@ + + + +### `splitlr` +A left-right split matte, split at a specified `U` value. + +@MX_TABLE_splitlr@ + + + +### `splittb` +A top-bottom split matte, split at a specified `V`` value. + +@MX_TABLE_splittb@ + + + +* **`randomfloat`**: Produces a stable randomized float value between 'min' and 'max', based on an 'input' signal and 'seed' value. Uses a 2d cellnoise function to produce the output. + * `in` (float or integer): Initial randomization seed, default is 0. + * `min` (float): The minimum output value, default is 0.0. + * `max` (float): The maximum output value, default is 1.0. + * `seed` (integer): Additional randomization seed, default is 0. + + + +* **`randomcolor`**: Produces a randomized RGB color within a randomized hue, saturation and brightness range, based on an 'input' signal and 'seed' value. Output type color3. + * `in` (float or integer): Initial randomization seed, default is 0. + * `huelow` (float): The minimum hue value, default is 0.0. + * `huehigh` (float): The maximum hue value, default is 1.0. + * `saturationlow` (float): The minimum saturation value, default is 0.0. + * `saturationhigh` (float): The maximum saturation value, default is 1.0. + * `brightnesslow` (float): The minimum brightness value, default is 0.0. + * `brightnesshigh` (float): The maximum brightness value, default is 1.0. + * `seed` (integer): Additional randomization seed, default is 0. + + +To scale or offset `rampX` or `splitX` input coordinates, use a <texcoord> or similar Geometric node processed by vector2 <multiply>, <rotate> and/or <add> nodes, and connect to the node's `texcoord` input. + + + +## Noise Nodes + +Noise nodes are used to generate value data using one of several procedural noise functions. + +```xml + + + + +``` + +Standard Noise nodes: + + + +### `noise2d` +2D Perlin noise in 1, 2, 3 or 4 channels. + +@MX_TABLE_noise2d@ + + + +### `noise3d` +3D Perlin noise in 1, 2, 3 or 4 channels. + +@MX_TABLE_noise3d@ + + + +* **`fractal2d`**: Zero-centered 2D Fractal noise in 1, 2, 3 or 4 channels, created by summing several octaves of 2D Perlin noise, increasing the frequency and decreasing the amplitude at each octave. + * `amplitude` (float or vectorN): the center-to-peak amplitude of the noise (peak-to-peak amplitude is 2x this value). Default is 1.0. + * `octaves` (integer): the number of octaves of noise to be summed. Default is 3. + * `lacunarity` (float or vectorN): the exponential scale between successive octaves of noise; must be an integer value if period is non-zero so the result is properly tileable. Default is 2.0. VectorN-output types can provide either a float (isotropic) or vectorN (anisotropic) values for `lacunarity` and `diminish`. + * `diminish` (float or vectorN): the rate at which noise amplitude is diminished for each octave. Should be between 0.0 and 1.0; default is 0.5. VectorN-output types can provide either a float (isotropic) or vectorN (anisotropic) values for `lacunarity` and `diminish`. + * `texcoord` (vector2): the 2D texture coordinate at which the noise is evaluated. Default is to use the first set of texture coordinates. + + + +### `fractal3d` +Zero-centered 3D Fractal noise in 1, 2, 3 or 4 channels, created by summing several octaves of 3D Perlin noise, increasing the frequency and decreasing the amplitude at each octave. + +@MX_TABLE_fractal3d@ + + + +### `cellnoise2d` +2D cellular noise, 1 or 3 channels (type float or vector3). + +@MX_TABLE_cellnoise2d@ + + + +### `cellnoise3d` +3D cellular noise, 1 or 3 channels (type float or vector3). + +@MX_TABLE_cellnoise3d@ + + + +### `worleynoise2d` +2D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features). + +@MX_TABLE_worleynoise2d@ + + + +### `worleynoise3d` +3D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features). + +@MX_TABLE_worleynoise3d@ + + + +### `unifiednoise2d` +(NG): a single node supporting 2D Perlin, Cell, Worley or Fractal noise in a unified interface. + +@MX_TABLE_unifiednoise2d@ + + + +### `unifiednoise3d` +(NG): a single node supporting 3D Perlin, Cell, Worley or Fractal noise in a unified interface. + +@MX_TABLE_unifiednoise3d@ + + +To scale or offset the noise pattern generated by a 3D noise node such as `noise3d`, `fractal3d` or `cellnoise3d`, use a <position> or other [Geometric Node](#geometric-nodes) (see below) connected to vector3 <multiply> and/or <add> nodes, in turn connected to the noise node's `position` input. To scale or offset the noise pattern generated by a 2D noise node such as `noise2d` or `cellnoise2d`, use a <texcoord> or similar Geometric node processed by vector2 <multiply>, <rotate> and/or <add> nodes, and connect to the node's `texcoord` input. + + + +## Shape Nodes + +Shape nodes are used to generate shapes or patterns in UV space. + +```xml + + + + + +``` + +Standard Shape nodes: + + + +### `checkerboard` +2D checkerboard pattern. + +@MX_TABLE_checkerboard@ + + + +### `line` +2D line pattern. + +@MX_TABLE_line@ + + + +### `circle` +2D circle(disk) pattern. + +@MX_TABLE_circle@ + + + +### `cloverleaf` +2D cloverleaf pattern: four semicircles on the edges of a square defined by center and radius. + +@MX_TABLE_cloverleaf@ + + + +### `hexagon` +2D hexagon pattern. + +@MX_TABLE_hexagon@ + + + +### `grid` +Creates a grid pattern of (1, 1, 1) white lines on a (0, 0, 0) black background with the given tiling, offset, and line thickness. Pattern can be regular or staggered. + +@MX_TABLE_grid@ + + + +### `crosshatch` +Creates a crosshatch pattern with the given tiling, offset, and line thickness. Pattern can be regular or staggered. + +@MX_TABLE_crosshatch@ + + + +### `tiledcircles` +Creates a black and white pattern of circles with a defined tiling and size (diameter). Pattern can be regular or staggered. + +@MX_TABLE_tiledcircles@ + + + +### `tiledcloverleafs` +Creates a black and white pattern of cloverleafs with a defined tiling and size (diameter of the circles circumscribing the shape). Pattern can be regular or staggered. + +@MX_TABLE_tiledcloverleafs@ + + + +### `tiledhexagons` +Creates a black and white pattern of hexagons with a defined tiling and size (diameter of the circles circumscribing the shape). Pattern can be regular or staggered. + +@MX_TABLE_tiledhexagons@ + + + +## Geometric Nodes + +Geometric nodes are used to reference local geometric properties from within a node graph: + +```xml + + + + +``` + +Standard Geometric nodes: + + + +### `position` +The coordinates associated with the currently-processed data, as defined in a specific coordinate space. + +@MX_TABLE_position@ + + + +### `normal` +The normalized geometric normal associated with the currently-processed data, as defined in a specific coordinate space. + +@MX_TABLE_normal@ + + + +### `tangent` +The geometric tangent vector associated with the currently-processed data, as defined in a specific coordinate space. + +@MX_TABLE_tangent@ + + + +### `bitangent` +The geometric bi-tangent vector associated with the currently-processed data, as defined in a specific coordinate space. + +@MX_TABLE_bitangent@ + + + +### `bump` +The normalized normal computed by offsetting the surface world space position along its world space normal. + +@MX_TABLE_bump@ + + + +### `texcoord` +The 2D or 3D texture coordinates associated with the currently-processed data + +@MX_TABLE_texcoord@ + + + +### `geomcolor` +The color associated with the current geometry at the current position, generally bound via per-vertex color values. The type must match the type of the "color" bound to the geometry. + +@MX_TABLE_geomcolor@ + + + +### `geompropvalue` +The value of the specified varying geometric property (defined using ) of the currently-bound geometry. This node's type must match that of the referenced geomprop. + +@MX_TABLE_geompropvalue@ + + + +### `geompropvalueuniform` +The value of the specified uniform geometric property (defined using ) of the currently-bound geometry. This node's type must match that of the referenced geomprop. + +@MX_TABLE_geompropvalueuniform@ + + +Additionally, the `geomcolor` and `geompropvalue` nodes for color3/color4-type properties can take a `colorspace` attribute to declare what colorspace the color property value is in; the default is "none" for no colorspace declaration (and hence no colorspace conversion). + + + +## Application Nodes + +Application nodes are used to reference application-defined properties within a node graph, and have no inputs: + +```xml + +