原创作品 |「拆」制作过程
今天要隆重介绍一款3D城市建筑制作利器——City Engine,City Engine在行业内应用不如其他CG软件那么广泛,比较小众,它并不是一款游戏引擎,只是名字带着引擎二字而已。小众的主要原因是它的使用原理相对复杂: 利用自身的CGA语法来编写生成城市的脚本,这对于习惯拖拽点线面来建模的CG艺术家来说很不友好,但它的强大之处只有真正使用过才能体会。
在2016年的Sigraph大会上就有人介绍用City Engine制作《独立日2》的中远景城市,很多人担心用城市引擎的代码做出来的城市太规整,过于CG,但测试完看了最后的效果后,完全可以胜任电影项目里中远景甚至近景的细节制作。
▼《独立日2》City Engine制作建筑物过程
▼《独立日2》City Engine制作的建筑光线测试
借着研发新技术的空档,本人加强了一下City Engine的学习和研究,以下是小有所学后的成果。整幅作品在编写City Engine代码上使用了两个星期,其他元部件小细节只占用了1天时间,飞行器是用以前制作过的资产上的零件拆卸拼装而成的,最终在Clarisse里渲染出图。不带体积雾3k的图只渲染了15
分钟,体积雾单独渲染使用了3个小时。
▼作品「拆」里的建筑物都是在City Engine里生成的:
▼建筑物细节
▼场景线框图
▼灯光层
▼大气效果
▼颜色层
▼高光反射层
City Engine的优势在于编写好一套风格的代码之后,就可以随机秒出成千上万不同的建筑模型了。而这套代码规则就是一个环境资产,不同于以往的3D资产,做好后就不能再修改,它是动态建模的,可以随时调整布局和建筑的样式,只需要重新生成一下就可以了,非常有利于后期修改。
▼City Engine 流程图
一个City Engine的工程文件包括场景文件、CGA规则文件和外部导入的模型贴图资产三部分。
场景文件中包括外部导入的地形地图(Map),地形可以使用黑白色的高度图来生成;网络布线(Networks),用来规划城市布局的线框;形状(Shapes),由Networks生成的用来生成建筑的面,可以理解为建筑的根基。Networks和Shapes都可以自动生成或利用编辑工具手动绘制和调整。
▼City Engine 自动生成城市布局
▼可利用编辑工具调整街道的形态
City Engine最核心的部分是编写CGA规则,每一个Shape形状都可以赋予CGA规则,在CGA规则里可以编写一些基本的命令,也可以调用外部的资产文件,最终从Shape里长出建筑的模型。
▼City Engine CGA语法创建基本模型
CGA并不难理解,只是把我们在其他三维软件里的按钮变成了一行命令而已,通过这些命令的有机组合,可以制作出风格迥异的城市模型。
▼City Engine CGA语法对模型编辑
▼City Engine CGA对UV和贴图的处理
可以通过简单的CGA语法来改变模型的LOD(Level of Details)。这在制作大场景时非常有用,可以很快速地制作出一版简模用于制作Layout和Previz.
例如:
#给一个shape设置一个LOD属性
Attr LOD =”Low”
…
case LOD == “Low”: 终止代码
else:继续添加细节
…
▼City Engine 一键转换模型级别
通过改变每一个Shape的Random Seed随机值可以很轻易地重新生成不一样的模型。
▼City Engine 随机生成不同外形模型
City Engine 最强大的部分还是在它对整座城市布局的控制上。举一个简单的例子,可以通过一个全局属性来判断每一个Shape里城市中心的距离,利用这个属性可以判断并自动制作湖城市中心是高楼,偏远地区是矮房的效果。
例如:
#五种建筑物的注释
# 0: highrise
# 1: commercial buildings
# 2: apartment blocks
# 3: residential
# 4: openspace
#定义五种类型的建筑离城市中心的距离
const radiusHighriseArea = 400
const radiusCommercialArea = 800
const radiusApartmentArea = 1200
const radiusResidentialArea = 1600
#获取单一shape到中心的距离
distanceToCenter = sqrt(initialShape.origin.px*initialShape.origin.px +initialShape.origin.pz*initialShape.origin.pz)
#定义shape生成的建筑类型属性building Type,判断该shape离中心的距离,并给building type属性赋值
attr buildingType =
case distanceToCenter < radiusHighriseArea : 65%: 0 33%: 1 2%: 2 else: 4 # 当该shape离城市中心的距离小于定义的radiusHighriseArea值时,65%几率是buildingType=0(即最高的楼),33%几率是buildingType=1(商业区),2%几率是buildingType=2:(公寓),其他都是4(户外空间)
case distanceToCenter < radiusCommercialArea : 39%: 0 50%: 1 10%: 2 else: 4 # 当该shape离城市中心的距离小于定义的radiusCommercialArea值时,大部分是商业中心
case distanceToCenter < radiusApartmentArea : 26%: 1 40%: 2 25%: 3 else: 4 # 当该shape离城市中心的距离小于定义的radiusApartmentArea值时,大部分是公寓
case distanceToCenter < radiusResidentialArea: 5%: 1 30%: 2 63%: 3 else: 4 # 当该shape离城市中心的距离小于定义的radiusResidentialArea值时,大部分是住宅社区
else : 1%: 1 4%: 2 90%: 3 else: 4 #其他情况,90%是住宅和户外空间
这段代码来自官方的例子,通过这些代码判断出每一个shape属于哪个区域,配合extrude()等命名可以自动可以完成以下的布局。图中中心的区域大部分是highrise,中间的部分更多的是commercial buildings和apartment blocks,偏远的地方更多的是residential和openspace.
▼City Engine 5秒钟完成从城市中心到周边的布局
City Engine不一样的制作流程带给了艺术家更多的可能性,以下是来自Gnomon的一个教程里的例子,但是教程本身的案例不是这个,只是在一开始介绍了一下他们制作过的这个项目,有点坑爹的感觉,到目前为止我还没有找到特别详细的实例教程,基本都是通过自学的。简单介绍一下教程里的制作思路,基本和我前边说的一致。
step1.从shape生成最基本的体积模型
step2.生成更多细节的体积
step3.生成墙面细节,随机赋贴图
step4.利用scatter命令随机摆放屋顶的杂物资产
step5.最终渲染出片
看完本文有没有蒙…蒙就对了。在这里我只是对City Engine的大致流程和制作理念进行了阐述,要接受它并自如地使用需要很大的勇气和耐心的学习。初学者可以通过帮助文档和官方的CGA例子制作出比较简单的城市,如果需要更高阶的学习,可以持续关注我的公众号,在业余时间我会出一套City Engine的详细教程分享给大家。
希望早日看到你的CE详细教程,最好能有和其他主流软件配合运用的教程谢谢啦。正在研究这个软件感觉很有意思。