NodeMaterial: Instancing API

I believe NodeMaterial could support an expressive instancing API, without requiring users to modify builtin shaders. The instancing • lambert example shows the simplest pre-existing approach, and is still complex enough that users will find it challenging to instance a 3D model created in a DCC tool.

Proposal:

import * as THREE from 'three';
import {
  StandardNodeMaterial,
  InstanceTransformNode,
  AttributeNode,
  FloatNode,
  OperatorNode,
  TextureNode
} from 'three/js/nodes/THREE.Nodes';

var material = new StandardNodeMaterial();

// Configure shared material properties as usual.
material.metalness = new FloatNode( 0 );

// Configure material.instanceTransform to reference 1-3 InstancedBufferAttribute nodes.
material.instanceTransform = THREE.InstanceTransformNode(
  new AttributeNode( 'instancePosition', 'vec3' ),
  new AttributeNode( 'instanceQuaternion', 'vec4' ),
  new AttributeNode( 'instanceScale', 'vec3' )
);

// Configure per-instance material properties using node expressions and InstancedBufferAttribute.
material.roughness = new AttributeNode( 'instanceRoughness' );
material.color = new OperatorNode(
  new TextureNode( baseColorTexture ),
  new AttributeNode( 'instanceColor' ),
  OperatorNode.MUL
);

With this API, and as loaders enable the NodeMaterial system, instancing models created in DCC tools becomes much easier:

var treePositions = new Float32Array(  [
  0, 0, 0,
  10, 0, 0,
  20, 0, 0
] );

var loader = new THREE.GLTFLoader();
loader
  .setUseNodes( true )
  .load( 'tree.glb', ( gltf ) => {
    var model = gltf.scene.children[ 0 ];

    model.geometry = new THREE.InstancedBufferGeometry().fromBufferGeometry( model.geometry );
    model.geometry.addAttribute( 'instancePosition', new THREE.InstancedBufferAttribute( treePositions, 3 );
    model.material.instanceTransfom = new THREE.InstanceTransformNode( THREE.AttributeNode( 'instancePosition' ) );

    scene.add( model );
  } );

This idea is based loosely on noticing recently that Unity plans to add instancing support to its Shader Graph master nodes.

/cc @sunag

Author: Fantashit

1 thought on “NodeMaterial: Instancing API

Comments are closed.