UniformsNode.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { addNodeClass } from '../core/Node.js';
  2. import { nodeObject } from '../shadernode/ShaderNode.js';
  3. import { NodeUpdateType } from '../core/constants.js';
  4. import { getValueType } from '../core/NodeUtils.js';
  5. import ArrayElementNode from '../utils/ArrayElementNode.js';
  6. import BufferNode from './BufferNode.js';
  7. class UniformsElementNode extends ArrayElementNode {
  8. constructor( arrayBuffer, indexNode ) {
  9. super( arrayBuffer, indexNode );
  10. this.isArrayBufferElementNode = true;
  11. }
  12. getNodeType( builder ) {
  13. return this.node.getElementType( builder );
  14. }
  15. generate( builder ) {
  16. const snippet = super.generate( builder );
  17. const type = this.getNodeType();
  18. return builder.format( snippet, 'vec4', type );
  19. }
  20. }
  21. class UniformsNode extends BufferNode {
  22. constructor( value, elementType = null ) {
  23. super( null, 'vec4' );
  24. this.array = value;
  25. this.elementType = elementType;
  26. this._elementType = null;
  27. this._elementLength = 0;
  28. this.updateType = NodeUpdateType.RENDER;
  29. this.isArrayBufferNode = true;
  30. }
  31. getElementType() {
  32. return this.elementType || this._elementType;
  33. }
  34. getElementLength() {
  35. return this._elementLength;
  36. }
  37. update( /*frame*/ ) {
  38. const { array, value } = this;
  39. const elementLength = this.getElementLength();
  40. const elementType = this.getElementType();
  41. if ( elementLength === 1 ) {
  42. for ( let i = 0; i < array.length; i ++ ) {
  43. const index = i * 4;
  44. value[ index ] = array[ i ];
  45. }
  46. } else if ( elementType === 'color' ) {
  47. for ( let i = 0; i < array.length; i ++ ) {
  48. const index = i * 4;
  49. const vector = array[ i ];
  50. value[ index ] = vector.r;
  51. value[ index + 1 ] = vector.g;
  52. value[ index + 2 ] = vector.b || 0;
  53. //value[ index + 3 ] = vector.a || 0;
  54. }
  55. } else {
  56. for ( let i = 0; i < array.length; i ++ ) {
  57. const index = i * 4;
  58. const vector = array[ i ];
  59. value[ index ] = vector.x;
  60. value[ index + 1 ] = vector.y;
  61. value[ index + 2 ] = vector.z || 0;
  62. value[ index + 3 ] = vector.w || 0;
  63. }
  64. }
  65. }
  66. setup( builder ) {
  67. const length = this.array.length;
  68. this._elementType = this.elementType === null ? getValueType( this.array[ 0 ] ) : this.elementType;
  69. this._elementLength = builder.getTypeLength( this._elementType );
  70. let arrayType = Float32Array;
  71. if ( this._elementType.charAt( 0 ) === 'i' ) arrayType = Int32Array;
  72. else if ( this._elementType.charAt( 0 ) === 'u' ) arrayType = Uint32Array;
  73. this.value = new arrayType( length * 4 );
  74. this.bufferCount = length;
  75. this.bufferType = builder.changeComponentType( 'vec4', builder.getComponentType( this._elementType ) );
  76. return super.setup( builder );
  77. }
  78. element( indexNode ) {
  79. return nodeObject( new UniformsElementNode( this, nodeObject( indexNode ) ) );
  80. }
  81. }
  82. export default UniformsNode;
  83. export const uniforms = ( values, nodeType ) => nodeObject( new UniformsNode( values, nodeType ) );
  84. addNodeClass( 'UniformsNode', UniformsNode );