Error creating the material

Hello. In my projects, I use images downloaded from the server. Recently, system warnings have begun to appear

WebGL: INVALID_VALUE: texImage2D: invalid image playcanvas-stable.dbg.js
WebGL-00001B6409189C00] GL_INVALID_OPERATION: Texture format does not support mipmap generation.

here is the code for creating textures

     Promise.all(data.map(el => new Promise(res => {
         const image = new Image()
         image.crossOrigin = 'anonymous'
         image.onload = () => {
                const texture = new pc.Texture(this.app.graphicsDevice, {
                    magFilter: pc.FILTER_LINEAR,
                    minFilter: pc.FILTER_LINEAR

                })
                texture.setSource(image)
                const material = new pc.StandardMaterial()
                material.diffuseMap = texture
                material.opacityMap = texture
                material.blendType = 'alpha'
                material.alphaToCoverage = true
                
                material.img = image;
                 material.update()
                this.materialItemsArr.push(material)
   
                   
                return res(material)
            }
            image.onload()
            image.src = el
     })))
     .then(()=> this.spawner.spawnItemAfterCreateMaterial(this.materialItemsArr))

tell me what is the error?

Sometimes the code works correctly, sometimes an error

Hi @sergey_ch ,

Are you able to share a project that reproduces the issue?

are you getting this on webgl1 devices? If yes, it’s possible your textures are not power of 2 dimensions, and webgl1 does not support mipmapping of those. You can add this line to the option you use to disable mipmapping. (you could also only do it on webgl1 devices if needed).

mipmaps: false
2 Likes

I wrote a personal message

I checked your project, I am not getting any error, not sure how to test. But indeed what @mvaligursky said, your remote images aren’t power of two sized:

For WebGL1 you definitely need to turn mipmaps off.

Tell me, and where to disable it?

         image.onload = () => {
                const texture = new pc.Texture(this.app.graphicsDevice, {
                    magFilter: pc.FILTER_LINEAR,
                    minFilter: pc.FILTER_LINEAR,
                    mipmaps: false
                })

Now, when restarting, there are warnings again, and the cubes are on the track without textures. If it is not difficult, you can run the project several times.

https://launch.playcanvas.com/1179340?debug=true

Can you share the steps on how to test? I am running your launch url but where am I supposed to see the remote images loading?

I am getting the warnings, though the game runs fine.

I think your code is not executing in the right order. Check here:

You set the image src after the promise finishes, but the promises is set to finish after the image has loaded? I am surprised this even worked.

Stepping through with the debugger I can see that when the material is assigned there is no diffuse map set (only an empty/placeholder):

I would start with that first, set the promise, and move the image.src setter outside of the callback. Untested, just to relay the idea:

GameManager.prototype.createLogo = function(data){

    const image = new Image()
    image.crossOrigin = 'anonymous'
    const prom = new Promise(res=>{
        image.onload = () => {
                const texture = new pc.Texture(this.app.graphicsDevice, {
                    magFilter: pc.FILTER_LINEAR,
                    minFilter: pc.FILTER_LINEAR

                })
                texture.setSource(image)
                const material = new pc.StandardMaterial()
                material.diffuseMap = texture
                material.opacityMap = texture
                material.blendType = 'alpha'
                material.alphaToCoverage = true
                material.update()
                material.img = image;
                console.log(material)
                return res(material)
            }
        image.onload()
    })
      
    prom.then(material =>{
         this.logos.forEach(el=>{
            // console.log(el, material)
            el.model.material = material
         })
    })

    image.src = data.game_stock.logo_200;
}
2 Likes

thank you for the idea, I will test it