从Maya中把模型搬运至网页的过程
虽然利用threejs来在网页中渲染3d模型不是第一次折腾了,但是还是遇到了各种问题。总结下我所遇到的问题,希望能给正在使用threejs的小伙伴一个帮助。
一、所使用的软件与开发环境
Maya2014、Blender2.77a
webpack + gulp
二、 动画模型的导入导出
1、格式的选择
threejs支持的动画模型有Collada(.dae)、mmd(用过MikuMikuDance的应该知道) 、fbx、json。
Collada里面包含了你场景中所有数据(camera、scene、light),因为手生所有这次没有采用这种格式。
fbx虽然网页中可以加载fbx,但我常用的是从其它软件中导个fbx给blender用。不过这里值的注意一下,以maya为栗子。
maya导出fbx的时候会有一个文件格式的选项: 二进制(导出给blender选择这种编码)、ASCII(导出给threejs直接用选择这种编码)如下图所示:

2、动画的分类
- 变形动画(threejs中
MorphAnimMesh类)
变形动画简单点来说就是通过变形物体来改变物体的样子,复杂的动画用这种方法处理就不合试了,因为改变一下所有的顶点都会随之改变。数据量挺大的。
在blender中的导出json选择如下所示:

- 骨骼动画(threejs中
SkinnedMesh类)
骨骼动画也就是蒙皮动画,通过给物体绑定骨骼来对物体进行操作。
在blender中的导出json时存在以下两种情况:
1、keyframe animation 导出选项以及json代码如下所示:

2、skeletal animation 导出选项以及json代码如下所示:

3、从maya中导出fbx至blender中
在maya中导出fbx给blender的时候文件格式选择
二进制。做模型绑定的时候对模型的数据进行
清零(这点很重要,不然blender导出json的会出现错误情况)、绑定方法的话按照做游戏的绑定方法就可以了。软边显示与硬边显示(导出时在maya中选择
软边显示)照理说应该是硬边显示才对,瞎猜是blender与maya设置不同吧。在页面中渲染的情况如下所示:

三、 模型渲染到网页中
1、创建场景
var camera,scene,renderer
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(40, 750 / 1200, 0.1, 10000);
renderer = new THREE.WebGLRenderer({antialias: true, alpha: false, preserveDrawingBuffer: true});
renderer.shadowMap.enabled = true;
renderer.autoClear = true;
var render = function () {
renderer.render(scene, camera);
}
var animate = function () {
requestAnimationFrame(_that.animate);
render();
}
//一个简单的场景就写好了
2、创建动画模型
这里我导出的是json格式的蒙皮动画所以我采用了threejs中提供的BlendCharacter()方法来创建我的动画模型。具体代码如下所示:
var createSkinningAnimate = function (model) {
var blendMesh = new THREE.BlendCharacter();
blendMesh.modelId = model.id;
blendMesh.load( model.modelSrc, function(){
blendMesh.name = model.modelName;
blendMesh.scale.set(model.scaleX, model.scaleY, model.scaleZ);
blendMesh.position.set(model.x, model.y, model.z);
blendMesh.frustumCulled = false;
blendMesh.material.transparent = true;
//
blendMesh.material.opacity = 0;
if(model.shadow) {
blendMesh.castShadow = true; //表示这个物体是可以产生阴影的
}
if(model.receive) {
blendMesh.receiveShadow = true; //表示这个物体是可以接受(显示)阴影的
}
if(model.side) {
blendMesh.material.side = THREE.DoubleSide; //解决单双面显示问题
}
blendMesh.visible = false;
for(var i = 0, len = model.action.length; i < len; i++) {
blendMesh.applyWeight( model.action[i].name, model.action[i].weight);
};
blendModelGroup.add(blendMesh);
loadModelProgress();
});
}
创建这个模型的时候我遇到了两个问题:
- 模型出现渲染的时候单双面问题吗,具体表现如下所示。

解决方法:
//设置material的side
blendMesh.material.side = THREE.DoubleSide; //解决单双面显示问题
- 当镜头拉近的时候模型从视野中消失,具体表现如下所示

