Texture.offset is shared by all material?

I want to make some light effect, as the post FBX keyframe animation support? here said, the fbx is not work. so I achieve it manualy.
The parent mesh object has for child, 01,02,03,04, they use the same material lightMat, which use a texture light.png, half of this picture is black and half is bright, so I change the texture.offset to 0.5/0 to achieve light on/off, this is my code:

            for(var i=0; i< 4; ++i) {
                var child = this.childrenObj[i]
                var texture = child.material.map
                if(i< nFlash) {
                    texture.offset.x = 0.5;
                else {
                    texture.offset.x = 0;
                texture.needsUpdate = true;
                // child.material.needsUpdate = true;

But it seem if I change one child’s texure offset , another three material 's texture 's offset will also be changed
I know in unity, there is .material and .sharedMaterial, but it do not exist in three.js

Create new material do not work event

        var textureLoader = new THREE.TextureLoader();
        this.childrenObj = [];
        var self = this;
        var texture1 = textureLoader.load(imgName, function(texture) {
            for(var i=0; i< children.length; ++i) {
                var child = self.meshObj.getObjectByName(children[i])
                child.material = new THREE.MeshBasicMaterial({map: texture})
                child.material.needsUpdate = true;


Using different materials won’t solve the issue since offset is a property of Texture. If you want different texture settings for your materials, you have to clone the texture object itself.

I tried clone the texture, but it do not work , maybe I do something wrong, or it is just a shadow copy?
But in final I created extra texture using the same image, solved this problem

Only the internal image object and mipmaps are shared but not texture properties like offset.

                outer = object.getObjectByName("Object001")
				outer.material.transparent = true;
				outer.material.needsUpdate = true;

				inner = object.getObjectByName("xs_box003")
				var newMat = outer.material.clone();
				inner.material.transparent = true;
				inner.material.needsUpdate = true;

  function render() {
				var dt = clock.getDelta();
				renderer.render( scene, camera );

			if(outer) {
				outer.material.opacity -= 0.1 * dt;
				outer.material.needsUpdate = true;
			if(inner) {

				inner.material.opacity += 0.1 * dt;
				inner.material.needsUpdate = true;
				console.log(outer.material.opacity)       // Note here, print outer, not inner


This is my another code, I copy the origin material and assign to inner mesh, but in render loop, the opacity property shared, so it never be down to 0.

This is wrong. You just do:

inner.material = outer.material.clone();
1 Like