【带着canvas去流浪(14)】Three.js中凹浮雕模型的生成方式

示例代码托管在:http://www.github.com/dashnowords/blogs前端

博客园地址:《大史住在大前端》原创博文目录git

华为云社区地址:【你要的前端打怪升级指南】github

浮雕模型,简单地说就是在木板上刻字时所造成的效果,若是把字的部分都剔除掉,就获得一个凹浮雕模型,若是把字之外的部分都剔除掉,就获得一个凸浮雕模型。本文分别对利用Three.js在Web环境中生成凹浮雕模型时的几种策略进行讲解。npm

一. 方案1:ThreeBSP.js或ThreeCSG.js扩展库

在众多技术博客里,说起最多的就是上述两个库,它们声称是Three.js的扩展库,用来对模型进行实体布尔操做。编程

But!不要用!不要用!不要用!canvas

查看github的仓库就能够发现,这两个库早在N年前已经中止维护,彻底是没有保障的。而笔者亲测后发现除了官方提供的示例外,它们连最基本的立方体挖孔都没法作到,按照官方示例的写法最终只获得了下面的模型,而笔者本来的指望是在大立方体上挖出一个小立方体凹槽,字体模型就更不用提了。数组

二. 方案2:平面镂空模型拉伸

因为指望实现的凹浮雕模型并不算复杂,能够换一种实现思路,先在平面上生成一个矩形,而后从其中去掉字体的形状,最后再将剩余的部分拉伸成几何体,固然若是指望的浮雕模型并无彻底穿过毛坯模型时,还须要使用一个额外的立方体来补全剩余的部分。app

字体文件的加载是异步的,当完成加载后,就能够得到字体对象,将它传入下面的函数来生成一个大小为40M字符,它本质上是一个shape实例,将其做为参数就能够生成拉伸体模型:异步

全部的shape实例都有holes属性,顾名思义它就是用来在封闭的平面图形上进行挖孔操做的,正好符合凹浮雕模型的制做需求,咱们只须要生成一个尺寸略大于字体模型包围盒的矩形,而后将字体模型的数据填入包围盒shape实例的holes数组中,Three.js就能够自动将其识别为孔:

关键代码以下所示(完整示例可在附件或文章开头的github仓库中获取):

/*在平面上生成镂空字体*/
    function calcShape(font) {
        fontShape = font.generateShapes('M',40);
        boxShape = new THREE.Shape();
        boxShape.moveTo(-20,-20);
        boxShape.lineTo(50,-20);
        boxShape.lineTo(50,50);
        boxShape.lineTo(-20,50);
        boxShape.lineTo(-20,-20);
        boxShape.holes.push(fontShape[0]);
        return boxShape;
}
/*生成拉伸体*/
 textGeometry = new THREE.ExtrudeGeometry(calcShape(font), {
                    depth:10,
                    bevelEnabled: false,
                    curveSegments: 4
                });

对于更为复杂的模型,这种方式仍然显得不够直观。

三. 方案3:Cinema 4D建模后输出模型文件

Three.js这种基于编程的建模方式并不够直观,面对复杂模型时,通用的解决办法是使用三维建模软件进行模型构建,而后导出Three.js可以识别的模型文件,使用加载器载入后再对模型进行微调,Three.js为数十种通用的三维模型文件都提供了加载器,本节以C4D为例演示基本的实现过程,若是你它的基本使用方法还不清楚,能够在【慕课网】上找到免费的使用教程。

C4D的主界面以下所示,建模的主要工具主要在图中红框标记的部分:

在图标上长按左键就能够看到每一个大类详细的功能:

本例中刚好每一个大类均用到一个功能(上图中红框标记的功能),立方体功能生成立体包围盒毛坯模型,文本功能生成须要雕刻的文字,使用挤压功能生成一个拉伸体对象后,在界面右侧的对象管理面板中将“文本模型”拖放到挤压文字上,就能够获得一个基于文本形状的拉伸体,最后生成一个实体布尔模型,在对象管理面板中将立方体挤压体依次拖放到对象名布尔这两个字上,它们就会成为布尔运算的成员,在布尔模型的配置中将操做类型选择为A减B,就能够获得凹浮雕模型了。建模的通用思路就像是函数式编程,先指定操做,再传入数据。

Three.js官方建议的模型格式为*.gltf格式,想要在C4D中直接导出这种格式须要安装相应的插件(GLTF格式工具仓库)。本例中咱们采用另外一种方式来实现,先在“文件”菜单中选择“导出”获得模型文件,本例中以*.obj扩展名为例。若是添加了表面材质,生成obj数据的同时还会带有一个同名的mtl文件(Material Template Library),它携带着obj几何体表面的材质信息,接下来使用命令行工具obj2gltfnpm上能够直接搜出来)对导出的文件进行格式转换,最后只须要将生成的marvel.gltf文件利用Three.js提供的GLTFLoader加载器导入到网页中便可,相关代码以下:

// instantiate a loader
    var loader = new THREE.GLTFLoader();

    // load a resource
    loader.load(
        // resource URL
        'assets/marvel.gltf',
        // called when resource is loaded
        function (event) {
            console.log(event);
            event.scene.scale.set(0.2,0.2,0.2);
            scene.add(event.scene);
            render();
        },
        // called when loading is in progresses
        function (xhr) {
            console.log((xhr.loaded / xhr.total * 100) + '% loaded');
        },
        // called when loading has errors
        function (error) {
            console.log('An error happened');
        }
    );

能够看到网页中加载的模型既包含了凹浮雕模型,也包含了咱们在建模软件中添加的蓝色材质(途中的亮蓝色区域是点光源照射的效果)。

本节的示例Demo可在文章开头的github仓库中获取到,若是以为对你有用,能够在仓库帮我点个星星~

相关文章
相关标签/搜索