解决方法:
//设置这个属性为false时这个bug就好了。
blendMesh.frustumCulled = false;
frustumCulled 这个属性是至今干嘛用的我不太清楚,求告知。
3、灯光渲染
场景中利用了两个灯光全局灯(AmbientLight)与聚光灯(SpotLight)代码如下:
_that.ambientLight = new THREE.AmbientLight( 0xffffff);
scene.add(_that.ambientLight);
var spotLight = new THREE.SpotLight(0xffffff);
_that.spotLight = spotLight;
spotLight.angle = 0.74;
spotLight.position.set(0, 60, -1);
spotLight.castShadow = true;
spotLight.penumbra = 0.7;
spotLight.intensity = 2;
spotLight.distance = 200;
spotLight.shadow.camera.near = 50;
spotLight.shadow.camera.far = 200;
spotLight.shadow.camera.fov = 35;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.mapSize.width = 1024;
spotLight.name = 'spotLight';
scene.add(spotLight);
spotLight.target.position.set(-15,0,0);
//scene.add(new THREE.SpotLightHelper( spotLight ));
scene.add(spotLight.target);
灯光的调试主要靠gui与LightHelper,这两个东西调试起来非常方便省了不少时间。调试前与调试后如图所示:

5、调试技巧
gui
helper
topView
helper:threejs的相机、灯光都提供了Helper这个方法,在页面中渲染添加一个参考线。
topView: 意思就是在页面中渲染一个顶视图,如果需要做相机的移动这个方法比较靠谱可以清楚的看见相机是这么运动的。然后发现问题的所在。渲染如下图所示:

实现代码:
var testW = 750,
testH = 1200;
var views = {
left: 0.5,
bottom: 0,
width: 0.5,
height: 0.5,
eye: [0, 0, 50],
direction: [-1, 0, 0]
};
var orthoCam = new THREE.OrthographicCamera(testW / -2, testW / 2, testH / 2, testH / -2, -500, 10000);
view.orthoCam = orthoCam;
update () {
var left = Math.floor( testW * 0.0 );
var bottom = Math.floor( testH * 0 );
var width = Math.floor( testW * 1.0 );
var height = Math.floor( testH * 1.0 );
renderer.setViewport( left, bottom, width, height );
renderer.setScissor( left, bottom, width, height );
renderer.setScissorTest ( true );
camera.updateProjectionMatrix();
cameraHelper.update();
cameraHelper.visible = false;
renderer.render(scene, camera);
cameraHelper.visible = true;
var view = views;
orthoCam = view.orthoCam;
orthoCam.left = testW / - 2;
orthoCam.right = testW / 2;
orthoCam.top = testH / 2;
orthoCam.bottom = testH / - 2;
orthoCam.position.x = view.eye[ 0 ];
orthoCam.position.y = view.eye[ 1 ];
orthoCam.position.z = view.eye[ 2 ];
orthoCam.rotation.x = view.direction[ 0 ] * Math.PI * 0.5;
orthoCam.rotation.y = view.direction[ 1 ] * Math.PI * 0.5;
orthoCam.rotation.z = view.direction[ 2 ] * Math.PI * 0.5;
orthoCam.updateProjectionMatrix();
var left1 = Math.floor( testW * view.left );
var bottom1 = Math.floor( testH * view.bottom );
var width1 = Math.floor( testW * view.width );
var height1 = Math.floor( testH * view.height );
renderer.setViewport( left1, bottom1, width1, height1 );
renderer.setScissor( left1, bottom1, width1, height1 );
renderer.setScissorTest ( true );
renderer.shadowMap.enabled = true;
renderer.render( scene, orthoCam );
}
核心创建一个正交相机OrthographicCamera
6、兼容判断
因为不是所有手机都支持webgl所以需要做一下兼容性的判断。
- 在ios8虽然支持webgl但是时间跟踪clock不支持,但在不报错。查看源码的情况下估计是
var newTime = ( performance || Date ).now()没有得到正确的值。因为时间关系没有过多的深入,所以页面在ios8直接跳转至2d版本。
-getExtension('WEBGL_depth_texture')经过测试在一些安卓上返回为null,所以没有用这个去做区分。
兼容代码如下所示:
var canvas = document.createElement("canvas");
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if( gl ){
var OES_TextureExtension = gl.getExtension('OES_texture_half_float');
var EXT_TextureExtension = gl.getExtension( 'EXT_texture_filter_anisotropic' );
}
if(gl && OES_TextureExtension && EXT_TextureExtension&& !(isIos && version < 9)) {
//..3d code
}else {
//..2d code
};
TODO:
虽然这个项目上线了,但是还有很多东西需要去细化完善- -!!。
更好的完成相机的移动
人物的动画拆分
整个场景动画优化
之前用threejs做的一个小项目点击这里查看
最后附上体验地址:

