Reputation: 987
I would like to modify one object within a mesh using perlin noise. How I am doing this right now...
I am creating the objects and adding them to a 3d object...
spheres = new THREE.Object3D();
for ( var i = 0; i < 40; i ++ ) {
var ball = new THREE.Mesh(new THREE.SphereGeometry(20,20,20), material);
ball.position.x = Math.random() * 600 - 300;
ball.position.y = Math.random() * 600 - 300;
ball.position.z = Math.random() * 600 - 300;
spheres.add(ball);
}
scene.add(spheres);
I am using a shader material...
material = new THREE.ShaderMaterial({
uniforms: {
time: {
type: "f",
value: 0.0
},
noisemax: {
type: "f",
value: 100.0
},
transparent: true
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
});
The shader material works on all 40 balls no problem. What I would like to do is change the shader say for spheres.children[0]
. Is it possible to change the perlin noise values (noiseMax) for one object or does it by nature effect the material for all objects using the material?
Upvotes: 1
Views: 2057
Reputation: 2747
You have a couple of options.
The easy way is to create and use a separate ShaderMaterial for each item that differs, and you can set its uniform easily. e.g.
var firstMaterial = new THREE.ShaderMaterial({
uniforms: { noisemax: { type: 'f', value: 3}}
});
var secondMaterial = new THREE.ShaderMaterial({
uniforms: { noisemax: { type: 'f', value: 10}}
});
var firstBall = new THREE.Mesh(new THREE.SphereGeometry(20,20,20), firstMaterial);
var secondBall = new THREE.Mesh(new THREE.SphereGeometry(20,20,20), secondMaterial);
// or in your case
spheres.children[0].material = secondMaterial;
Alternatively and probably preferably for your situation (at least from a performance standpoint) is that you should change noisemax to an attribute, that way you can have a separate value per object.
You will have to remember that attributes are per vertex, so you'll need to duplicate the values for all vertices belonging to each object. This will complicate things a little bit.
Edit: To reduce memory usage, you can use THREE.InstancedBufferGeometry with THREE.InstancedBufferAttribute
Upvotes: 2