InstanceNode.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { instanceIndex } from '../core/InstanceIndexNode.js';
  3. import { temp } from '../core/VarNode.js';
  4. import { buffer } from './BufferNode.js';
  5. import { normalLocal } from './NormalNode.js';
  6. import { positionLocal } from './PositionNode.js';
  7. import { nodeProxy, vec3, mat3 } from '../shadernode/ShaderNode.js';
  8. class InstanceNode extends Node {
  9. constructor( instanceMesh ) {
  10. super( 'void' );
  11. this.instanceMesh = instanceMesh;
  12. //
  13. const instanceBufferNode = buffer( instanceMesh.instanceMatrix.array, 'mat4', instanceMesh.count );
  14. this.instanceMatrixNode = temp( instanceBufferNode.element( instanceIndex ) ); // @TODO: a possible caching issue here?
  15. }
  16. generate( builder ) {
  17. const { instanceMatrixNode } = this;
  18. // POSITION
  19. const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
  20. // NORMAL
  21. const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
  22. const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
  23. const instanceNormal = m.mul( transformedNormal ).xyz;
  24. // ASSIGNS
  25. positionLocal.assign( instancePosition ).build( builder );
  26. normalLocal.assign( instanceNormal ).build( builder );
  27. }
  28. }
  29. export default InstanceNode;
  30. export const instance = nodeProxy( InstanceNode );
  31. addNodeClass( InstanceNode );