【带着canvas去流浪(14)】Three.js中凹浮雕模型的生成方式
【摘要】 使用three.js生成凹浮雕模型。
示例代码托管在:http://www.github.com/dashnowords/blogs
博客园地址:《大史住在大前端》原创博文目录
浮雕模型,简单地说就是在木板上刻字时所形成的效果,如果把字的部分都剔除掉,就得到一个凹浮雕模型,如果把字以外的部分都剔除掉,就得到一个凸浮雕模型。本文分别对利用Three.js
在Web环境中生成凹浮雕模型时的几种策略进行讲解。
一. 方案1:ThreeBSP.js或ThreeCSG.js扩展库
在众多技术博客里,提及最多的就是上述两个库,它们声称是Three.js
的扩展库,用来对模型进行实体布尔操作。
But!不要用!不要用!不要用!
查看github
的仓库就可以发现,这两个库早在N年前已经停止维护,完全是没有保障的。而笔者亲测后发现除了官方提供的示例外,它们连最基本的立方体挖孔都无法做到,按照官方示例的写法最终只得到了下面的模型,而笔者原本的期望是在大立方体上挖出一个小立方体凹槽,字体模型就更不用提了。
二. 方案2:平面镂空模型拉伸
由于期望实现的凹浮雕模型并不算复杂,可以换一种实现思路,先在平面上生成一个矩形,然后从其中去掉字体的形状,最后再将剩余的部分拉伸成几何体,当然如果期望的浮雕模型并没有完全穿过毛坯模型时,还需要使用一个额外的立方体来补全剩余的部分。
字体文件的加载是异步的,当完成加载后,就可以获得字体对象,将它传入下面的函数来生成一个大小为40
的M
字符,它本质上是一个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
几何体表面的材质信息,接下来使用命令行工具obj2gltf
(npm
上可以直接搜出来)对导出的文件进行格式转换,最后只需要将生成的marvel.gltf
文件利用Three.js
提供的GLTFLoader
加载器导入到网页中即可,相关代码如下:
// instantiate a loadervar loader = new THREE.GLTFLoader();// load a resourceloader.load(// resource URL'assets/marvel.gltf',// called when resource is loadedfunction (event) {console.log(event);event.scene.scale.set(0.2,0.2,0.2);scene.add(event.scene);render();},// called when loading is in progressesfunction (xhr) {console.log((xhr.loaded / xhr.total * 100) + '% loaded');},// called when loading has errorsfunction (error) {console.log('An error happened');});
可以看到网页中加载的模型既包含了凹浮雕模型,也包含了我们在建模软件中添加的蓝色材质(途中的亮蓝色域是点光源照射的效果)。
本节的示例Demo可在文章开头的github仓库中获取到,如果觉得对你有用,可以在仓库帮我点个星星~
作者:大史不说话
【带着canvas去流浪(14)】Three.js中凹浮雕模型的生成方式相关推荐
- 带着canvas去流浪系列之二 绘制折线图
[摘要] 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 【带着canvas去流浪(11)】Three.js入门学习笔记
[摘要] three.js 入门学习笔记 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 资料推荐及建议 1.官方文档 很详细,但是API部分单独 ...
- 【带着canvas去流浪(13)】用Three.js制作简易的MARVEL片头动画(下)#华为云·寻找黑马程序员#
[摘要] three.js实现的Web 3D字体模型动画 示例代码托管在:http://www.github.com/dashnowords/blogs 有了上一篇基础知识的储备,本节就来制作一下简易 ...
- 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)
我的github主页:https://github.com/dashnowords 我的新书上架啦,3天即登京东计算机编程语言类排行榜Top1!!!精选30+JavaScript库,从使用方式,设计原 ...
- 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上) #华为云·寻找黑马程序员#
[摘要] 用three.js实现简易的漫威片头动画 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 大作业说明 通读完上一篇博文中提及的教程,觉得 ...
- 【带着canvas去流浪(15)】threejs fundamentals翻译系列1-scene graph
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 目录 ...
- 【带着canvas去流浪(9)】粒子动画
我的github主页:https://github.com/dashnowords 我的新书上架啦,3天即登京东计算机编程语言类排行榜Top1!!!精选30+JavaScript库,从使用方式,设计原 ...
- 【带着canvas去流浪(10)】文字烟花
目录 一. 文字烟花 二. 动画原理 2.1 像素操作 2.2 烟花生成算法 2.3 计时器 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址 ...
- 带着canvas去流浪系列之九 粒子动画
[摘要] canvas实现粒子动画 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 粒子特效 粒子特效一般指密集点阵效果,它并不是canvas独有 ...
最新文章
- 软件需求阅读笔记之三
- 转】用Maven构建Mahout项目
- linux shell 字符串 数组,bash shell函数返回数组字符串
- PIL模块与随机生成中文验证码
- ASP.NET MVC使用Oauth2.0实现身份验证
- ligergrid 奇偶行效果_怎么护发才是真的有效果的?
- 一个列中多行求和_excel表格制作,Excel表格的基本操作,包含制作一个表格10方面的知识(1)...
- python社招面试_百度大牛总结十条Python面试题陷阱,看看你是否会中招
- Python递归函数的正确理解与使用
- SSO单点登录之同域登录的实现
- URL Scheme获取帮助文档
- Tapestry5的基础知识
- wordpress制作主题之菜单
- py文件编译成pyc文件
- Java截图转文字程序
- Kafka producer程序本地运行时发送信息失败解决方案
- 使用Python分析网易云歌曲评论信息,通过可视化处理我发现了这些有趣的规律...
- Ububtu 解压zip分卷文件
- I.MX6U 0411简介
- (开源)一款可以发文字发图片的实时聊天微信小程序,可以滚动内容到底部
热门文章
- 树莓派Raspberry Pi OS开机自启动脚本
- java怎么连elk_从Java应用程序登录到ELK而无需解析日志
- 渭南师范计算机科学与技术,渭南师范学院计算机科学与技术专业2016年在陕西理科高考录取最低分数线...
- TCP/IP , HTTP Protocol
- 网易云免费OSS服务用做Markdown图床或博客图片外链
- Prime Time UVA - 10200
- 开源软件free download manager在windows defender中报毒
- 新手必学的java报表开发工具FineReport实用技巧
- 我的2013 --岁月划过生命线(大二.上)
- leetcode 203 python3