InstanceNode.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { bufferAttribute } from './BufferAttributeNode.js';
  3. import { normalLocal } from './NormalNode.js';
  4. import { positionLocal } from './PositionNode.js';
  5. import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
  6. class InstanceNode extends Node {
  7. constructor( instanceMesh ) {
  8. super( 'void' );
  9. this.instanceMesh = instanceMesh;
  10. //
  11. const instanceBuffers = [
  12. // F.Signature -> bufferAttribute( array, type, stride, offset )
  13. bufferAttribute( instanceMesh.instanceMatrix.array, 'vec4', 16, 0 ),
  14. bufferAttribute( instanceMesh.instanceMatrix.array, 'vec4', 16, 4 ),
  15. bufferAttribute( instanceMesh.instanceMatrix.array, 'vec4', 16, 8 ),
  16. bufferAttribute( instanceMesh.instanceMatrix.array, 'vec4', 16, 12 )
  17. ];
  18. this.instanceMatrixNode = mat4( ...instanceBuffers );
  19. }
  20. construct( builder ) {
  21. const { instanceMatrixNode } = this;
  22. // POSITION
  23. const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
  24. // NORMAL
  25. const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
  26. const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
  27. const instanceNormal = m.mul( transformedNormal ).xyz;
  28. // ASSIGNS
  29. builder.stack.assign( positionLocal, instancePosition );
  30. builder.stack.assign( normalLocal, instanceNormal );
  31. return builder.stack;
  32. }
  33. }
  34. export default InstanceNode;
  35. export const instance = nodeProxy( InstanceNode );
  36. addNodeClass( InstanceNode );