Why do I get CORS problem when loading image as texture, but no problem in the loading screen?

The following is my loadingScreen script:

pc.script.createLoadingScreen(function (app) {
    var showSplash = function () {
        // splash wrapper
        var wrapper = document.createElement('div');
        wrapper.id = 'application-splash-wrapper';
        document.body.appendChild(wrapper);

        var loading_img = document.createElement('img');
        loading_img.src = 'https://www.roomscalestudios.com/progressive_forest.jpg';
        wrapper.appendChild(loading_img);
    };

    var hideSplash = function () {
        var splash = document.getElementById('application-splash-wrapper');
        splash.parentElement.removeChild(splash);
    };

    var createCss = function () {
        var css = [
            'body {',
            '    background-color: #000000;',
            '}',
            '',
            '#application-splash-wrapper {',
            '    position: absolute;',
            '    top: 0;',
            '    left: 0;',
            '    width: 100vw;',
            '    height: 100vh;',
            '    overflow: hidden;',
            '    background-color: #000000;',
            '    display: flex;',
            '    align-items: center;',
            '    justify-content: center;',
            '}',
            '',
            '#application-splash-wrapper img {',
            '    object-fit: cover;',
            '    min-width: 100vw;',
            '    min-height: 100vh;',
            '    width: auto;',
            '    height: auto;',
            '}'
        ].join('\n');

        var style = document.createElement('style');
        style.type = 'text/css';
        if (style.styleSheet) {
            style.styleSheet.cssText = css;
        } else {
            style.appendChild(document.createTextNode(css));
        }

        document.head.appendChild(style);
    };

    createCss();
    showSplash();

    app.on('start', hideSplash);
});

This works and the image is displayed during loading.

However, then in the app I’m trying to load the exact same image as a texture:

  var background_image = new Image();
  background_image.decoding = 'async';
  background_image.loading = 'eager';
  // background_image.crossOrigin = 'anonymous';
  background_image.src = 'https://www.roomscalestudios.com/progressive_forest.jpg';
  background_image.decode().then(() => {
    var bg_texture = new pc.Texture(graphicsDevice);
    bg_texture.setSource(background_image);
    var material = this.backgroundEntity.render.material;
    material.emissiveMap = bg_texture;
    material.update();
  });

While the image displays fine on the loading Screen, here I’m now getting WebGL errors:

Uncaught SecurityError: Failed to execute ‘texImage2D’ on ‘WebGL2RenderingContext’: The image element contains cross-origin data, and may not be loaded.

if I uncomment background_image.crossOrigin = ‘anonymous’; then I’m getting instead

Access to image at ‘https://www.roomscalestudios.com/progressive_forest.jpg’ from origin ‘https://launch.playcanvas.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

I understand that I need to setup my server to serve propper CORS headers, but why is the image loaded and displayed without problem during the loading screen?

Also, if I load the same image in the loadingScreen and afterwards load it again as a texture, can I rely on the browser getting it from cache?

The reason I’m doing this is that I want to display an image during loading and then create a smooth transition to the app once it’s loaded.

IIRC, it’s something about using the image as a texture.

I recommend using https://api.playcanvas.com/classes/Engine.AssetRegistry.html#loadFromUrlAndFilename or https://api.playcanvas.com/classes/Engine.AssetRegistry.html#loadFromUrl instead to load the image as a texture

They go through a loading path that sets the image cross origin property as seen here in the engine:
https://github.com/playcanvas/engine/blob/dev/src%2Fresources%2Fparser%2Ftexture%2Fimg.js#L76

1 Like

doing so gives me the same error

Access to image at ‘https://www.roomscalestudios.com/progressive_forest.jpg’ from origin ‘https://launch.playcanvas.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Hmm… not sure then :thinking: Testing it against a file on GitHub (https://raw.githubusercontent.com/yaustar/yaustar.github.io/master/skybox/Helipad_negx.png) works fine

Using a tester for CORs gives errors with your file: CORS Tester - Test a URL for valid CORS headers