自从我13岁开始玩AMOS 3D以来,我一直想学习如何编写3D图形.现在,10年后,我终于认为我已经积累了足够的数学来试一试.
我已经按照各种教程,并将screenX(和screenY,等效)定义为
screenX = (pointX * cameraX) / distance
(加上偏移和缩放.)
我的问题是距离变量实际上指的是什么.我已经看到距离被定义为相机和点之间z的差异.然而,这不可能是完全正确的,因为x和y与从相机到该点的实际距离上的z具有相同的效果.我将距离作为实际距离来实现,但结果给出了一个有点偏斜的视角,好像它有"太多"的视角.
我的"实际距离"实施方式如下:
distance = new Vector(pointX, pointY, cameraZ - pointZ).magnitude()
使用代码,我在我的方程中添加了一个额外的变量,一个perspectiveCoefficient如下:
distance = new Vector(pointX * perspectiveCoefficient, pointY * perspectiveCoefficient, cameraZ - pointZ).magnitude()
出于某种原因,这超出了我的范围,我倾向于获得将perspectiveCoefficient设置为1/sqrt(2)的最佳结果.
我的3D测试立方体位于http://vega.soi.city.ac.uk/~abdv866/3dcubetest/3dtest.svg.(在Safari和FF中测试过.)它会提示你一个perspectiveCoefficient,其中0给出了一个不考虑x/y距离的透视图,1给出了一个透视图,其中x,y和z距离被同等考虑.默认为1/sqrt(2).可以使用箭头键将立方体旋转大约x和y.(对于任何感兴趣的人,相关代码都在View.js文件的update()中.)
对此有任何想法感激不尽.
通常,从该平面后面的眼睛位置在Z = 0平面上进行投影.投影点是线(Pt,Eye)与Z = 0平面的交点.最后你会得到类似的东西:
screenX = scaling * pointX / (1 + pointZ/eyeDist) screenY = scaling * pointY / (1 + pointZ/eyeDist)
我假设相机位于(0,0,0)并注视(0,0,-eyeDist).如果eyeDist变为无限,则获得平行投影.