【问题标题】:Questions before ray projection射线投影前的问题
【发布时间】:2013-09-30 10:14:23
【问题描述】:

在学习与 Three.js 交互时我脑海中的几个问题

1)请解释一下什么是视口坐标?

2)它们与客户端坐标有何不同?

3)我们是如何得出这个公式的。

var vpx = ( eltx / div.offsetWidth ) * 2 - 1;
var vpy = - ( elty / div.offsetHeight ) * 2 + 1;
// vp->viewport, eltx->client coords,div->The div where webGL renderer has been appended.

4) 为什么我们在取向量时取视口系统中的第三个坐标为 0.5 比 1?

如果您能详细解释这些问题和概念,或者建议我读一本书,我将不胜感激。最好有一些 3D 图表可用于第一个问题。 真的很感激。

【问题讨论】:

  • 请回答专家...... @mrdoob
  • 请回答专家......@WestLangley

标签: javascript three.js projection


【解决方案1】:

3D 场景在画布容器内渲染。它可以是任意大小,并且可以位于 HTML 页面布局中的任何位置。很多时候,WebGL 示例和应用程序都是全屏显示的,这样画布就会填满整个屏幕,并且实际上与 HTML 布局的大小相同。但情况并非总是如此,WebGL 场景可以与其他 HTML 内容一起嵌入,就像图像一样。

Three.js 通常不关心也不知道 3D 画布如何与整个 HTML 页面的坐标和大小相关联。在 WebGL 画布内部,使用了完全不同的坐标系——完全独立于屏幕像素。

当您想要处理 3D 画布内的点击时,不幸的是,浏览器只提供从 HTML 页面左上角开始计数的像素值(eltx 和 elty)。因此,您需要先将 HTML 鼠标坐标转换为 WebGL 坐标(Three.js 中可用的矢量)。在 WebGL 坐标中,0,0 是画布的中心,-1,-1 是左上角,+1,+1 是右下角等等,无论画布的大小和位置如何。

首先,您需要获取画布的位置并从鼠标坐标中减去该位置。您的公式没有考虑到这一点,而是假设 webgl 容器位于页面的左上角(画布位置为 0px 0px)。没关系,但是如果您移动了容器或 HTML 正文具有 CSS 填充,例如,它将不再准确。

其次,您需要转换绝对鼠标像素位置(在上一步中调整),并将其转换为画布内的相对位置。这就是你的公式的作用。如果鼠标 x 位置为 50px,而您的画布为 100px 宽,则公式为 (50/100) * 2 - 1 = 0,即画布视口的屏幕空间中心。

现在您有了在 Three.js 3D 场景中有意义的坐标。

【讨论】:

  • 好友得到了前三个 3 个答案。但是在我的脑海中仍然有一件事为什么 webGL 有自己的坐标系?为什么不适用于基于像素的坐标
  • 您可以将 3D 场景视为完全独立于屏幕和屏幕像素的自己的世界。然后你有一个相机,它把这个世界转换成二维表​​示(即屏幕图像)。您根本不可能有从 2D 屏幕空间到具有透视图的 3D 空间的 1 对 1 映射。远处的物体在屏幕上的像素大小与近处的物体不同,这完全取决于相机的属性。这就是为什么从 3D 坐标到屏幕坐标再返回有点复杂的原因。
  • 非常感谢。先生,我又问了一个问题stackoverflow.com/questions/19140166/…。请也调试一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 2022-10-15
  • 2021-09-16
相关资源
最近更新 更多