95 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import Node, { addNodeClass } from '../core/Node.js';
 | |
| import { varyingProperty } from '../core/PropertyNode.js';
 | |
| import { instancedBufferAttribute, instancedDynamicBufferAttribute } from './BufferAttributeNode.js';
 | |
| import { normalLocal } from './NormalNode.js';
 | |
| import { positionLocal } from './PositionNode.js';
 | |
| import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
 | |
| import { DynamicDrawUsage, InstancedInterleavedBuffer, InstancedBufferAttribute } from 'three';
 | |
| 
 | |
| class InstanceNode extends Node {
 | |
| 
 | |
| 	constructor( instanceMesh ) {
 | |
| 
 | |
| 		super( 'void' );
 | |
| 
 | |
| 		this.instanceMesh = instanceMesh;
 | |
| 
 | |
| 		this.instanceMatrixNode = null;
 | |
| 
 | |
| 		this.instanceColorNode = null;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	setup( /*builder*/ ) {
 | |
| 
 | |
| 		let instanceMatrixNode = this.instanceMatrixNode;
 | |
| 
 | |
| 		const instanceMesh = this.instanceMesh;
 | |
| 
 | |
| 		if ( instanceMatrixNode === null ) {
 | |
| 
 | |
| 			const instanceAttribute = instanceMesh.instanceMatrix;
 | |
| 			const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
 | |
| 
 | |
| 			const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
 | |
| 
 | |
| 			const instanceBuffers = [
 | |
| 				// F.Signature -> bufferAttribute( array, type, stride, offset )
 | |
| 				bufferFn( buffer, 'vec4', 16, 0 ),
 | |
| 				bufferFn( buffer, 'vec4', 16, 4 ),
 | |
| 				bufferFn( buffer, 'vec4', 16, 8 ),
 | |
| 				bufferFn( buffer, 'vec4', 16, 12 )
 | |
| 			];
 | |
| 
 | |
| 			instanceMatrixNode = mat4( ...instanceBuffers );
 | |
| 
 | |
| 			this.instanceMatrixNode = instanceMatrixNode;
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		const instanceColorAttribute = instanceMesh.instanceColor;
 | |
| 
 | |
| 		if ( instanceColorAttribute && this.instanceColorNode === null ) {
 | |
| 
 | |
| 			const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
 | |
| 			const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
 | |
| 
 | |
| 			this.instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		// POSITION
 | |
| 
 | |
| 		const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
 | |
| 
 | |
| 		// NORMAL
 | |
| 
 | |
| 		const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
 | |
| 
 | |
| 		const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
 | |
| 
 | |
| 		const instanceNormal = m.mul( transformedNormal ).xyz;
 | |
| 
 | |
| 		// ASSIGNS
 | |
| 
 | |
| 		positionLocal.assign( instancePosition );
 | |
| 		normalLocal.assign( instanceNormal );
 | |
| 
 | |
| 		// COLOR
 | |
| 
 | |
| 		if ( this.instanceColorNode !== null ) {
 | |
| 
 | |
| 			varyingProperty( 'vec3', 'vInstanceColor' ).assign( this.instanceColorNode );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| export default InstanceNode;
 | |
| 
 | |
| export const instance = nodeProxy( InstanceNode );
 | |
| 
 | |
| addNodeClass( 'InstanceNode', InstanceNode );
 |