Repository: three.js
Issue: ShaderNode: MaterialX Nodes
Labels: Enhancement

Document with the purpose of comparing Three.js `ShaderNode` with `MaterialX`.

https://materialx.org/assets/MaterialX.v1.38.Spec.pdf

## Geometric

### Position
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  Position Model | `positionGeometry`  |
| ✅ |  Position Object | `positionLocal`  |
| ✅ |  Position World | `positionWorld`  |

### Normal
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  Normal Model | `normalGeometry`  |
| ✅ |  Normal Object | `normalLocal`  |
| ✅ |  Normal World | `normalWorld`  |

### Tangent
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  Tangent Model | `tangentGeometry`  |
| ✅ |  Tangent Object | `tangentLocal`  |
| ✅ |  Tangent World | `tangentWorld`  |

### Bitangent
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  Bitangent Model | `bitangentGeometry`  |
| ✅ |  Bitangent Object | `bitangentLocal`  |
| ✅ |  Bitangent World | `bitangentWorld`  |

### Texture coordinate
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  texcoord | `uv( index )`  |

### Geometry attribute
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  geomcolor | `attribute( 'color', 'vec3' )`  |
| ✅ |  geompropvalue | `attribute( value, type )`  |

## Application
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  frame | `frameId`  |
| ✅ |  time | `timeLocal()`  |
| ⬜️ |  updirection |   |

## Math
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  add | `add( in1, in2 )` |
| ✅ |  subtract | `sub( in1, in2 )`  |
| ✅ |  multiply | `mul( in1, in2 )`  |
| ✅ |  divide | `div( in1, in2 )`  |
| ✅ |  modulo | `mod( in1, in2 )`  |
| ✅ |  absval | `abs( in )`  |
| ✅ |  sign | `sign( in )`  |
| ✅ |  floor | `floor( in )`  |
| ✅ |  ceil | `ceil( in )`  |
| ✅ |  round | `round( in )`  |
| ✅ |  power | `pow( in1, in2 )`  |
| ✅ |  sin | `sin( in )`  |
| ✅ |  cos | `cos( in )`  |
| ✅ |  tan | `tan( in )`  |
| ✅ |  asin | `asin( in )`  |
| ✅ |  acos | `acos( in )`  |
| ✅ |  atan2 | `atan2( in1, in2 )`  |
| ✅ |  sqrt | `sqrt( in )`  |
| ⬜️ |  ln |  |
| ✅ |  exp | `exp( in )`  |
| ✅ |  clamp | `clamp( in, low = 0, high = 1 )`  |
| ✅ |  min | `min( in1, in2 )`  |
| ✅ |  max | `max( in1, in2 )`  |
| ✅ |  normalize | `normalize( in )`  |
| ✅ |  magnitude | `length( in )`  |
| ✅ |  dotproduct | `dot( in1, in2 )`  |
| ✅ |  crossproduct | `cross( in )`  |
| ⬜️ |  transformpoint |  |
| ⬜️ |  transformvector |  |
| ⬜️ |  transformnormal |  |
| ⬜️ |  transformmatrix | `transformDirection( in, mat )`  |
| ✅ |  normalmap | `normalMap( in, ... )`  |
| ⬜️ |  transpose |  |
| ⬜️ |  determinant |  |
| ⬜️ |  invertmatrix |  |
| ✅ |  rotate2d | `rotateUV( in, degToRad( amount ) )`  |
| ⬜️ |  rotate3d |  |
| ⬜️ |  arrayappend |  |
| ⬜️ |  dot |  |

## Adjustment
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  remap | `remap( in, inlow, inHigh, outLow, outHigh )` |
| ✅ |  smoothstep | `smoothstep( in, low, high )`  |
| ⬜️ |  curveadjust |   |
| ⬜️ |  curvelookup |   |
| ✅ |  luminance | `luminance( in, lumacoeffs = lumeCoeffs )`   |
| ✅ |  rgbtohsv | `mx_rgbtohsv( rgb )`  |
| ✅ |  hsvtorgb | `mx_hsvtorgb( hsv )`  |

