Can I use a Material Array for ShaderMaterial and SphereGeometry?

Can I use a Material Array for ShaderMaterial?

The BoxBufferGeometry used a material array for Skybox.
just like :

let envMap = new THREE.CubeTextureLoader()
.setPath('images/skybox/')
.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
let cubeShader = THREE.ShaderLib['cube'];
cubeShader.uniforms['tCube'].value = envMap;

        let skyBoxMaterial = new THREE.ShaderMaterial({
            fragmentShader: cubeShader.fragmentShader,
            vertexShader: cubeShader.vertexShader,
            uniforms: cubeShader.uniforms,
            side: THREE.BackSide
        });

        var skyBox = new THREE.Mesh(new THREE.BoxBufferGeometry(1000, 1000, 1000), skyBoxMaterial);
        scene.add(skyBox);

If I use the THREE.SphereBufferGeometry or THREE.SphereGeometry with a material array.
How can I do?
1、load the material array to a big Canvas?
2、use UVs mapping?

You can use an array of materials if your instance of BufferGeometry has defined group data. That said, any type of material including ShaderMaterial or RawShaderMaterial can be used in this context.

Unlike BoxBufferGeometry, SphereBufferGeometry does not create any groups so it’s not possible to apply multiple materials to it. You have to generate group data by yourself or your create a sphere mesh with multiple materials in Blender, export the 3D model to glTF and then load it into your app.

Thanks for your reply!

I want create the skybox with a SphereGeometry and some Big Size Image.

The Big Size Image can not be load ,so I split one Big Size Image to 32 images.

I create a SphereGeometry and a material array ,

set the

let geometry = new THREE.SphereGeometry(500,32,16);

// ...

geometry.faces[faceNum].materialIndex = materialNum;
geometry.faceVertexUvs[0][faceNum] = [uvArray0[ux + 0], uvArray1[ux + 0], uvArray1[ux + 1]];

then

I can create THREE.Mesh object .

mesh = new THREE.Mesh(geometry, materials);

If I change the material array for the mesh, the page update slowly and with empty dack.

So I want use ShaderMaterial . I can load two or three materialarrays and push them to the ShaderMaterial uniforms, but only one of the them is the ActiveTexture .

   var uniforms = {
                                 ActiveTexture : {
                                     type: "t",
                                     value: matArray1
                                 },
                                 texture0: {
                                     type: "t",
                                     value: matArray2
                                 },
                                 texture1: {
                                     type: "t",
                                     value: matArray3
                                 }

}

When I change the mesh material by button ClickEvent, I can set the ShaderMaterial ActiveTexture.

But it dose not work!!!

If I use the three images for the uniforms as follow ,it can work well.

var textureLoader = new THREE.TextureLoader();

 var uniforms2 = {
                                 ActiveTexture : {
                                     type: "t",
                                     value: textureLoader.load(imgUrl)
                                 },
                                 texture0: {
                                     type: "t",
                                     value:textureLoader.load(imgUrl2)
                                 },
                                 texture1: {
                                     type: "t",
                                     value: textureLoader.load(imgUrl3)
                                 }

}

I think that should be some error in the “x-fragment”. But I do not know how to modify it .

Please create a live example to demonstrate the issue. It’s not clear from your code what you are trying to achieve.

I’m afraid it makes no sense to assign a material array to a uniform. BTW: Specifying the uniform type (e.g. type: "t") is not necessary anymore.