BatchNode.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { normalLocal } from './NormalNode.js';
  3. import { positionLocal } from './PositionNode.js';
  4. import { nodeProxy, vec3, mat3, mat4, int, ivec2, float } from '../shadernode/ShaderNode.js';
  5. import { textureLoad } from './TextureNode.js';
  6. import { textureSize } from './TextureSizeNode.js';
  7. import { Float32BufferAttribute } from 'three';
  8. import { bufferAttribute } from './BufferAttributeNode.js';
  9. import { tangentLocal } from './TangentNode.js';
  10. class BatchNode extends Node {
  11. constructor( batchMesh ) {
  12. super( 'void' );
  13. this.batchMesh = batchMesh;
  14. this.instanceColorNode = null;
  15. this.batchingIdNode = null;
  16. }
  17. setup( builder ) {
  18. // POSITION
  19. if ( this.batchingIdNode === null ) {
  20. const batchingAttribute = this.batchMesh.geometry.getAttribute( 'batchId' );
  21. const array = new Float32Array( batchingAttribute.array );
  22. const buffer = new Float32BufferAttribute( array, 1 );
  23. this.batchingIdNode = bufferAttribute( buffer, 'float' ).toVar();
  24. }
  25. const matriceTexture = this.batchMesh._matricesTexture;
  26. const size = textureSize( textureLoad( matriceTexture ), 0 );
  27. const j = float( int( this.batchingIdNode ) ).mul( 4 ).toVar();
  28. const x = int( j.mod( size ) );
  29. const y = int( j ).div( int( size ) );
  30. const batchingMatrix = mat4(
  31. textureLoad( matriceTexture, ivec2( x, y ) ),
  32. textureLoad( matriceTexture, ivec2( x.add( 1 ), y ) ),
  33. textureLoad( matriceTexture, ivec2( x.add( 2 ), y ) ),
  34. textureLoad( matriceTexture, ivec2( x.add( 3 ), y ) )
  35. );
  36. const bm = mat3(
  37. batchingMatrix[ 0 ].xyz,
  38. batchingMatrix[ 1 ].xyz,
  39. batchingMatrix[ 2 ].xyz
  40. );
  41. positionLocal.assign( batchingMatrix.mul( positionLocal ) );
  42. const transformedNormal = normalLocal.div( vec3( bm[ 0 ].dot( bm[ 0 ] ), bm[ 1 ].dot( bm[ 1 ] ), bm[ 2 ].dot( bm[ 2 ] ) ) );
  43. const batchingNormal = bm.mul( transformedNormal ).xyz;
  44. normalLocal.assign( batchingNormal );
  45. if ( builder.hasGeometryAttribute( 'tangent' ) ) {
  46. tangentLocal.mulAssign( bm );
  47. }
  48. }
  49. }
  50. export default BatchNode;
  51. export const batch = nodeProxy( BatchNode );
  52. addNodeClass( 'batch', BatchNode );