点击具有three.js的网格获取像素的颜色值

时间:2017-04-24 08:16:17

标签: javascript three.js getimagedata

我正在使用最后一个版本的three.js,我得到了一个带有渐变色的2D网格场景。颜色取决于分配给每个顶点的值。我希望通过用鼠标点击它来获得渐变的每个点的值(通过获取颜色,并为我的值做一些数学运算)

我尝试使用像这样的系统,因为它可以在这里工作:http://jsbin.com/wepuca/2/edit?html,js,output

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

function echoColor(e){
    var imgData = ctx.getImageData(e.pageX, e.pageX, 1, 1);
    red = imgData.data[0];
    green = imgData.data[1];
    blue = imgData.data[2];
    alpha = imgData.data[3];
    console.log(red + " " + green + " " + blue + " " + alpha);  
}

我的问题是这种技术用于在显示图像时从画布获取数据,而不是网格。当我试图在我的网格上使用它时,我有这个错误:

“TypeError:ctx为null”或“imageData不是函数”(取决于我如何声明我的画布及其上下文)。

由于我没有发现这种方法是否可以与网格一起使用,我在这里询问它是否可能,而不是如何做。

提前致谢

1 个答案:

答案 0 :(得分:2)

首先,您无法从已使用WebGL上下文的画布中获取2D上下文。这就是您收到ctx is null错误的原因。

要获得像素颜色,您有两种选择。

<强> 1。将WebGL画布图像传输到具有2D上下文的画布上。

要执行此操作,请创建一个新画布并将其调整为与THREE.js画布相同的大小,并从中获取2D上下文。然后,您可以使用2D上下文将THREE.js画布中的渲染图像作为图像绘制到新画布上:

var img2D = new Image();
twoDeeCanvasImage.addEventListener("load", function () {
    ctx2D.clearRect(0, 0, canvas2D.width, canvas2D.height);
    ctx2D.drawImage(img2D, 0, 0);
    // from here, get your pixel data
});
img2D.src = renderer.domElement.toDataURL("img/png");

从那里你可以像以前一样使用getImageData

此方法的一个警告是,您可能会看到由于通过toDataURL导出图像时引入的压缩导致的图像质量下降。你可以在某些情况下绕过这个:

if(ctx2D.imageSmoothingEnabled !== undefined){
    ctx2D.imageSmoothingEnabled  = false;
}
else if(ctx2D.mozImageSmoothingEnabled  !== undefined){
    ctx2D.mozImageSmoothingEnabled   = false;
}
else if(ctx2D.webkitImageSmoothingEnabled  !== undefined){
    ctx2D.webkitImageSmoothingEnabled   = false;
}
else{
    console.warn("Browser does not support disabling canvas antialiasing. Results image may be blurry.");
}

<强> 2。您也可以直接从渲染器获取像素值,但这会花费额外的渲染过程。

请参阅此THREE.js示例:https://threejs.org/examples/?q=instanc#webgl_interactive_instances_gpu

此示例使用readRenderTargetPixels中的THREE.WebGLRendererhttps://threejs.org/docs/#api/renderers/WebGLRenderer

我没有使用这种方法的任何个人经验,所以希望其他人可以填写一些空白。