从Maya中把模型搬运至网页的过程的更多相关文章
- C#开发BIMFACE系列38 网页集成开发2:审图系统中的模型或图纸批注
系列目录 [已更新最新开发文章,点击查看详细] 在运维或协同的场景中,经常需要对模型或图纸进行批注,及时记录已发现的问题并交给相关负责的人员. 在开始实现功能之前,先了解一下BIMFACE中有 ...
- 从Maya中导入LightMap到unity中
导入步骤 1.在Maya中为每一个模型烘焙好帖图(tif格式),会发现烘焙好的图和UV是一一对应的 2.把模型和烘焙帖图导入到Unity中 3.选中材质,修改Shader为 Legacy Shader ...
- maya中MFnMesh.h使用说明的翻译
由于最近要修改一个maya中的deformer脚本,于是开始系统学习openMaya的一些知识,当然少不了得把一堆头文件说明看一遍.首先把MFnMesh.h这个文件翻译一下吧,不废话,上译文: 首先M ...
- unity3d 资源文件从MAX或者MAYA中导出的注意事项
unity3d 资源文件从MAX或者MAYA中导出的注意事项 1.首先,Unity3d 中,导出带动画的资源有2种导出方式可以选择: 1) 导出资源时,只导出一个文件,保留模型,骨骼和所 ...
- 总结一下一般游戏中3D模型各种勾边方法遇到的工程性问题
以前做过简单的rim light勾边,几何勾边,这次又做了后处理的勾边,工程化的时候,都遇到很多问题,简单总结一下. 首先是火炬之光勾边效果,类似轮廓光的实现,简单的卡通渲染也是通过类似的算法加采样色 ...
- 15SpringMvc_在业务控制方法中写入模型变量收集参数,且使用@InitBind来解决字符串转日期类型
之前第12篇文章中提到过在业务控制方法中写入普通变量收集参数的方式,也提到了这种凡方式的弊端(参数很多怎么办),所以这篇文章讲的是在业务控制方法中写入模型变量来收集参数.本文的案例实现的功能是,在注册 ...
- ThinkPHP中的模型二
ThinkPHP中的模型 1.为什么要创建数据对象 案例:使用ThinkPHP完成部门管理 ① 设计数据库 ② 创建Dept控制器 路径:./Application/Admin/Controller创 ...
- ThinkPHP中的模型
ThinkPHP中的模型 1.什么是模型(Model) 模型表示企业数据和业务规则,实际项目开发中,主要实现与数据库进行操作. 2.模型的定义规则 模型类的命名规则是除去表前缀的数据表名称,采用驼峰法 ...
- 从3dmax中导入模型到UDK Editor(供个人备忘)
笔记从3dmax中导入模型到UDK Editor 1) 在3dmax中导出 2) 选择FBX格式,保存 3) 在UDK中打开content browser,自己选个pac ...
随机推荐
- Centos6.5下编译安装mysql 5.6
一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm -e mysql //普通删除模式 rpm -e ...
- Dapper.Contrib:GetAsync<T> only supports an entity with a [Key] or an [ExplicitKey] property
异常处理:http://www.cnblogs.com/dunitian/p/4523006.html#dapper 原来Model是这样滴 修改后是这样滴 注意点:Model里面的Table和Key ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
- 模拟AngularJS之依赖注入
一.概述 AngularJS有一经典之处就是依赖注入,对于什么是依赖注入,熟悉spring的同学应该都非常了解了,但,对于前端而言,还是比较新颖的. 依赖注入,简而言之,就是解除硬编码,达到解偶的目的 ...
- WebApi基于Token和签名的验证
最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...
- 张高兴的 UWP 开发笔记:汉堡菜单进阶
不同于Windows 8应用,Windows 10引入了"汉堡菜单"这一导航模式.说具体点,就拿官方的天气应用来说,左上角三条横杠的图标外加一个SplitView控件组成的这一导航 ...
- Xamarin Android 应用程序内图标上数字提示
最近在用 Xamarin 做一个 Android 应用,打开应用时,如果有新消息,需要在应用内的 Toolbar 或者首页的图标上显示数字提示.在这里和大家分享一下实现方法,如果你有更新好的实现方法, ...
- 【代码笔记】iOS-获得当前的月的天数
一,代码. #import "ViewController.h" @interface ViewController () @end @implementation ViewCon ...
- Atitit 软件工程概览attilax总结
Atitit 软件工程概览attilax总结 1.1. .2 软件工程的发展 进一步地,结合人类发展史和计算机世界演化史来考察软件工程的发展史. 表2 软件工程过程模型 表2将软件工程的主要过程模型做 ...
- 自定义可视化调试工具(Microsoft.VisualStudio.DebuggerVisualizers)
前言: 最近飞机失联的太多,明天要飞北京处理服务器双机热备的问题,航空保险已买,单号是:TF10122913. 至于我的银行卡密码,在我枕头下面的字条里,要是我之后没再更新文章,请通知我家人,哈哈哈哈 ...