[SOLVED] Dynamic texture creation

Hi. When loading the game, I make a request to the server and get the URL of the link to the images. Next, I need to use these images as textures for primitives. Do I understand correctly that the algorithm of my actions is as follows: create a new material for each image, upload the image, use the image as a diffuse in the material, apply the material to the image? If this is the optimal algorithm, you can write an example code to load new images and create material in the script, because I am still not familiar with the methods. Thank you in advance!

Hi @sergey_ch,

Yes, you got it right, in more detail the flow would be:

  1. Create an Image element and add the remote file as source
  2. When the image has loaded create a pc.Texture and set the image as source
  3. Create a pc.StandardMaterial and add the pc.Texture from the previous step as a map in a channel
  4. Apply the material to one or more mesh instances.

The video texture tutorial does this, with the only difference instead of a browser Image element it creates a Video element:

https://developer.playcanvas.com/en/tutorials/video-textures/

1 Like

thank you for the detailed answer. If you don’t mind, please comment on a few points

  1. Create an Image element and add the remote file as source
  const img = document.createElement('img')
 img.src = 'https://stihi.ru/pics/2016/05/02/983.jpg'
  1. When the image has loaded create a pc.Texture and set the image as source
const texture = new pc.Texture(this.app.graphicsDevice,{})
 texture.setSource(img)
  1. Create a pc.StandardMaterial and add the pc.Texture from the previous step as a map in a channel
  2. Apply the material to one or more mesh instances.
    tell me how to do this in the code, please

I wrote it like this, but it didn’t work

         const pcMaterial = new pc.StandardMaterial()
         pcMaterial.diffuse = texture
        newEl.model.materialAsset = pcMaterial

This engine example should help: http://playcanvas.github.io/#graphics/model-textured-box.html

Line of interest: https://github.com/playcanvas/playcanvas.github.io/blob/master/graphics/model-textured-box.html#L91

Here is a script I just wrote for you:

var ServerTexture = pc.createScript('serverTexture');

ServerTexture.attributes.add('serverTextures', {
    type: 'json',
    array: true,
    schema: [{
        name: 'url',
        type: 'string'
    }, {
        name: 'material',
        type: 'asset',
        assetType: 'material'
    }, {
        name: 'materialProperty',
        type: 'number',
        enum: [
            { 'Diffuse Map': 0 },
            { 'Emissive Map': 1 }
        ]
    }]
});

// initialize code called once per entity
ServerTexture.prototype.initialize = function() {
    this.serverTextures.forEach(function (serverTexture) {
        var image = new Image();
        image.crossOrigin = 'anonymous'; // This is critical when loading image from a different domain

        image.onload = function () {
            var texture = new pc.Texture(this.app.graphicsDevice, {
                magFilter: pc.FILTER_LINEAR,
                minFilter: pc.FILTER_LINEAR
            });
            texture.setSource(image);

            var mapNames = [ 'diffuseMap', 'emissiveMap' ];
            var mapName = mapNames[serverTexture.materialProperty];
            var material = serverTexture.material.resource;
            material[mapName] = texture;
            material.update();
        }.bind(this);
        image.src = serverTexture.url;
    }, this);
};

Here’s that script working in the Editor:

I’m using it to load this image from GitHub:

(The URL is https://raw.githubusercontent.com/playcanvas/editor/master/images/editor.png)

3 Likes