Loading Images from URL - Loading multiple images

Hello I am currently working on a 3d gallery for displaying multiple images from a URL provided via a url attribute as per this example


I have given each entity a unique url for the url attribute using the script shown in the demo, however when I go to load this on my server, it returns a random texture for all the multiple entities which have a unique url instead of showing the individual images as textures. So it half works but it must show each entity with it’s own applied texture.

Now I am fairly sure I am missing something obvious here but having trouble figuring out what, each entity has a unique url as I said.

Code here

var LoadExternalImage = pc.createScript('loadExternalImage');

LoadExternalImage.attributes.add("imageUrl", {type: "string"});

// initialize code called once per entity
LoadExternalImage.prototype.initialize = function() {
    var self = this;
    // allow cross origin texture requests
    this.app.loader.getHandler("texture").crossOrigin = "anonymous";
    var asset = new pc.Asset("myTexture", "texture", {
        url: this.imageUrl
    asset.on("error", function (message) {
    asset.on("load", function (asset) {
        var material = self.entity.model.material;
        material.diffuseMap = asset.resource;

// update code called every frame
LoadExternalImage.prototype.update = function(dt) {

// swap method called for script hot-reloading
// inherit your script state here
// LoadExternalImage.prototype.swap = function(old) { };

and the result

Any help much appreciated

Do the picture models in the gallery all have the same material?

If so, that’s your issue. They are all referencing the same material asset. I would either clone the material in the editor and give reference each picture their own material asset or clone the material and reassign at runtime.

Dumb question: why script this if you weren’t going to ever use it? You used this.stuff through the entire function, rather than self.stuff.

They use it in the asset on load function callback where it’s needed for the closure to capture the variable.

It’s to with variable scoping and what is available in the context.

Freecodecamp have an article on this: https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4?gi=3a94783363e8

1 Like

The 5 entities I’m using to test have no material assigned, the material textures are being applied at runtime by the script, but it is randomly assigning one of the 5 images to everything instead of applying the individual image urls for each entity as expected. The script I thought would grab an image from the images folder and then create a material from it. I thought maybe it was the entities didn’t have unique names or something but they do, though they are grouped as one, so not sure if that could create issues?

I just copied the script from the example I found that I linked to as a first step, I guess I will experiment with scope. Thanks for the link.

In which case, they are pointing to the same default material.

Here’s a variation of the project that you have linked to that has two boxes loading different images by cloning the model’s material and assigning it back to the model: https://playcanvas.com/editor/scene/734178

1 Like

Thanks a lot that helped me fix it, once again thanks a lot. Very helpful

nice - and if one have to load an png with transparecy?

    asset.on("load", function (asset) {
        var material = self.entity.model.material.clone();
        material.opacityMap = asset.resource;
        self.entity.model.material = material;

Make sure that the material has the correct properties set for the transparency which depends on your use case.

ok, got it:

  • for those interested in using imgur, be aware of:
    Correct linking: Use direct linking (i.imgur and not just imgur …etc)

Be also aware that the material needs a; transparent png attached, on beforehand (not a must at ‘yogi bear-image’ -> the box that only loads a regular png).

It doesn’t need to before hand. It just needs the properties to be set when you need them (eg after the image is loaded)