将 Perlin 噪声着色器仅应用于网格内的某些对象
Applying Perlin noise shader just to some objects within a mesh
我想使用柏林噪声修改网格中的一个对象。我现在是怎么做到的...
我正在创建对象并将它们添加到 3d 对象...
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);
我正在使用着色器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
});
着色器 material 适用于所有 40 个球,没问题。我想做的是改变 spheres.children[0]
的着色器。是否可以更改一个对象的 perlin 噪声值 (noiseMax),或者它是否会自然地影响使用 material 的所有对象的 material?
你有几个选择。
简单的方法是为每个不同的项目创建和使用一个单独的 ShaderMaterial,并且您可以轻松地设置其统一。例如
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;
或者,可能更适合您的情况(至少从性能的角度来看)是您应该将 noisemax 更改为 attribute,这样您就可以为每个对象设置一个单独的值.
您必须记住属性是每个顶点的,因此您需要复制属于每个对象的所有顶点的值。这会使事情变得有点复杂。
编辑:要减少内存使用,您可以使用THREE.InstancedBufferGeometry with THREE.InstancedBufferAttribute
我想使用柏林噪声修改网格中的一个对象。我现在是怎么做到的...
我正在创建对象并将它们添加到 3d 对象...
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);
我正在使用着色器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 });
着色器 material 适用于所有 40 个球,没问题。我想做的是改变 spheres.children[0]
的着色器。是否可以更改一个对象的 perlin 噪声值 (noiseMax),或者它是否会自然地影响使用 material 的所有对象的 material?
你有几个选择。
简单的方法是为每个不同的项目创建和使用一个单独的 ShaderMaterial,并且您可以轻松地设置其统一。例如
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;
或者,可能更适合您的情况(至少从性能的角度来看)是您应该将 noisemax 更改为 attribute,这样您就可以为每个对象设置一个单独的值.
您必须记住属性是每个顶点的,因此您需要复制属于每个对象的所有顶点的值。这会使事情变得有点复杂。
编辑:要减少内存使用,您可以使用THREE.InstancedBufferGeometry with THREE.InstancedBufferAttribute