如何从鼠标单击坐标获取 WebGL 3d 空间中的对象 [英] How to get object in WebGL 3d space from a mouse click coordinate

查看:33
本文介绍了如何从鼠标单击坐标获取 WebGL 3d 空间中的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 WebGL 构建一个棋盘游戏.该板可以旋转/缩放.我需要一种方法将画布元素 (x,y) 上的点击转换为 3D 空间 (x, y, z) 中的相关点.最终的结果是我想知道(x,y,z)坐标,该坐标包含与用户最近的物体接触的点.例如,用户点击一个棋子,你想象一条光线穿过 3D 空间,穿过棋子和游戏板,但我想要棋子的 (x, y, z) 坐标在它所在的点感动.

I'm building a boardgame in WebGL. The board can be rotated/zoomed. I need a way to translate a click on the canvas element (x,y) into the relevant point in 3D space (x, y, z). The ultimate result is that I want to know the (x, y, z) coordinate that contains the point that touches the object closest to the user. For instance, the user clicks a piece, and you imagine a ray traveling through 3D space that goes through both the piece and the game board, but I want the (x, y, z) coord of the piece at the point where it was touched.

我觉得这一定是一个非常普遍的问题,但我似乎无法在我的谷歌中找到解决方案.必须有某种方法将 3D 空间的当前视图投影到 2D 中,以便您可以将 2D 空间中的每个点映射到 3D 空间中的相关点.我希望用户能够将鼠标悬停在板上的空白处,并让专色更改颜色.

I feel like this must be a very common problem, but I can't seem to find a solution in my googles. There must be some way to project the current view of the 3D space into 2D so you can map each point in 2D space to the relevant point in 3D space. I want to the user to be able to mouse over a space on the board, and have the spot change color.

推荐答案

您正在寻找一个 unproject 函数,它将屏幕坐标转换为从相机位置投射到 3D 世界的光线.然后,您必须执行光线/三角形相交测试,以找到距离相机最近且也与光线相交的三角形.

You're looking for an unproject function, which converts screen coordinates into a ray cast from the camera position into the 3D world. You must then perform ray/triangle intersection tests to find the closest triangle to the camera which also intersects the ray.

我在 js#L568.js/#L568 -- 但您仍然需要实现光线/三角形相交.我在 jax/triangle.js#L111 中有一个实现一>.

I have an example of unprojecting available at jax/camera.js#L568 -- but you'll still need to implement ray/triangle intersection. I have an implementation of that at jax/triangle.js#L113.

然而,有一种更简单且(通常)更快的替代方法,称为挑选".如果您想选择整个对象(例如,棋子),并且您不关心鼠标实际单击的位置,请使用此选项.WebGL 的方法是将整个场景以各种深浅不一的蓝色(蓝色是关键,而红色和绿色用于场景中对象的唯一 ID)渲染到纹理,然后从那种质地.将 RGB 解码为对象的 ID 将为您提供单击的对象.同样,我已经实现了这个,它可以在 jax/world 上找到.#L82.(另见第 146、162、175 行.)

There is a simpler and (usually) faster alternative, however, called 'picking'. Use this if you want to select an entire object (for instance, a chess piece), and if you don't care about where the mouse actually clicked. The WebGL way to do this is to render the entire scene in various shades of blue (the blue is a key, while red and green are used for unique IDs of the objects in the scene) to a texture, then read back a pixel from that texture. Decoding the RGB into the object's ID will give you the object that was clicked. Again, I've implemented this and it's available at jax/world.js#L82. (See also lines 146, 162, 175.)

这两种方法各有利弊(在此处和一些之后的评论),您需要弄清楚哪种方法最能满足您的需求.大场景的选择速度较慢,但​​在纯 JS 中取消投影非常慢(因为 JS 本身并不是那么快)所以我最好的建议是对两者进行试验.

Both approaches have pros and cons (discussed here and in some of the comments after) and you'll need to figure out which approach best serves your needs. Picking is slower with huge scenes, but unprojecting in pure JS is extremely slow (since JS itself isn't all that fast) so my best recommendation would be to experiment with both.

仅供参考,您还可以查看 GLU 项目和取消项目代码,我的代码松散地基于这些代码:http://www.opengl.org/wiki/GluProject_and_gluUnProject_code

FYI, you could also look at the GLU project and unproject code, which I based my code loosely upon: http://www.opengl.org/wiki/GluProject_and_gluUnProject_code

这篇关于如何从鼠标单击坐标获取 WebGL 3d 空间中的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