## Compositing

### Premult
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ |  premult |   |
| ⬜️ |  unpremult |   |

### Blend
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  plus | `add( b, f )`  |
| ✅ |  minus | `sub( b, f )`   |
| ✅ |  difference | `difference( b, f )`   |
| ✅ |  burn | `burn( b, f )`   |
| ✅ |  dodge | `dodge( b, f )`   |
| ✅ |  overlay | `overlay( b, f )`   |

### Merge
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ |  disjointover |   |
| ⬜️ |  in |   |
| ⬜️ |  mask |   |
| ⬜️ |  matte |   |
| ⬜️ |  out |   |
| ⬜️ |  over |   |

### Masking
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ |  inside |   |
| ⬜️ |  outside |   |

### Mix
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ |  mix | `mix( x, y, a )` |

## Conditional
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ | ifgreater | `cond( greaterThan( in1, in2 ), value1, value2 )` |
| ✅ | ifgreatereq | `cond( greaterThanEqual( in1, in2 ), value1, value2 )` |
| ✅ | equal | `cond( equal( in1, in2 ), value1, value2 )` |
| ⬜️ | switch | |

## Channel
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ | convert | `vec*( in )` or `type*( in )` |
| ✅ | swizzle | `node.xyzw` or `node.rgba` |
| ✅ | combine2 | `vec2( in1, in2 )` |
| ✅ | combine3 | `vec3( in1, in2, in3 )` |
| ✅ | combine4 | `vec4( in1, in2, in3, in4 )` |

## Convolution
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ | blur| |
| ⬜️ | heighttonormal| |

## Procedural
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ | constant | `float( value )`, `vec2( value )`, `vec3( value )`, ...  |
| ✅ | ramplr | `mx_ramplr( valuel, valuer, texcoord )` |
| ✅ | ramptb | `mx_ramptb( valuet, valueb, texcoord )` |
| ✅ | splitlr | `mx_splitlr( valuel, valuer, center, texcoord )` |
| ✅ | splittb | `mx_splittb( valuet, valueb, texcoord )` |
| ✅ | noise2d | `mx_noise_float( vec2( texcoord ), amplitude = 1, pivot = 0 )` |
| ✅ | noise3d | `mx_noise_float( vec3( texcoord ), amplitude = 1, pivot = 0 )` |
| ✅ | fractal3d | `mx_fractal_noise_float( position, octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 )` |
| ✅ | cellnoise2d | `mx_cell_noise_float( vec2( texcoord ) )` |
| ✅ | cellnoise3d | `mx_cell_noise_float( vec3( texcoord ) )` |
| ✅ | worleynoise2d | `mx_worley_noise_float(.vec2( texcoord ), jitter = 1 )` |
| ✅ | worleynoise3d | `mx_worley_noise_float(.vec3( texcoord ), jitter = 1 )` |

## Global
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ | ambientocclusion | |

## Color Management 
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ✅ (Partial) | colorspace | `colorspace()` |

## Supplemental
| Supported | MaterialX | ShaderNode |
| ------------- | ------------- | ------------- |
| ⬜️ |  tiledimage | |
| ✅ |  triplanarprojection | `triplanarTextures( filex, filey, filez )` |
| ⬜️ |  ramp4 | |
| ⬜️ |  place2d | |
| ⬜️ |  safepower | |
| ✅ |  contrast | `add( mul( in, amount ), pivot )`  |
| ⬜️ |  range | |
| ⬜️ |  hsvadjust | |
| ✅ |  saturate |  `saturation( in, amount ) ` |
| ✅ |  extract |  `node[ 0 ]`,  `node[ 1 ]`, .. or `element( node, index )` |
| ✅ |  separate2 | `node.x`, `node.y` |
| ✅ |  separate3 | `node.x`, `node.y`, `node.z` |
| ✅ |  separate4 | `node.x`, `node.y`, `node.z`, `node.w` |