StorageBufferNode.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import BufferNode from './BufferNode.js';
  2. import { bufferAttribute } from './BufferAttributeNode.js';
  3. import { nodeObject, varying } from '../tsl/TSLBase.js';
  4. import { storageElement } from '../utils/StorageArrayElementNode.js';
  5. import { NodeAccess } from '../core/constants.js';
  6. import { getTypeFromLength } from '../core/NodeUtils.js';
  7. class StorageBufferNode extends BufferNode {
  8. static get type() {
  9. return 'StorageBufferNode';
  10. }
  11. constructor( value, bufferType = null, bufferCount = 0 ) {
  12. if ( bufferType === null && ( value.isStorageBufferAttribute || value.isStorageInstancedBufferAttribute ) ) {
  13. bufferType = getTypeFromLength( value.itemSize );
  14. bufferCount = value.count;
  15. }
  16. super( value, bufferType, bufferCount );
  17. this.isStorageBufferNode = true;
  18. this.access = NodeAccess.READ_WRITE;
  19. this.isAtomic = false;
  20. this.bufferObject = false;
  21. this.bufferCount = bufferCount;
  22. this._attribute = null;
  23. this._varying = null;
  24. this.global = true;
  25. if ( value.isStorageBufferAttribute !== true && value.isStorageInstancedBufferAttribute !== true ) {
  26. // TOOD: Improve it, possibly adding a new property to the BufferAttribute to identify it as a storage buffer read-only attribute in Renderer
  27. if ( value.isInstancedBufferAttribute ) value.isStorageInstancedBufferAttribute = true;
  28. else value.isStorageBufferAttribute = true;
  29. }
  30. }
  31. getHash( builder ) {
  32. if ( this.bufferCount === 0 ) {
  33. let bufferData = builder.globalCache.getData( this.value );
  34. if ( bufferData === undefined ) {
  35. bufferData = {
  36. node: this
  37. };
  38. builder.globalCache.setData( this.value, bufferData );
  39. }
  40. return bufferData.node.uuid;
  41. }
  42. return this.uuid;
  43. }
  44. getInputType( /*builder*/ ) {
  45. return this.value.isIndirectStorageBufferAttribute ? 'indirectStorageBuffer' : 'storageBuffer';
  46. }
  47. element( indexNode ) {
  48. return storageElement( this, indexNode );
  49. }
  50. setBufferObject( value ) {
  51. this.bufferObject = value;
  52. return this;
  53. }
  54. setAccess( value ) {
  55. this.access = value;
  56. return this;
  57. }
  58. toReadOnly() {
  59. return this.setAccess( NodeAccess.READ_ONLY );
  60. }
  61. setAtomic( value ) {
  62. this.isAtomic = value;
  63. return this;
  64. }
  65. toAtomic() {
  66. return this.setAtomic( true );
  67. }
  68. getAttributeData() {
  69. if ( this._attribute === null ) {
  70. this._attribute = bufferAttribute( this.value );
  71. this._varying = varying( this._attribute );
  72. }
  73. return {
  74. attribute: this._attribute,
  75. varying: this._varying
  76. };
  77. }
  78. getNodeType( builder ) {
  79. if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
  80. return super.getNodeType( builder );
  81. }
  82. const { attribute } = this.getAttributeData();
  83. return attribute.getNodeType( builder );
  84. }
  85. generate( builder ) {
  86. if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
  87. return super.generate( builder );
  88. }
  89. const { attribute, varying } = this.getAttributeData();
  90. const output = varying.build( builder );
  91. builder.registerTransform( output, attribute );
  92. return output;
  93. }
  94. }
  95. export default StorageBufferNode;
  96. // Read-Write Storage
  97. export const storage = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ) );
  98. export const storageObject = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ).setBufferObject( true ) );
粤ICP备19079148号