Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript WebGL二维画布点转换为三维世界点_Javascript_Matrix_3d_Webgl - Fatal编程技术网

Javascript WebGL二维画布点转换为三维世界点

Javascript WebGL二维画布点转换为三维世界点,javascript,matrix,3d,webgl,Javascript,Matrix,3d,Webgl,我的代码有问题,或者我预期的值错误。我想要实现的是将二维点从画布转换为三维世界空间点 如果我理解正确,我应该始终获得相同的点,而不考虑摄影机的旋转,因为我不想要视图空间,而是世界空间点。想象一下,我点击这个立方体的正面墙,在X轴和Z轴之间,然后我想我应该得到恒定的Y值,它正常工作,直到我对我的相机做了一些旋转改变。如果我们让相机在墙上看,但是有一定的角度,那么每次点击都会得到不同的Y轴值,哪个值应该是常数,因为墙上的每个点都在相同的Y位置 我做错了什么 我不能100%确定我是否理解您的图表,但

我的代码有问题,或者我预期的值错误。我想要实现的是将二维点从画布转换为三维世界空间点

如果我理解正确,我应该始终获得相同的点,而不考虑摄影机的旋转,因为我不想要视图空间,而是世界空间点。想象一下,我点击这个立方体的正面墙,在X轴和Z轴之间,然后我想我应该得到恒定的Y值,它正常工作,直到我对我的相机做了一些旋转改变。如果我们让相机在墙上看,但是有一定的角度,那么每次点击都会得到不同的Y轴值,哪个值应该是常数,因为墙上的每个点都在相同的Y位置


我做错了什么

我不能100%确定我是否理解您的图表,但在其他方面,您的代码看起来不错

在大多数WebGL数学中,平截头体在远处是-Z。当然,您可以根据视图旋转它。但在任何情况下,如果将剪辑空间[x,y,-1]通过(投影*视图)矩阵的逆方向,则会得到视锥体远平面的某个点。当视图旋转时,该点随平截头体移动

如果我们让相机在墙上看,但是有一定的角度,那么每次点击都会得到不同的Y轴值,哪个值应该是常数,因为墙上的每个点都在相同的Y位置

否:如果旋转摄影机,则整个墙将旋转,因此墙上的点将旋转

这是一张俯视世界空间中视锥体顶部的示意图。视图正在旋转。如果clipX和clipY为0,则要计算的点位于平截头体远平面的中心(剪辑空间中的Z=1)。你可以看到那个点在旋转,即使它停留在平面上。它在视图空间中的位置不会更改,但在世界空间中的位置会更改,因为整个视锥体正在有效地旋转

当然,如果旋转摄影机,Y的值会不同

constv3=twgl.v3;
常数m4=twgl.m4;
const ctx=document.querySelector('canvas').getContext('2d');
常数boxTop=[
[-1,  1, -1],
[-1,  1,  1],
[ 1,  1,  1],
[ 1,  1, -1],
];
函数渲染(时间){
时间*=0.001;
setTransform(1,0,0,1,0,0);
clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
常数fov=60*Math.PI/180;
const ratio=ctx.canvas.clientWidth/ctx.canvas.clientHeight;
常数近=10;
常数far=40;
const projectionMatrix=m4.透视图(视野、比率、近距离、远距离);
常数viewMatrix=m4.旋转Y(时间);
//转换为剪辑空间
常数xClipSpace=0;
const yClipSpace=0;
常数zClipSpace=1;
//从剪辑空间转换回世界空间
const xyzVec3=v3.create(xClipSpace、yClipSpace、zClipSpace);
常量变换=m4.乘法(投影矩阵、视图矩阵);
常量逆=m4.逆(变换);
常数结果=m4.转换点(逆,xyzVec3);
// -------------
ctx.setTransform(1,0,0,1150.5,75.5);
//画原点
ctx.beginPath();

对于(设i=-200;我不是在检查数学是否完美,但总体而言,您正在计算相机表面上的一个3D点,它将始终随相机移动。您仍然必须从该点投射光线(使用视图方向),并检查它是否与立方体碰撞。该碰撞点就是您要寻找的。
var r = canvas.getBoundingClientRect();
var x = clientX - r.left;
var y = height - (clientY - r.top);

var projectionMatrix = matrix4.perspective(fov , ratio, near, far);
// convert to clip space
var xClipSpace = x / width * 2.0 - 1.0;
var yClipSpace = y / height * -2.0 + 1.0;
var zClipSpace = 1;
// convert back from clip space to world space
var xyzVec3 = vector3.create(xClipSpace ,yClipSpace ,zClipSpace);
var transfrom = matrix4.multiply(projectionMatrix,viewMatrix);
var inverse = matrix4.invert(transform);
var result = vector3.transformMat4(xyzVec3,inverse);