Three.js 将3D拾取转换为纹理投影?
我正在尝试在WebGL中编写一个非常小的工具,它允许我在UV网格中绘制。到目前为止,挑战之一是试图找到一种方法,将鼠标拾取位置转换为我应该在加载纹理中绘制的位置。有没有人有任何例子或可以推荐一些关于这方面的文献 您正在寻找的“技巧”可能是三个.Raycaster.setFromCamera()。这就是我认为你想要做的事情的一个简单版本。它在一个画布中渲染包含纹理球体的简单场景,并在另一个画布中放置应用于球体的纹理副本。单击球体将在第二个画布中纹理的相应点上绘制一个红点 有趣的是: 在init()。它将单击事件的x和y坐标传递给getClickPosition():Three.js 将3D拾取转换为纹理投影?,three.js,Three.js,我正在尝试在WebGL中编写一个非常小的工具,它允许我在UV网格中绘制。到目前为止,挑战之一是试图找到一种方法,将鼠标拾取位置转换为我应该在加载纹理中绘制的位置。有没有人有任何例子或可以推荐一些关于这方面的文献 您正在寻找的“技巧”可能是三个.Raycaster.setFromCamera()。这就是我认为你想要做的事情的一个简单版本。它在一个画布中渲染包含纹理球体的简单场景,并在另一个画布中放置应用于球体的纹理副本。单击球体将在第二个画布中纹理的相应点上绘制一个红点 有趣的是: 在init()
function getClickPosition(n, x, y) {
var rect;
rect = n.getBoundingClientRect();
return([
(x - rect.left) / n.clientWidth,
(y - rect.top) / n.clientHeight
]);
}
function projectLocation(x, y) {
var c, i, v, p;
// Bounds check our coords
if(x < 0) x = 0;
if(x > 1) x = 1;
if(y < 0) y = 0;
if(y > 1) y = 1;
// Convert our values from the range [0, 1] to the range [-1, 1]
v = new THREE.Vector2();
v.x = x * 2 - 1;
v.y = (-y * 2) + 1;
raycaster.setFromCamera(v, camera);
i = raycaster.intersectObjects(scene.children, true);
if(i.length > 0) {
getLocation(i[0]);
}
}
function getLocation(intersect) {
var uv;
uv = intersect.uv;
x = Math.round(uv.x * texture.image.width);
y = Math.round((1 - uv.y) * texture.image.height);
canvasCtx.lineWidth = 1;
canvasCtx.fillStyle = 'red';
canvasCtx.fillRect(x - 1, y - 1, 2, 2);
canvasCtx.fill();
}
这会将x和y坐标转换为一对介于0和1之间的值。这些值被传递到项目位置():
function getClickPosition(n, x, y) {
var rect;
rect = n.getBoundingClientRect();
return([
(x - rect.left) / n.clientWidth,
(y - rect.top) / n.clientHeight
]);
}
function projectLocation(x, y) {
var c, i, v, p;
// Bounds check our coords
if(x < 0) x = 0;
if(x > 1) x = 1;
if(y < 0) y = 0;
if(y > 1) y = 1;
// Convert our values from the range [0, 1] to the range [-1, 1]
v = new THREE.Vector2();
v.x = x * 2 - 1;
v.y = (-y * 2) + 1;
raycaster.setFromCamera(v, camera);
i = raycaster.intersectObjects(scene.children, true);
if(i.length > 0) {
getLocation(i[0]);
}
}
function getLocation(intersect) {
var uv;
uv = intersect.uv;
x = Math.round(uv.x * texture.image.width);
y = Math.round((1 - uv.y) * texture.image.height);
canvasCtx.lineWidth = 1;
canvasCtx.fillStyle = 'red';
canvasCtx.fillRect(x - 1, y - 1, 2, 2);
canvasCtx.fill();
}
交叉点对象包含交叉点的UV坐标getLocation()将这些转换为纹理中的XY坐标。您正在寻找的“技巧”可能是THREE.Raycaster.setFromCamera()。这就是我认为你想要做的事情的一个简单版本。它在一个画布中渲染包含纹理球体的简单场景,并在另一个画布中放置应用于球体的纹理副本。单击球体将在第二个画布中纹理的相应点上绘制一个红点
有趣的是:
在init()。它将单击事件的x和y坐标传递给getClickPosition():
function getClickPosition(n, x, y) {
var rect;
rect = n.getBoundingClientRect();
return([
(x - rect.left) / n.clientWidth,
(y - rect.top) / n.clientHeight
]);
}
function projectLocation(x, y) {
var c, i, v, p;
// Bounds check our coords
if(x < 0) x = 0;
if(x > 1) x = 1;
if(y < 0) y = 0;
if(y > 1) y = 1;
// Convert our values from the range [0, 1] to the range [-1, 1]
v = new THREE.Vector2();
v.x = x * 2 - 1;
v.y = (-y * 2) + 1;
raycaster.setFromCamera(v, camera);
i = raycaster.intersectObjects(scene.children, true);
if(i.length > 0) {
getLocation(i[0]);
}
}
function getLocation(intersect) {
var uv;
uv = intersect.uv;
x = Math.round(uv.x * texture.image.width);
y = Math.round((1 - uv.y) * texture.image.height);
canvasCtx.lineWidth = 1;
canvasCtx.fillStyle = 'red';
canvasCtx.fillRect(x - 1, y - 1, 2, 2);
canvasCtx.fill();
}
这会将x和y坐标转换为一对介于0和1之间的值。这些值被传递到项目位置():
function getClickPosition(n, x, y) {
var rect;
rect = n.getBoundingClientRect();
return([
(x - rect.left) / n.clientWidth,
(y - rect.top) / n.clientHeight
]);
}
function projectLocation(x, y) {
var c, i, v, p;
// Bounds check our coords
if(x < 0) x = 0;
if(x > 1) x = 1;
if(y < 0) y = 0;
if(y > 1) y = 1;
// Convert our values from the range [0, 1] to the range [-1, 1]
v = new THREE.Vector2();
v.x = x * 2 - 1;
v.y = (-y * 2) + 1;
raycaster.setFromCamera(v, camera);
i = raycaster.intersectObjects(scene.children, true);
if(i.length > 0) {
getLocation(i[0]);
}
}
function getLocation(intersect) {
var uv;
uv = intersect.uv;
x = Math.round(uv.x * texture.image.width);
y = Math.round((1 - uv.y) * texture.image.height);
canvasCtx.lineWidth = 1;
canvasCtx.fillStyle = 'red';
canvasCtx.fillRect(x - 1, y - 1, 2, 2);
canvasCtx.fill();
}
交叉点对象包含交叉点的UV坐标getLocation()将这些转换为纹理中的XY坐标