2
\$\begingroup\$

I've been doing some reading and can't seem to figure out a good way to do this..

I have a simple globe with a material on it like so:

const earthGeomerty = new THREE.SphereGeometry( 4, 48, 48 );
const earthDiffuse = loader.load('assets/drought_earth_texture.png');
const earthSpec = loader.load('assets/drought_earth_texture_bump.png');

const material = new THREE.MeshPhongMaterial( {
    specular: 0xffffff,
    map: earthDiffuse,
    specularMap: earthSpec,
    normalScale: new THREE.Vector2( 1, 1 ),
    shininess: 5,
    transparent: true,
    depthTest: true,
    depthWrite: false,
    polygonOffset: true,
    polygonOffsetFactor: - 4,
    wireframe: false
} );

and I apply this material to my earthGeometry like so:

const sphere = new THREE.Mesh( earthGeomerty, material );

but now I want to add an atmospheric glow, which I found a nice extension for and created like so:

const atmosphereMaterial = THREEx.createAtmosphereMaterial();

but after doing a ton of reading I'm unsure of how to use both material and atmosphereMaterial to my single sphere mesh.

Any help? Thanks!

\$\endgroup\$
1

2 Answers 2

3
\$\begingroup\$

You can have multiple materials in one mesh in Three.js. Supply an array of materials to the Mesh constructor instead of a single material. You then also have to specify vertex groups in the geometry. If you want, you can specify the groups to contain the same vertices, only different material index.

It is also possible to define multiple meshes using the same geometry, but unique materials. You can organize the meshes as children of a THREE.Group.

\$\endgroup\$
2
\$\begingroup\$

First there's a problem with your code, you should use callbacks when using a TextureLoader, and with multiple textures you should use Promises, with your code you are not waiting for textures to load and your material will not work.

But after doing a ton of reading I'm unsure of how to use both material and atmosphereMaterial to my single sphere mesh.

In short you can't add two materials to the same mesh using Three.js, materials are coupled vertex fragment shaders and geometries are arrays of vector positions.

You can use a custom material using ShaderMaterial so you can create a custom shader that combine the two effects, then you can apply the material to a mesh.

Or you can simply use two meshes and bind them to a parent Object3D.

Something like this:

var earthObj = new THREE.Object3D();

var sphereMesh = new THREE.Mesh(geometry, material);

earthObj.add(sphereMesh);

var atmosphereMaterial = THREEx.createAtmosphereMaterial();

earthObj.add(atmosphereMaterial);

It is important to know that child meshes will get the origin from their parents. Every translation, rotation is intended related to the parent mesh position, which make a lot of sense for building complex objects with multiple meshes.

I made an example a while ago about using multiple textures and multiple meshes.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .