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