深入探索3D拾取技术.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入探索3D拾取技术

深入探索3D拾取技术 在游戏中,玩家需要通过点击2D屏幕来选择3D物体,这个过程就是拾取(picking)。拾取是3D游戏必不可少的基本操作,它实现了玩家和游戏世界内对象的交互。 虽然拾取技术很基本,但它却迷惑了很多3D初学者。很多朋友都问过我关于拾取的细节问题,这让我觉得很有必要具体探讨一下该技术。 其实,拾取之所以让很多开发者感到复杂,主要原因在于它跨域了流水线的多个阶段,并且是逆流水线上行。另外,它是一个2D信息扩展到3D的过程,必须对信息做相应的扩展和额外的计算才能够得到正确的结果。下面我门具体分析一下这个技术。 水流线主要阶段分析 我们来直观地看一下从相机空间到viewport的变换 相机空间中的一个顶点v,经过透视变换后进入了CVV中。这个变换矩阵实际上完成了两个工作: 1)将顶点从3D空间投影到2D的投影平面(Projection Plane)上。 2)将投影平面上的2D投影点通过线性插值变换到齐次裁剪空间CVV中。 这些变换都通过透视矩阵一次完成我之所以把这一步分解为两步,因为这对于分析拾取很重要。 顶点进入齐次裁剪空间并经过CVV裁剪,最终进行透视除法从4D齐次形式变回成3D形式。然后经过一个线性插值(被封装在视口(viewport)变换中),变换到viewport中,多个点以三角形的形式经过光栅化后被玩家看到。最后一步的点变换可以描述为: 3)将CVV中的点通过线性插值变换到viewport中。 分析了这个变换过程之后,我们知道了从相机空间开始实际处理点位置信息的操作,就是上面的三个步骤。这样,我们可以先把顶点从viewport中先变换回投影平面上,也就是我们可以先完成(2)和(3)的逆处理。这里我们不用考虑裁剪和透视除法这些操作,因为反推的时候,处于视口中的点,已经是经过裁剪后留下的有效点了,必定处于CVV内,也必定处于projection plane内!而且从viewport逆变换到projection plane,点一直保持2D形式。 picking的开始是玩家在屏幕上点击一个位置——这实际上是在viewport中进行了点击。我们通过响应玩家的点击事件,得到在viewport中的点击位置,记为P0(Xp0,Yp0)。然后我们把p0从viewport中线性插值到CVV中,得到P1(Xp1,Yp1): 上面的线性插值(如果对线性插值公式不熟悉,请参考《深入探索透视投影变换》一文中的线性插值部分)公式在x方向上计算出了CVV中的P1,y方向的公式同理。接下来我们再把P1从CVV中变换到projection plane中,得到P2(Xp2,Yp2): y方向的计算同理。P2就是viewport中玩家点击的点在projection plane上所对应的位置。 目前来看很好。我们已经获得了相机空间中的投影平面上,玩家点击的位置。但目前的点是一个2D点——它处于投影平面上。玩家需要拾取的是一个3D对象,因此我们需要将2D信息拓展到3D中。 向3D世界拓展 将2D的点信息拓展到3D空间进行picking,会使用射线(ray)进行。ray就是一端固定,另一端无限延伸的线性模型。如下图所示: 在相机空间中,红线标明的就是用于picking的ray。它的固定端就是eye的位置(也就是相机空间的原点),并且穿过我们刚刚求出来的projection plane上面的点P2。射线向空间无限延伸,第一个穿过的polygon应该就是picking到的结果。在图中,有两个polygon被picking到:绿色和黄色的。其中黄色的polygon是第一个被穿过的,因此picking操作返回的结果就是这个polygon。在实现中,我们一般有两种方式来表示一个ray: [cpp] view plaincopy struct Ray3D { Point3D m_startingPos; Point3D m_penetratedPos; }; struct Ray3D { Point3D m_startingPos; Point3D m_direction; }; 第一种方式标明了ray的起始点m_startingPos和任意一个穿过点m_penetrated。第二种方式标明了ray的起始点m_startingPos和方向m_direction。这两种方式可以很方便的相互转换。 在有了ray的表示法之后,我们要做的就是判断ray是否和各个polygon产生了相交——这实际上是一个射线和三角形的相交判断算法。这种算法很普遍,很容易找到,这里我们不进行讨论。最基本的拾取算法(相机空间中)如下所示; [cpp] view plaincopy extern

文档评论(0)

zilaiye + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档