| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import BufferNode from './BufferNode.js';
- import { bufferAttribute } from './BufferAttributeNode.js';
- import { nodeObject, varying } from '../tsl/TSLBase.js';
- import { storageElement } from '../utils/StorageArrayElementNode.js';
- import { NodeAccess } from '../core/constants.js';
- import { getTypeFromLength } from '../core/NodeUtils.js';
- class StorageBufferNode extends BufferNode {
- static get type() {
- return 'StorageBufferNode';
- }
- constructor( value, bufferType = null, bufferCount = 0 ) {
- if ( bufferType === null && ( value.isStorageBufferAttribute || value.isStorageInstancedBufferAttribute ) ) {
- bufferType = getTypeFromLength( value.itemSize );
- bufferCount = value.count;
- }
- super( value, bufferType, bufferCount );
- this.isStorageBufferNode = true;
- this.access = NodeAccess.READ_WRITE;
- this.isAtomic = false;
- this.bufferObject = false;
- this.bufferCount = bufferCount;
- this._attribute = null;
- this._varying = null;
- this.global = true;
- if ( value.isStorageBufferAttribute !== true && value.isStorageInstancedBufferAttribute !== true ) {
- // TOOD: Improve it, possibly adding a new property to the BufferAttribute to identify it as a storage buffer read-only attribute in Renderer
- if ( value.isInstancedBufferAttribute ) value.isStorageInstancedBufferAttribute = true;
- else value.isStorageBufferAttribute = true;
- }
- }
- getHash( builder ) {
- if ( this.bufferCount === 0 ) {
- let bufferData = builder.globalCache.getData( this.value );
- if ( bufferData === undefined ) {
- bufferData = {
- node: this
- };
- builder.globalCache.setData( this.value, bufferData );
- }
- return bufferData.node.uuid;
- }
- return this.uuid;
- }
- getInputType( /*builder*/ ) {
- return this.value.isIndirectStorageBufferAttribute ? 'indirectStorageBuffer' : 'storageBuffer';
- }
- element( indexNode ) {
- return storageElement( this, indexNode );
- }
- setBufferObject( value ) {
- this.bufferObject = value;
- return this;
- }
- setAccess( value ) {
- this.access = value;
- return this;
- }
- toReadOnly() {
- return this.setAccess( NodeAccess.READ_ONLY );
- }
- setAtomic( value ) {
- this.isAtomic = value;
- return this;
- }
- toAtomic() {
- return this.setAtomic( true );
- }
- getAttributeData() {
- if ( this._attribute === null ) {
- this._attribute = bufferAttribute( this.value );
- this._varying = varying( this._attribute );
- }
- return {
- attribute: this._attribute,
- varying: this._varying
- };
- }
- getNodeType( builder ) {
- if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
- return super.getNodeType( builder );
- }
- const { attribute } = this.getAttributeData();
- return attribute.getNodeType( builder );
- }
- generate( builder ) {
- if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
- return super.generate( builder );
- }
- const { attribute, varying } = this.getAttributeData();
- const output = varying.build( builder );
- builder.registerTransform( output, attribute );
- return output;
- }
- }
- export default StorageBufferNode;
- // Read-Write Storage
- export const storage = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ) );
- export const storageObject = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ).setBufferObject( true ) );
|