tslFn - how to update things after compute?

Time to answer my own question. I know now what i need to do, to get updates, but i don’t fully understand why. For anyone, who hits the same wall, here is updated code, that should work:

import * as THREE from 'three';
import { tslFn, storage, vec3, instanceIndex, uniform } from 'three/nodes';
import { oscSine, timerLocal} from 'three/nodes';

import StorageBufferAttribute from 'three/addons/renderers/common/StorageBufferAttribute.js';

const powerFn = tslFn ( ({ color, x } ) => {
	const colorSingle = color.element( instanceIndex );
	colorSingle.assign(vec3(oscSine(x), 0, 0));
});
	
function doIt( mesh, renderer ){
	const positionBaseAttribute = mesh.geometry.attributes.position;
	
	if(!mesh.userData.powerFn) {
		
		// this should be created only once in my case. 
		// It seems thath binding another StorageBufferAttribute to color makes it unaccessible, like it holds an old reference, 
		// or it needs to be explicitly updated, just like `x` below
		const colorStorageBufferAttribute = new StorageBufferAttribute(  positionBaseAttribute.count, 3 ); 
		
		mesh.geometry.setAttribute( 'color', colorStorageBufferAttribute );
		
		mesh.userData.powerFn = powerFn( {
			
			color:  storage( colorStorageBufferAttribute, 'vec3', colorStorageBufferAttribute.count ),
			// x will be updated automatically, if it's passed by reference, not value. so objects arrays and propably storage() will be updated on the go
			x: Math.random() 
			
		} );
			
	} else {
		
		// there could be better way to update things
		mesh.userData.powerFn.inputNodes.x.value = Math.random(); 
		
		// for good measure
		mesh.userData.powerFn.needsUpdate = true;
	}

	// compute every time
	renderer.computeAsync( mesh.userData.powerFn.compute( positionBaseAttribute.count ) );
	
	mesh.material.vertexColors = mesh.material.needsUpdate = true;
	
}
2 Likes