[SOLVED] Cross-Origin error on loading internal PlayCanvas texture assets

Good afternoon guys, i’m facing a really strange problem. When i make a build from my project, the texture assets marked to not preload present a Cross-Origin error.

I’ve tried to reproduce the error on another project and it doens’t occur.

Steps to reproduce:

var entity = new pc.Entity();
entity.addComponent('model', {type: 'box'});
entity.setLocalScale(10,10,10);
pc.app.root.addChild(entity);

var texture = pc.app.assets.find('lightmap.jpg')
pc.app.assets.load(texture)

texture.ready(function(){
    var material = entity.model.model.meshInstances[0].material
    material.diffuseMap = texture.resource
    material.update();
});

This code simply load a jpg from my project and apply to a cube.

Details:

  • The texture was uploaded to Playcanvas editor and is built-in to the project
  • This only occurs at a builded project (at editor environment it works fine)
  • This only occurs when the asset preload is disabled
  • This occurs with every texture, not only the “lightmap.jpg”
  • This doesn’t occur at any other project that i create

Anyone knows what is going on?

Hi @derickwelman,

This appears to be a Same-origin policy issue: https://en.wikipedia.org/wiki/Same-origin_policy . Since the load is coming from the aws domain instead of the playcanv.as domain, chrome is blocking the asset load. In the editor launch environment, Playcanvas is loaded in and loading assets is from https://launch.playcanvas.com. I found this activity while inspecting my own preloader.

I am unsure about a workaround for this issue in the browser console. I do not have this problem when loading assets in my scripts in builds.

2 Likes

You should use the asset’s helper method asset.getFileUrl():

var asset = this.app.assets.find('my-asset-name');
var url = asset.getFileUrl();

You then load the asset by the provided url, which will be correct at run time in the build version.

2 Likes

Odd, I can’t replicate this in a new project: https://playcanvas.com/project/759410/settings

Build: https://playcanv.as/b/yaXfC2ks/

1 Like

@derickwelman Out of interest, if you did a new build, does this still happen?

1 Like

Yes, this problem affects all builds

Alright, it’s on my todo list for today but I have a lot on so I see how it gets on :slight_smile:

Edit: Looking at this now

1 Like

@derickwelman It looks like the project has patched the engine texture load to have custom logic

pc.TextureHandler.prototype.load = function(r, o) {
    "string" == typeof r && (r = {
        load: r,
        original: r
    });
    var n, i = r.original.indexOf("?") >= 0 ? r.original.split("?")[0] : r.original, t = pc.path.getExtension(i).toLowerCase();
    if (".dds" === t || ".ktx" === t) {
        pc.http.get(r.load, {
            cache: !0,
            responseType: "arraybuffer"
        }, (function(r, n) {
            r ? o(r) : o(null, n)
        }
        ))
    } else if (".jpg" === t || ".jpeg" === t || ".gif" === t || ".png" === t || ".webp" === t)
        n = new Image,
        void 0 !== this.crossOrigin && pc.ABSOLUTE_URL.test(r.original) && (n.crossOrigin = this.crossOrigin),
        n.onload = function() {
            o(null, n)
        }
        ,
        n.onerror = function(n) {
            o(pc.string.format("Error loading Texture from: '{0}'", r.original))
        }
        ,
        n.src = r.load;
    else {
        var e = i.indexOf("blob:");
        e >= 0 ? (i = i.substr(e),
        r = i,
        (n = new Image).onload = function() {
            o(null, n)
        }
        ,
        n.onerror = function(n) {
            o(pc.string.format("Error loading Texture from: '{0}'", r))
        }
        ,
        n.src = r) : setTimeout((function() {
            o(pc.string.format("Error loading Texture: format not supported: '{0}'", t))
        }
        ), 0)
    }
}
;

It’s minified code but it looks like it is only setting the crossOrigin on the image if it is an absolute path.

Whoever wrote this on your team will need to look this as it’s not PlayCanvas code.

The reason why it works when the asset is preloaded, is because the patch is part of the game_sprites file which isn’t applied until assets are preloaded.

(Side note: If you want to patch the engine, change the JS file in Editor to be ‘After Engine’ in the loading type)

1 Like

Hummm interesting. A long time ago i’ve made myself a script that adds webp texture support and added a commit with this fix to Playcanvas Git. At that epoch it was not merged at the engine, but today the webp has fully support and i don’t need this anymore. So, thank you so much!!! Problem solved.

1 Like