How to change material properties on image element?

hello all,

I’m trying to change a texture on the emissive property of a material that is used on a image element.

Not too sure how to achieve that.
trying this without success

var iconMeshInstance = this.buttonScript.iconEntity.element.material.meshInstances;

    for (let j = 0; j < iconMeshInstance.length; j++) {
        let material = iconMeshInstance[j].material;
        material.emissiveMap = texture;

any suggestions? thanks

Does it have to be the material emissive map you want to change? Can you not change the texture via element.texture?

I have a round button, so I’m using a material with opacity & emissive to have the texture apply correctly on the round button

When you apply a texture to an element, it automatically handles the alpha as opacity

But if you are already using a material, you can reference the material asset and change the maps there

If you can post an example project, that will help too

I’m trying to have a round corner square button that as a shadow, button should have that blue grid texture on it.


Can you post a link to an example project please?

So in the project, I have the material version Im trying to achieve. What I want to do is change the blue
texture to something else. Basically, I will create a scrollview with many different texture buttons

I really dont get it, this dont work.

var mat = this.buttonScript.iconEntity.element.material;
mat.emissiveMap = backgroundIcon.resource;

I’m trying to debug values in the element and I’m only getting defaultmaterial, I cannot find any occurence of my own material…

thank you for the support! good night!

It’s a bit tricky here.

The UI elements share the same material that has a custom shader on it and therefore have shader parameters to set the color and opacity maps.

So you either have to go through the same parameters which requires going to private API:

var Test = pc.createScript('test');
Test.attributes.add('textureAsset', { type: 'asset', assetType: 'texture'});

// initialize code called once per entity
Test.prototype.initialize = function() {
    this.entity.element._image._renderable.setParameter('texture_opacityMap', this.textureAsset.resource);

Or creating a new material at runtime

var Test2 = pc.createScript('test2');
Test2.attributes.add('colortextureAsset', { type: 'asset', assetType: 'texture'});
Test2.attributes.add('opacitytextureAsset', { type: 'asset', assetType: 'texture'});

// initialize code called once per entity
Test2.prototype.initialize = function() {
    /** @type {pc.StandardMaterial} */
    const m = new pc.StandardMaterial();
    m.blendType = pc.BLEND_NORMAL;
    m.opacityMap = this.opacitytextureAsset.resource;
    m.opacity = 1;
    m.opacityMapChannel = 'a';
    m.alphaTest = 0.634;
    m.emissiveMap = this.colortextureAsset.resource;
    this.entity.element.material = m;

    this.on('destroy', () => {

Or do what you are currently doing with the material asset assignment.

Test project:

1 Like

hooo! thats a perfect answer!!! And I will keep it in mind! Thank you so much!