javascript webgl 中的屏幕到世界坐标
我试图使用以下代码在我的数据中找到一个点(屏幕到世界坐标)(基于 单击放大 WebGL):
var world1 = [0,0,0,0] ;
var world2 = [0,0,0,0] ;
var dir = [0,0,0] ;
var w = event.srcElement.clientWidth ;
var h = event.srcElement.clientHeight ;
// calculate x,y clip space coordinates
var x = (event.offsetX-w/2)/(w/2) ;
var y = -(event.offsetY-h/2)/(h/2) ;
mat4.inverse(pvMatrix, pvMatrixInverse) ;
// convert clip space coordinates into world space
mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world1) ;
为了简单起见,我设置了一系列 z 坐标始终为 0 的顶点: 我正在绘制的坐标:
<前><代码>0.0 0.0 0.0 1.0 1.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.5 0.5 0.0
然后我将 world1 中的值与我的顶点进行比较。 world1 中的值与我所点击的位置不匹配。谁能帮忙解决这个问题吗?
I'm trying to find a point (screen to world coordinates) in my data by using the following code (based on Click to zoom in WebGL):
var world1 = [0,0,0,0] ;
var world2 = [0,0,0,0] ;
var dir = [0,0,0] ;
var w = event.srcElement.clientWidth ;
var h = event.srcElement.clientHeight ;
// calculate x,y clip space coordinates
var x = (event.offsetX-w/2)/(w/2) ;
var y = -(event.offsetY-h/2)/(h/2) ;
mat4.inverse(pvMatrix, pvMatrixInverse) ;
// convert clip space coordinates into world space
mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world1) ;
for simplicity's sake I have set up a series of vertices where the z coordinate is always 0:
coordinates I'm graphing:
0.0 0.0 0.0 1.0 1.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.5 0.5 0.0
Then I compare the values in world1 to my vertices. The values in world1 do not match to where I know I've clicked. Can anyone help with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅我的类似答案 如何从鼠标单击坐标获取 WebGL 3d 空间中的对象。
TL;DR:我认为您的 unproject 功能尚未完成。查看源代码 jax/camera .js#L568 为另一个实现。另请参阅 glhUnProjectf C 实现,前者(松散地)基于它。
最后一件事。请注意 HTML canvas 元素。很多时候,它并不位于您认为的位置,而使像素位置准确的唯一方法是向上遍历 DOM。请参阅 jax/events.js#L6和 jax/events.js#L100 的示例那。或者使用 jQuery
$('#canvas').offset()
函数并完成它。 :)Please see my similar answer at How to get object in WebGL 3d space from a mouse click coordinate.
TL;DR: I don't think your unproject function is complete. Take a look at the source at jax/camera.js#L568 for another implementation. See also the glhUnProjectf C implementation, which the former is (loosely) based upon.
One last thing. Be careful about the HTML canvas element. Quite often, it's not positioned where you think it is and the only way to make the pixel locations accurate is to traverse upward through the DOM. See jax/events.js#L6 and jax/events.js#L100 for examples of that. Or use the jQuery
$('#canvas').offset()
function and be done with it. :)一般来说,当您“取消投影”像 [x,y,z,1] 这样的剪辑空间点时,您将得到从视点发出的光线上的一个点(在您的情况下穿过您单击的顶点)。 z 的值将决定您在那条射线上的位置。您几乎肯定无法返回您点击的点。
所以你想要做的是计算该射线(例如通过取消投影 [x,y,0,1] 和 [x,y,1,1] 等两个点并计算未投影点所在的线),然后测试哪个顶点位于该射线上。
编辑:此外,您还需要确保已将
world1
的前三个坐标除以第四个坐标。In general when you "unproject" a clip space point like [x,y,z,1] you will get a point on a ray emanating from the eye point (and in your case going through the vertex you clicked on). The value of z will determine where you are on that ray. You're almost guaranteed to not get back the point you clicked on.
So what you want to do is calculate that ray (say by unprojecting two points like [x,y,0,1] and [x,y,1,1] and calculating the line that the unprojected points are on), and then testing which of your vertices lies on that ray.
Edit: Also, you want to make sure that you've divided the first three coordinates of
world1
by the fourth coordinate.