使用Three.js绘制一个虚拟城市

这篇文章解释了如何使用代码来编写一座3D立体“城市”。这个代码是由@ mrdoob最新发布的演示Demo。我发现这个演示的算法很优雅,是一个简单而有效的解决方案,所以我发了一个帖子解释它。

关于算法的一些评论

在我们将关注焦点置于问题的细节之前,把握下问题的整体和全局是很有帮助的。这个3D虚拟城市所使用的算法是完全由程序所生成的,这意味着整个城市 是动态建立,而不参考任何模板。这个算法相当优雅,且不超过100行javascript代码。这个算法的原理是怎么样的呢?简而言之,每一个建筑是一个 立方体,他们得到随机的大小和位置。足够简单吗?听起来好像不切实际,但事实就是这样的,当你从城市底部往上看时就会发现这个秘密。

从性能的角度来看,所有的建筑都合并成一个单一的几何形状,用一个单一的材料。这是做法是非常有效的,因为没有着色器切换和绘图调用命令。

为了提高真实感,通过模拟自然光使用了vertexColor小把戏。在这个城市,在街道级别里你可以看到来自其他建筑物的阴影,所以建筑物的底部比顶部暗,我们可以采用vertexColor来重现这样的效果。我们采取建筑物的底部顶点,并使其比顶部更暗。

让我们开始吧

我们将逐步解释那100行代码:(1)生成建筑的基础几何形状 ;(2)在城市的合适位置放置建筑物;(3)使用vertexColor技巧模拟环境光和阴影;(4)合并所有的建筑物,这样整个城市可以在一次性绘制。不多说,让我们开始吧!

生成建筑的基础几何形状

我们首先需要建立构建城市建筑的基础几何形状,它会重复使用多次,然后构建起整个城市。所以我们建立了一个简单的CubeGeometry对象。

var geometry = new THREE.CubeGeometry( 1, 1, 1 );

我们将参考点设置在立方体的底部,而不是它的中心,以便我们进行平移操作。

geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0.5, 0 ) );

然后我们去掉立方体的底面,这是一个优化小技巧。因为建筑物的底面是不可见的,因为它始终是在地面上。所以它是无用的,我们将其删除。

geometry.faces.splice( 3, 1 );

现在我们修复顶面的UV映射,我们将它们设置为单一的坐标(0,0),这样屋顶将和地板颜色相同,且建筑物的各面纹理共用,这样使得我们可以可以在单一的绘图过程中完成绘制。这也是优化绘制的小技巧。

geometry.faceVertexUvs[0][2][0].set( 0, 0 );
geometry.faceVertexUvs[0][2][1].set( 0, 0 );
geometry.faceVertexUvs[0][2][2].set( 0, 0 );
geometry.faceVertexUvs[0][2][3].set( 0, 0 );

好了,现在我们得到了一个单体建筑的几何形状,让我们绘制更多的建筑物,让它看起来更像一个城市!

在城市的合适位置放置建筑物

嗯……说实话,我们可以把他们放在任何地方。全部是随机。但是要小心,因为建筑和建筑之间会发生碰撞。但不管怎样,我们先把建筑放在随机位置。

buildingMesh.position.x = Math.floor( Math.random() * 200 - 100 ) * 10;
buildingMesh.position.z = Math.floor( Math.random() * 200 - 100 ) * 10;

然后我们在Y方向做一个随机的旋转:

buildingMesh.rotation.y = Math.random()*Math.PI*2;

然后,我们通过设置mesh.scale属性来改变建筑的大小。首先是如何建筑的宽度和深度。

buildingMesh.scale.x  = Math.random()*Math.random()*Math.random()*Math.random() * 50 + 10;
buildingMesh.scale.z  = buildingMesh.scale.x

然后是建筑物的高度:

buildingMesh.scale.y  = (Math.random() * Math.random() * Math.random() * buildingMesh.scale.x) * 8 + 8;

我们设置好了建筑物的位置/旋转/缩放等属性。现在让我们设置它的颜色,以及如何使用它来模拟阴影。

使用vertexColor技巧模拟环境光和阴影

在建筑丛生的大城市,建筑的底部往往比顶端更暗。这是因为太阳光线照射到建筑物顶部比底部更容易,而且在建筑物底部往往由来自其它建筑物的阴影,这 是在图形编程中称之为环境光遮蔽(Ambien

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值