0

Three.js 笔记 2:绘制3D对象

 2 years ago
source link: https://blog.theerrorlog.com/threejs-note-2-drawing-3d-objects-zh.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

上次我们在黑漆漆的屏幕上画了三条座标轴,是不是很有成就感呢?但是对 Three.js 这么牛逼的绘图工具来说,只画线似乎太小儿科了。敢不敢画点立 体的东西?

Mesh 对象

笔记1 里,我们画线的时候用到了 Line 对象,它用一个包含顶点数 组的 Geometry 对象来描述自己的几何形状。

实际上在 Three.js 里,具有“几何形状”的对象只有4种: LineMeshPointCloudSprite . 基本上,除了线条以外,所有的3D模型(包括3D 空间中的各种平面)都是由 Mesh 对象以及它的变种来描述的,所以我们在这 里也只讨论 Mesh 对象。至于另外两种, PointCloud 和 Sprite , 我们在 以后会了解到的,不用着急 :)

回到 Mesh 对象上,从文档里可以看到,它的构造函数和 Line 很像:

var mesh = new THREE.Mesh(geometry, material)

也就是说,要定义一个 Mesh ,我们也需要提供几何结构和材质信息。

Mesh 的几何结构

和 Line 一样, Mesh 的几何结构是由 Geometry 对象定义的;但是和 Line 不同的是,仅仅一个顶点数组并不足以描述 Mesh 的完整结构,因为 Mesh 由 面组成,而一个面至少包含3个顶点,一维数组不能描述顶点间的这种二维关系。

所以, Three.js 定义了 Face3 类型:

var geometry = new THREE.Geometry();
geometry.vertices.push(
    new THREE.Vector3(-10,  10, 0),
    new THREE.Vector3(-10, -10, 0),
    new THREE.Vector3( 10, -10, 0)
);
geometry.faces.push(new THREE.Face3( 0, 1, 2 ));

var material = new THREE.MeshBasicMaterial({color: 0xff0000});

var mesh = new THREE.Mesh(geometry, material);

上面 Face3 构造函数的三个参数分别是该平面三个顶点在 Geometry.vertices 数组中的 索引 ;由此可见, Face3 对象是不能独立于 Geometry 对象存 在的,要画出一个面,就要通过 Geometry 的 vertices 和 faces 属性去定义它。 这样定义好 Mesh 的各个面,再提供渲染这些面所用的材质,就能将这个 Mesh 绘制出来了。

简而言之 , Mesh 比 Line 多出一个描述 Face3 的步骤。

但是……为什么 Three.js 只定义了 Face3 ,而没有 Face4 、 Face5 、 FaceN 呢? 因为3顶点和4顶点组成的面具有许多方便程序处理的性质,图形学研究基本上集中在 这两种面上,而这里面又以3顶点的面处理起来最为简单快捷而且显示效果更好。

另外,在 OpenGL 里, 构成面的顶点顺序决定了面的方向 :顶点按逆时针方向排列 的那一面是正面,反之则是背面。以上面的例子画出的三角形为例,顺着Z轴负方向 看过去,看到的就是三角形的正面,因为定义这个面的三个顶点在这个方向上正是 按逆时针排列的。

除了“GL”之名以外, WebGL 也继承了这个约定。而且为了节省资源,WebGL 也是默 认不渲染背面的;所以当我们发现本该出现3D模型的地方空空如也的时候,就要检查 一下是不是把面给画反了……

生成随机地形

为了演示通过程序一步步生成一个有意义的 Mesh ,我们来生成个随机的山地 地形吧。方法很简单:首先通过简化的 Loop Subdivision 算法 将一个正 方形平面细分为足够小的三角形,然后随机一下细分后每个顶点的Y轴坐标。

以下是执行结果,源码嘛当然就在本页面源文件里了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK