InstanceNode.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { instancedBufferAttribute, instancedDynamicBufferAttribute } 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. import { DynamicDrawUsage, InstancedInterleavedBuffer } from 'three';
  7. class InstanceNode extends Node {
  8. constructor( instanceMesh ) {
  9. super( 'void' );
  10. this.instanceMesh = instanceMesh;
  11. this.instanceMatrixNode = null;
  12. }
  13. setup( /*builder*/ ) {
  14. let instanceMatrixNode = this.instanceMatrixNode;
  15. if ( instanceMatrixNode === null ) {
  16. const instanceMesh = this.instanceMesh;
  17. const instanceAttribute = instanceMesh.instanceMatrix;
  18. const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
  19. const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
  20. const instanceBuffers = [
  21. // F.Signature -> bufferAttribute( array, type, stride, offset )
  22. bufferFn( buffer, 'vec4', 16, 0 ),
  23. bufferFn( buffer, 'vec4', 16, 4 ),
  24. bufferFn( buffer, 'vec4', 16, 8 ),
  25. bufferFn( buffer, 'vec4', 16, 12 )
  26. ];
  27. instanceMatrixNode = mat4( ...instanceBuffers );
  28. this.instanceMatrixNode = instanceMatrixNode;
  29. }
  30. // POSITION
  31. const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
  32. // NORMAL
  33. const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
  34. const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
  35. const instanceNormal = m.mul( transformedNormal ).xyz;
  36. // ASSIGNS
  37. positionLocal.assign( instancePosition );
  38. normalLocal.assign( instanceNormal );
  39. }
  40. }
  41. export default InstanceNode;
  42. export const instance = nodeProxy( InstanceNode );
  43. addNodeClass( 'InstanceNode', InstanceNode );