How do I update node-material uniforms?

I finally want to understand the 3js node system a little better and for that I made this very small example. That works so far.

const textureLoader = new THREE.TextureLoader();
const uvTexture = textureLoader.load( '../resources/textures/uv_grid_opengl.jpg' );				

this.dt = 0.01;

const params = {
	uvTex: texture( uvTexture ),
	time: uniform(this.dt),
}

const customShaderNode = tslFn( ( input ) => {

	let finalColor = input.uvTex.xyz;			
	return finalColor.mul(input.time);
});

let material = new MeshBasicNodeMaterial();
material.colorNode = customShaderNode( params );			
		

const geometry = new THREE.BoxGeometry();
this.cube = new THREE.Mesh(geometry, material);
this.scene_.add(this.cube);

But what I can’t figure out is how to do a node uniform update. Normally this is simply done with:

this.cube.material.uniforms.time.value += this.dt;
this.cube.material.uniformsNeedUpdate = true;

But I don’t see the node uniform “time” in the material uniforms. With this very small example, I’m just trying to understand how I change a uniform variable. I appreciate advice

1 Like

I encountered the very same issue, and sunag kindly disclosed the process.

import { uniform, MeshBasicNodeMaterial } from "three/examples/jsm/nodes/Nodes.js";

const myUniform = uniform( 1 ); // you can put number, Vector*, Color  and others

const nodeMaterial = new MeshBasicNodeMaterial();
nodeMaterial.colorNode = myUniform;

// changing
//myUniform.value = .5;
4 Likes

I wouldn’t have thought of that because you can’t actually change const values ​​like this. But I’m so happy right now. I’ve been stuck with this for a while.
I have now done it in such a way that if you want to change many uniforms, you don’t just have individual uniforms flying around freely in the code, but can bundle them into a material parameter set for a specific material.

const textureLoader = new THREE.TextureLoader();
const uvTexture = textureLoader.load( '../resources/textures/uv_grid_opengl.jpg' );				

this.dt = 0.01;

this.materialParams = {
	uvTex: texture( uvTexture ),
	time: uniform(this.dt),
}

const customShaderNode = tslFn( ( input ) => {

	let finalColor = input.uvTex.xyz;			
	return finalColor.mul(input.time);
});

let material = new MeshBasicNodeMaterial();
material.colorNode = customShaderNode( this.materialParams );			
		
const geometry = new THREE.BoxGeometry();
this.cube = new THREE.Mesh(geometry, material);
this.scene_.add(this.cube);

And in the update function that I call in the render loop:

this.materialParams.time.value += this.dt;

Next I will deal with node attributes but I will ask a new question. You have answered this one in full and I think that will help many.

2 Likes