RangeNode.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import Node from '../core/Node.js';
  2. import { attribute, float } from '../shadernode/ShaderNodeBaseElements.js';
  3. import { MathUtils, InstancedBufferAttribute } from 'three';
  4. class RangeNode extends Node {
  5. constructor( min, max ) {
  6. super();
  7. this.min = min;
  8. this.max = max;
  9. }
  10. getVectorLength() {
  11. const min = this.min;
  12. let length = 1;
  13. if ( min.isVector2 ) length = 2;
  14. else if ( min.isVector3 ) length = 3;
  15. else if ( min.isVector4 ) length = 4;
  16. else if ( min.isColor ) length = 3;
  17. return length;
  18. }
  19. getNodeType( builder ) {
  20. return ( builder.object.isInstancedMesh === true ) ? builder.getTypeFromLength( this.getVectorLength() ) : 'float';
  21. }
  22. construct( builder ) {
  23. const { min, max } = this;
  24. const { object, geometry } = builder;
  25. let output = null;
  26. if ( object.isInstancedMesh === true ) {
  27. const vectorLength = this.getVectorLength();
  28. const attributeName = 'node' + this.id;
  29. const length = vectorLength * object.count;
  30. const array = new Float32Array( length );
  31. const attributeGeometry = geometry.getAttribute( attributeName );
  32. if ( attributeGeometry === undefined || attributeGeometry.array.length < length ) {
  33. if ( vectorLength === 1 ) {
  34. for ( let i = 0; i < length; i ++ ) {
  35. array[ i ] = MathUtils.lerp( min, max, Math.random() );
  36. }
  37. } else if ( min.isColor ) {
  38. for ( let i = 0; i < length; i += 3 ) {
  39. array[ i ] = MathUtils.lerp( min.r, max.r, Math.random() );
  40. array[ i + 1 ] = MathUtils.lerp( min.g, max.g, Math.random() );
  41. array[ i + 2 ] = MathUtils.lerp( min.b, max.b, Math.random() );
  42. }
  43. } else {
  44. for ( let i = 0; i < length; i ++ ) {
  45. const index = i % vectorLength;
  46. const minValue = min.getComponent( index );
  47. const maxValue = max.getComponent( index );
  48. array[ i ] = MathUtils.lerp( minValue, maxValue, Math.random() );
  49. }
  50. }
  51. geometry.setAttribute( attributeName, new InstancedBufferAttribute( array, vectorLength ) );
  52. geometry.dispose();
  53. }
  54. output = attribute( attributeName, builder.getTypeFromLength( vectorLength ) );
  55. } else {
  56. output = float( 0 );
  57. }
  58. return output;
  59. }
  60. }
  61. export default RangeNode;