sketchfabAPIUtility.setTexture does not change texture


(Improviz) #1

I am trying to dynamically change the texture on a model using sketchfabAPIUtility. However, when I use the method to set the texture as directed in the docs, nothing changes on the model in the viewer. I expect that calling this method will change the previous texture to the one called in the method. I have looked at many different posts in the forums, but those have not been helpful. Is this not the intended behavior or am I doing something wrong? I have also tried this with the regular viewer api with the same (non)result.

var iframe = document.getElementById('api-frame');
var urlid = 'mymodel';
var sketchfabAPIUtility = new SketchfabAPIUtility(urlid, iframe, onSketchfabUtilityReady);

var boxElder = "https://.../test-room/BoxElder.jpg";

function onSketchfabUtilityReady() {
    console.log('Viewer is ready');
    // sketchfabAPIUtility.setNodeVisibility("Floor", false);
    // sketchfabAPIUtility.setColor("Material", sketchfabAPIUtility.DiffusePBR, "#9ef442");

    sketchfabAPIUtility.setTexture("BakedCycles", sketchfabAPIUtility.AlbedoPBR, boxElder);

(Shaderbytes) #2

you server is probably not CORS enabled , this is required for texture injection to work. This is a browser security issue, so the regular api has this restriction and of coarse so would the utility. If you are using a browser like Chrome you can open the developer tools for your page and check the console, it will report the error there.

(Improviz) #3

CORS is enabled; no console errors. When using viewer API, I am able to get a reference to it in the texture list. Any other ideas?

(Shaderbytes) #4

you could be targeting the incorrect channel of the material perhaps?

(Improviz) #5

Thanks @shaderbytes, as it turns out I needed to use the DiffusePBR channel to change this texture. Sketchfab editor, however, refers to the texture as Albedo. See attached screenshot. Should/ could this discrepancy be addressed?

sketchfabAPIUtility.setTexture("BakedCycles", sketchfabAPIUtility.DiffusePBR, boxElder); works as expected.

sketchfabAPIUtility.setTexture("BakedCycles", sketchfabAPIUtility.AlbedoPBR, boxElder); does not.

On a side note, is there documentation describing the optional parameters that are passed into the setTexture method?

Finally, can the link to the texture be local to the website folders? IE can I use "../images/myImage.jpg" as the url instead of "https://..." I wasnt able to get this to work.

(Shaderbytes) #6

yeah I have complained more than once over the channel names myself :slight_smile: There is nothing we can do about this.

setTexture is a method in my API Utility that abstracts the whole process of doing it with the regular api. If you use the regular api , this involves calling addTexture , getting a result with texture id , possibly constructing a texture object or reusing one on the material , applying the id and then calling set material.

here is the docs to the regular api..

Here is the function in my Utility, there are two additional arguments , one is so you can set your own custom texture object, this will then override the one being created in the function. The other additional argument you dont have to use , it is used by another function in the Utility "resetTexture".

There is no documentation for the texture object created for the material , I just had to view the objects returned from api to understand what to use. This is the very reason why I made it possible to accept an override object when calling this function. In case you need to set it up differently for some or other reason.

this.setTexture = function (materialName, channelPropertyName, url, textureObjectDefaults, performCacheReset) {
        performCacheReset = performCacheReset || false;
        var materialObjectRef = classScope.getMaterialObject(materialName);
        if (materialObjectRef != null) {
            var channelObjectRef = classScope.getChannelObject(materialObjectRef, channelPropertyName);
            if (channelObjectRef != null) {

                if (performCacheReset) {
                    if (channelObjectRef.textureIsCached != undefined) {
                        channelObjectRef.texture = channelObjectRef.textureCached;                      
                        classScope.api.setMaterial(materialObjectRef, function () {

                    } else {
                        if (classScope.enableDebugLogging) {
                            console.log("a call to reset a texture has been ignored since the texture has not changed");


                if (channelObjectRef.textureIsCached == undefined) {
                    channelObjectRef.textureIsCached = true;
                    channelObjectRef.textureCached = channelObjectRef.texture;

                //if the material never had a texture object to begin with we need to generate one for it
                //else use the existing object to try preserve all properties excpt the texture uid obviously
                var texob = {};
                if (channelObjectRef.textureCached == null) {
                    var texob = {};
                    texob.internalFormat = "RGB";
                    texob.magFilter = "LINEAR";
                    texob.minFilter = "LINEAR_MIPMAP_LINEAR";
                    texob.texCoordUnit = 0;
                    texob.textureTarget = "TEXTURE_2D";
                    texob.uid = 0; // not actual value , the uid still needs to be returned from a succcessful texture upload.
                    texob.wrapS = "REPEAT";
                    texob.wrapT = "REPEAT";

                    // default properties for a newly created texture object are not always as coded above
                    //when needed, pass in an object with any alternate specified properities and they will be used
                    if (textureObjectDefaults != null) {
                        for (var prop in textureObjectDefaults) {                           
                            texob[prop] = textureObjectDefaults[prop];                           
                } else {
                    //deep copy
                    for (var prop in channelObjectRef.textureCached) {
                        texob[prop] = channelObjectRef.textureCached[prop];

                function addTextureCallback(err, uid) {
                    if (classScope.textureLoadedCallback != null) {

                    if (err) {
                        console.log('Error when calling  api.addTexture');

                    texob.uid = uid;
                    channelObjectRef.texture = texob;

                    classScope.api.setMaterial(materialObjectRef, function () {



                classScope.api.addTexture(url, addTextureCallback);
                if(classScope.textureLoadedCallback != null){




(Improviz) #7

Awesome. Thanks for your help.