InstanceNode.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { varyingProperty } from '../core/PropertyNode.js';
  3. import { instancedBufferAttribute, instancedDynamicBufferAttribute } from './BufferAttributeNode.js';
  4. import { normalLocal } from './NormalNode.js';
  5. import { positionLocal } from './PositionNode.js';
  6. import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
  7. import { DynamicDrawUsage, InstancedInterleavedBuffer, InstancedBufferAttribute } from 'three';
  8. class InstanceNode extends Node {
  9. constructor( instanceMesh ) {
  10. super( 'void' );
  11. this.instanceMesh = instanceMesh;
  12. this.instanceMatrixNode = null;
  13. this.instanceColorNode = null;
  14. }
  15. setup( /*builder*/ ) {
  16. let instanceMatrixNode = this.instanceMatrixNode;
  17. const instanceMesh = this.instanceMesh;
  18. if ( instanceMatrixNode === null ) {
  19. const instanceAttribute = instanceMesh.instanceMatrix;
  20. const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
  21. const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
  22. const instanceBuffers = [
  23. // F.Signature -> bufferAttribute( array, type, stride, offset )
  24. bufferFn( buffer, 'vec4', 16, 0 ),
  25. bufferFn( buffer, 'vec4', 16, 4 ),
  26. bufferFn( buffer, 'vec4', 16, 8 ),
  27. bufferFn( buffer, 'vec4', 16, 12 )
  28. ];
  29. instanceMatrixNode = mat4( ...instanceBuffers );
  30. this.instanceMatrixNode = instanceMatrixNode;
  31. }
  32. const instanceColorAttribute = instanceMesh.instanceColor;
  33. if ( instanceColorAttribute && this.instanceColorNode === null ) {
  34. const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
  35. const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
  36. this.instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
  37. }
  38. // POSITION
  39. const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
  40. // NORMAL
  41. const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
  42. const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
  43. const instanceNormal = m.mul( transformedNormal ).xyz;
  44. // ASSIGNS
  45. positionLocal.assign( instancePosition );
  46. normalLocal.assign( instanceNormal );
  47. // COLOR
  48. if ( this.instanceColorNode !== null ) {
  49. varyingProperty( 'vec3', 'vInstanceColor' ).assign( this.instanceColorNode );
  50. }
  51. }
  52. }
  53. export default InstanceNode;
  54. export const instance = nodeProxy( InstanceNode );
  55. addNodeClass( 'InstanceNode', InstanceNode );