我正在使用最后一个版本的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不是函数”(取决于我如何声明我的画布及其上下文)。
由于我没有发现这种方法是否可以与网格一起使用,我在这里询问它是否可能,而不是如何做。
提前致谢
答案 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.WebGLRenderer
。 https://threejs.org/docs/#api/renderers/WebGLRenderer
我没有使用这种方法的任何个人经验,所以希望其他人可以填写一些空白。