问题描述
我正在使用three.js的最新版本,并且我得到了一个带有2D网格和渐变颜色的场景.颜色取决于分配给每个顶点的值.我想通过使用鼠标单击来获得渐变的每个点的值(通过获取颜色,并对我的值进行一些数学运算)
I'm working with the last version of three.js and I got a scene with a 2D mesh, with gradient color. The color depends of a value assigned to each vertex. I would like to get the value of every point of my gradient by clicking on it with the mouse (by getting the color, and make some math for my value)
我尝试使用这样的系统,因为它在这里起作用: http://jsbin.com/wepuca/2/edit?html,js,输出
I tried to use a system like this one, since it works here : 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);
}
我的问题是,当显示图像时,此技术用于从画布获取数据,而不是网格.当我尝试在网格物体上使用它时,出现了这个错误:
My problem is that this technique is used to get data from the canvas, when an image is displayed, and not a mesh. When I tried to use it on my mesh, I have that error :
"TypeError:ctx为空"或"imageData不是函数"(取决于我如何声明画布及其上下文).
"TypeError: ctx is null" or "imageData is not a function" (depending on how I declared my canvas and his context).
由于我没有找到该方法是否可以与网格一起使用,所以我在这里问是否可以实现,而不是如何实现.
Since I didn't find if this method can be used with mesh, I'm here asking if it's possible or not, more than how to do it.
预先感谢
推荐答案
首先,您无法从已经使用WebGL上下文的画布中获得2D上下文.这就是为什么出现ctx is null
错误的原因.
First, you cannot get a 2D context from a canvas which is already using a WebGL context. This is why you're getting the ctx is null
error.
要获取像素颜色,您有两个选择.
To get the pixel color, you have two options.
1.将WebGL画布图像传输到具有2D上下文的画布上.
要执行此操作,请创建一个新画布并将其大小设置为与THREE.js画布相同,然后从中获取2D上下文.然后,您可以使用2D上下文将THREE.js画布中的渲染图像作为图像绘制到新画布上:
To do this, create a new canvas and size it to be the same size as your THREE.js canvas, and get a 2D context from it. You can then draw the rendered image from the THREE.js canvas onto your new canvas as an image, using the 2D context:
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
.
From there you can use getImageData
, like you did before.
此方法的一个警告是,您可能会看到由于通过toDataURL
导出图像时引入的压缩而导致的图像降级.在某些情况下,您可以避免这种情况:
One caveat of this method is that you may see image degradation due to compression introduced when exporting the image via toDataURL
. You can circumvent this in some cases:
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
See this THREE.js example: https://threejs.org/examples/?q=instanc#webgl_interactive_instances_gpu
此示例在THREE.WebGLRenderer
中使用readRenderTargetPixels
. https://threejs.org/docs/#api/renderers/WebGLRenderer
我没有使用此方法的任何个人经验,因此希望其他人可以填补其中的空白.
I don't have any personal experience using this method, so hopefullysomeone else can fill in some of the blanks.
这篇关于使用three.js在单击网格时获取像素的颜色值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!