[SOLVED] Runtime Generated Textures Scope polution

The Problem

Im trying to create entities at runtime and assign a “canvas text” texture to them.
But some reason all the elements end up having the same texture.

Example

https://playcanvas.com/project/487854/overview/texturetroubles

Creating the Entities

ObjectSpawner.prototype.spawn = function () {
    
    
    for(var i = 0; i < 10; i++) {
  
        var entity = new pc.Entity("my-name-" + i);

        entity.addComponent("model", {
            type: "plane"
        });
        
        
        entity.model.material = this.app.assets.find("Blue").resource;
        
        entity.setLocalScale(1, 1, 1);
        entity.setLocalPosition (
            pc.math.random(-this.boxDimensions, this.boxDimensions),
            pc.math.random(-this.boxDimensions, this.boxDimensions),
            pc.math.random(-this.boxDimensions, this.boxDimensions)
        );

 
    
        entity.addComponent("script");        
        entity.script.create("text", {    
            attributes: {
              text: "hello " + i
            }
        });

        this.app.root.addChild(entity);
        this.entities.push(entity);
    
    }
};

Creating the text

var canvas = document.createElement('canvas');
    canvas.setAttribute("id", this.entity.name);
    canvas.height   = 128;
    canvas.width   =  512;
    
    var ctx = canvas.getContext("2d");    

    this.texture = new pc.Texture(this.app.graphicsDevice, {
        format: pc.PIXELFORMAT_R8_G8_B8_A8,
        autoMipmap: true
    });
    
    this.texture.setSource(canvas);
    
    this.texture.minFilter = pc.FILTER_LINEAR_MIPMAP_LINEAR;
    this.texture.magFilter = pc.FILTER_LINEAR;
    this.texture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
    this.texture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;
    
    
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;

    ctx.fillStyle = "white";
    ctx.font = 'bold 70px Verdana';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(this.entity.name, w / 2, h / 2);
    this.texture.upload();
    
    
    console.log(this.entity.name);
    
    this.entity.model.material.emissiveMap = this.texture;
    this.entity.model.material.opacityMap = this.texture;
    this.entity.model.material.blendType = pc.BLEND_NORMAL;
    this.entity.model.material.update();
};

The result

Should all be uniq, but they all say my-name-9 ?

They’re the same because all the models share the same material and you’re just changing properties of the same material… You need to make a new material for each model. You could call material.clone() to get back a copy of a material if you want.

Thx for responding,

So i changed this line:

entity.model.material = this.app.assets.find("Blue").resource;

To

entity.model.material = this.app.assets.find("Blue").resource.clone();

And now it workes :slight_smile:

Thanks