javascriptthree.jsrendering

three.js color changes don't revert on instanceColor set


I am currently working on a loaded ifc model that has some custom propeties. I have a search field and my goal is it that the user of my application can enter the custom designator into the field and the element will blink to be identified in the screen.

I managed to implement the search field and the identification of the element. This is the relevant search function:


function performSearchIfc() {
    let searchInput = document.getElementById("uuidsearchinput").value;
    let expressId = designatorToExpressId.get(searchInput);
    let arrayOfParts = loadedFragmentsGroup.data.get(expressId)[0];

    console.log(arrayOfParts);

    for (let i = 0; i < arrayOfParts.length; i++) {
        let partId = arrayOfParts[i];

        let children = loadedFragmentsGroup.children;
        let item = children.find(item => item.id === partId);

        if (!item) {
            console.log("Skipping item: " + partId);
            continue;
        }

        console.log(item);

        (async () => { //Something doesnt work with the colors - scale works
            try {
                let r = item.instanceColor.array[0] + 1 - 1;
                let g = item.instanceColor.array[1] + 1 - 1;
                let b = item.instanceColor.array[2] + 1 - 1;
                let copyOfOrigColor =  new Float32Array([r, g, b]);

                let intenseGreen = new Float32Array([0, 1, 0]);

                while (true) {
                    console.log("Setting color to " + intenseGreen);
                    item.instanceColor.set(intenseGreen);
                    item.scale.set(2.2, 2.2, 2.2);
                    await sleep(1000);
                    console.log("Setting color to " + copyOfOrigColor);
                    item.instanceColor.set(copyOfOrigColor);
                    item.scale.set(1, 1, 1);
                    await sleep(1000);
                }
            } catch (error) {
                console.error(error);
            }
        })();

    }
}

The funny thing is the behaviour of the blinking. My stuff works perfectly fine, the elements that belong to my identifier are found and are adressed perfectly. What works is that i change the scale of the objects, and the color is also set to the bright green. The outputs of the console are as expected:

Log.

However, for some reason, resetting the color back to the old color is not working. The elements just stay green.

Can anyone explain this?

EDIT:

Shortly after posting, I noticed that sometimes only parts become colored, then it looks like this:

part color

So this coloring method seems to be unreliable altogether.


Solution

  • The instanceColor attribute represents the color of the instance and isn't meant to be edited that way. a reference image from three.js docs

    You can read more in the docs

    So, you will need to call item.setColorAt(index, color) and once you do so, you call the item.instanceColor.needsUpdate = true;

    index is the index of the instanced mesh (probably i in your case) and color is a THREE.Color() variable. You can set color to

    // if you use a CDN or imported three.js like: import * as THREE from 'three'
    const color = new THREE.Color('#00ff00');
    
    
    // or import Color and use it directly
    import { Color } from 'three';
    const color = new Color('#00ff00');