Search code examples
colorsthree.jshtml5-canvasgetimagedata

Mesh Material color stumper when using with a single pixel's getImageData in Three.js


This question is strictly about one color materials (the same amount of data that one single pixel would have) and not textures.

When using getImageData, I can get the color/opacity of a specified pixel in a 2d image in a canvas just fine; resulting with something like: 50,41,26,255 (for example).

But my question is: instead of having to use a rgba-to-hex system like toString(16) (then using string manipulation and also the opacity/alpha value separately since that is 0-1 and not 00-FF), etc, for converting, when specifying the exact pixel-color-and-opacity data for THREE.MeshBasicMaterial colors...

Is there a more efficient way?

Ideally, instead of:

new THREE.MeshBasicMaterial(
    {color:0x33AA55, transparent:true, opacity:0.8, side: THREE.DoubleSide})

And then all the heaps of conversion code required for making that

To have something like:

new THREE.MeshBasicMaterial(
    {rgba-color:(ctx.getImageData(x, y, 1, 1).data), side: THREE.DoubleSide});

Solution

  • As things are right now you do need to convert it. I don't see a convenience method happening for this, as it is a very specific use-case. It isn't all that bad doing the conversion manually anyway: if you also want to handle the opacity you'll have to tackle that value specifically anyway since THREE.Color doesn't use it.

    var data = context.getImageData( x, y, 1, 1 ).data;
    var floats = data.slice( 0, 4 ).map( function( val ) { return val / 255; });
    var color = THREE.Color( float[0], float[1], float[2] );
    var opacity = float[4];
    

    Not exactly heaps of code, but if it bothers you too much then create a function for it.

    Don't use string manipulation, that's error-prone and inefficient.